Получить компонент в N-ой строке Xp:repeat'а (xpages)

  • Автор темы Zeka
  • Дата начала

Eugen

Green Team
22.03.2012
210
1
BIT
1
Попробовал пример накидать
XML:
<xp:panel id="panelTasks">
        <xp:this.data>
            <xp:dominoView var="ProtocolTasksView"
                viewName="TasksAllByParentUNID">
                <xp:this.databaseName><![CDATA[#{javascript:return 'someSrv!!someDb.nsf';}]]></xp:this.databaseName>
                <xp:this.categoryFilter><![CDATA[#{javascript:return document.getDocument().getUniversalID();}]]></xp:this.categoryFilter>
            </xp:dominoView>
        </xp:this.data>
        <xp:repeat id="repeat1" rows="100" var="rowTask"
            repeatControls="false" indexVar="rowTaskIndex" first="1"
            value = "#{ProtocolTasksView}">
            <xp:div styleClass="list-group">
                <xp:inputText id="contents">
                    <xp:this.readonly><![CDATA[#{javascript:if(viewScope.editTasks != null && viewScope.editTasks == '1'){
                        return false;
                    }else{
                        return true;
                    }}]]></xp:this.readonly>
                    <xp:this.value><![CDATA[#{javascript:if(rowTask.isDocument()){
                        return rowTask.getDocument().getItemValueString('TaskContents');
                    }}]]></xp:this.value>
                </xp:inputText>
            </xp:div>
        </xp:repeat>
        <xp:div styleClass="panel-heading clearfix" id="buttonsAddEdit"
            rendered="#{javascript:compositeData.dataSource.isEditable();}">
            <div class="btn-group">
                <xp:button styleClass="btn btn-primary" value=""
                    id="btnEditTasks">
                    <xp:span>
                        <xp:this.styleClass><![CDATA[#{javascript:if(viewScope.editTasks != null && viewScope.editTasks == '1'){
    return 'fa fa-save';
}else{
    return 'fa fa-edit';
}}]]></xp:this.styleClass>
                    </xp:span>
                    <xp:eventHandler event="onclick" submit="true"
                        refreshMode="partial" refreshId="panelTasks">
                        <xp:this.action><![CDATA[#{javascript:try{
    print('try to edit task');
    if(viewScope.editTasks == null || viewScope.editTasks == ''){
        //редактирование
        viewScope.editTasks = '1';
    }else{
        //окончание редактирования
        var coll:NotesDocumentCollection = ProtocolTasksView.getAllDocumentsByKey(document.getDocument().getUniversalID());
        var count = 0;
        if(coll != null)count = coll.getCount();
        var doc:NotesDocument = coll.getFirstDocument();
        var xspDoc:NotesXspDocument;
       
        while(doc != null){
            xspDoc = XSPUtils_wrapDocument(doc);
            if(xspDoc != null) xspDoc.save();;
           
            var tmp = coll.getNextDocument(doc);
            doc.recycle();
            doc = tmp;
        }
       
        viewScope.editTasks = null;
    }
}catch(err){
    print("Произошла ошибка: " + err);
}}]]></xp:this.action>

                    </xp:eventHandler>
                </xp:button>
            </div>
        </xp:div>
    </xp:panel>
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Но вообще описание сумбурное. Нарисуй картинку что ли
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
Но вообще описание сумбурное. Нарисуй картинку что ли
Clip2net_190725185443.png

Нижняя кнопка за пределами репитера. По объекту "ProtocolTasksView" собирает коллекцию и сейвит. За пределами panel "panelTasks" объект "ProtocolTasksView" почему-то не виден и приходится извращаться.
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
За пределами панели ты теряешь контекст объектов. Из вложенных объектов родители видны, из родителей вложенные - нет.
Самый простой вариант - сделый эмуляцию нажатия кнопки.
На обычном JS вызови событие нажатия на рабочую кнопку.
Так же можн получить URL на функцию из рабочей кнопки и прописать ее в нужную, но такой вариант не лучшее решение
 
Последнее редактирование:

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
так же можно попробовать через RPC.
Кстати, а просто сделать Submit не помогает?
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
Самый простой вариант - сделый эмуляцию нажатия кнопки.
Пробовал через view.postScript делать клик кнопки - не срабатывает почемму-то... Обращаюсь по clientID естессно...
так же можно попробовать через RPC.
Это как?

где-то тут на форуме натыкался на упоминане, что датасорс репитера можно в каком-то java объекте хранить, и типа он виден ото всюду. Что-нибудь знаешь про такое?
Я пробовал просто на самом кастом контроле добавить датасорс с нужной коллекцией, но репитер не видит ее(
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Есть компонент такой RPC. Как придумать сохранение - не знаю. Надо мозговать.
Пример использования RPC

Касательно датасорса.
Вид можно определить на самом пейдже, а использовать в репитере. Никаких хитрых объектов не надо. Но конечно все зависит от структуры приложения
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
Вид можно определить на самом пейдже, а использовать в репитере. Никаких хитрых объектов не надо. Но конечно все зависит от структуры приложения
сделал - объект виден из кнопки, но изменения внесенные в UI в нем отсутствуют. Т.е. страница отрисовалась, редактирую поле, затем из кнопки на основной пейджине беру значение из этого датасорса и оно старое.

Как можно сымитировать клиентское нажатие кнопки? Через viewScope выполняю код - id корректный, но не срабатывает нажатие. На клиенте тоже пробовал - id формируется корректный, а нажатие не фунциклирен(

JavaScript:
    var id = getClientId('btnEditTasks');
    var script = "try{document.getElementById('" + id + ").click()}catch(err){alert(err)}";
   
    view.postScript(script);

JavaScript:
    document.getElementById("#{id:btnEditTasks}").click();


Или может все-таки как-то можно обратиться к содержимому репитера и собрать введенные данные?
 
Последнее редактирование:

alexas1

Green Team
10.04.2014
1 202
225
BIT
45
.....затем из кнопки на основной пейджине беру значение из этого датасорса и оно старое.
"из этого датасорса" - т.е. с сервера(!!), а ты ТАМ значения не апдейтил, поэтому и старое
а чтобы отрефрешить на сервере, надо выполнить XSP.partialRefreshPost, к примеру (это НЕ сохранит док, конечно же)
document.getElementById("#{id:btnEditTasks}").click(); - нормально "кликнет", где бы кнопа не находилась если!!! попутно НЕТ ошибок в скрипте, такшта ищи
ващще, погугли что то вроде "xpages inline edit table" - подходов множество разных...
напр
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
есть такой метод на SSJS
save();
Он постит все документы, которые открыты на странице
я сначала видимо про другой сейв подумал... нашел флаг save у eventHandler'а кнопки, но для меня не подходит - основной документ сейвить нельзя
"из этого датасорса" - т.е. с сервера(!!), а ты ТАМ значения не апдейтил, поэтому и старое
а чтобы отрефрешить на сервере, надо выполнить XSP.partialRefreshPost, к примеру (это НЕ сохранит док, конечно же)
document.getElementById("#{id:btnEditTasks}").click(); - нормально "кликнет", где бы кнопа не находилась если!!! попутно НЕТ ошибок в скрипте, такшта ищи
ващще, погугли что то вроде "xpages inline edit table" - подходов множество разных...
напр
Немного переделал структуру(писал по памяти):
XML:
<xp:panel id="panelTasks">
        <xp:this.data>
            <xp:dominoView var="ProtocolTasksView"
                viewName="TasksAllByParentUNID">
                <xp:this.databaseName><![CDATA[#{javascript:return 'someSrv!!someDb.nsf';}]]></xp:this.databaseName>
                <xp:this.categoryFilter><![CDATA[#{javascript:return document.getDocument().getUniversalID();}]]></xp:this.categoryFilter>
            </xp:dominoView>
        </xp:this.data>
        <xp:repeat id="repeat1" rows="100" var="rowTask"
            repeatControls="false" indexVar="rowTaskIndex" first="1"
            value = "#{ProtocolTasksView}">
                <xp:panel id="panelRepeaterRow">
                    <xp:this.data>
                        <xp:dominoDocument var="targetDoc"
                            action="editDocument">
                            <xp:this.databaseName><![CDATA[#{javascript:try{
    return compositeData.targetDbNameNPath;
}catch(err){print(err)}}]]></xp:this.databaseName>
                            <xp:this.documentId><![CDATA[#{javascript:try{if(row.isDocument())row.getDocument().getUniversalID();}catch(err){print(err);}}]]></xp:this.documentId>
                        </xp:dominoDocument>
                    </xp:this.data>
                    <xp:div styleClass="list-group">
                        <xp:inputText id="contents">
                            <xp:this.readonly><![CDATA[#{javascript:if(viewScope.editTasks != null && viewScope.editTasks == '1'){
                                return false;
                            }else{
                                return true;
                            }}]]></xp:this.readonly>
                            <xp:this.value><![CDATA[#{javascript:targetDoc.getItemValueString('TaskContents');}]]></xp:this.value>
                        </xp:inputText>
                    </xp:div>
                </xp:panel>
        </xp:repeat>
        <xp:div styleClass="panel-heading clearfix" id="buttonsAddEdit"
            rendered="#{javascript:compositeData.dataSource.isEditable();}">
            <div class="btn-group">
                <xp:button styleClass="btn btn-primary" value=""
                    id="btnEditTasks">
                    <xp:span>
                        <xp:this.styleClass><![CDATA[#{javascript:if(viewScope.editTasks != null && viewScope.editTasks == '1'){
    return 'fa fa-save';
}else{
    return 'fa fa-edit';
}}]]></xp:this.styleClass>
                    </xp:span>
                    <xp:eventHandler event="onclick" submit="true"
                        refreshMode="partial" refreshId="repeat1" save = "true">
                        <xp:this.action><![CDATA[#{javascript:try{
    print('try to edit task');
    if(viewScope.editTasks == null || viewScope.editTasks == ''){
        //редактирование
        viewScope.editTasks = '1';
    }else{
        //окончание редактирования
        viewScope.editTasks = null;
    }
}catch(err){
    print("Произошла ошибка: " + err);
}}]]></xp:this.action>

                    </xp:eventHandler>
                </xp:button>
            </div>
        </xp:div>
    </xp:panel>
Суть в том, что внутрь репитера добавлена панель, датасорс которой используется в полях. Флаг save сохраняет изменения, но как я написал выше, он сейвит и основной документ, чего делать нельзя. А еще после его срабатывания что-то происходит с кнопкой и на ней перестает работать серверный скрипт, при этом ошибок явных нет, ни на клиенте, ни в серверной консоли....
Из ссылки выше вынес для себя только про датасорс через panel внутри репитера(panelRepeaterRow в моем примере).

В общем, вернулся практически к тому, с чего начал - надо как-то доковыряться до доков внутри репитера и сохранить их.
Пробовал еще вот так, но изменения не сохраняются:
XML:
<xp:eventHandler event="onclick" submit="true"
                        refreshMode="partial" refreshId="repeat1" save = "true"
                        onComplete="XSP.partialRefreshPost('#{id:panelRepeaterRow}')">
                        <xp:this.action><![CDATA[#{javascript:try{
    print('try to edit task');
    if(viewScope.editTasks == null || viewScope.editTasks == ''){
        //редактирование
        viewScope.editTasks = '1';
    }else{
        //окончание редактирования
        viewScope.editTasks = null;
    }
}catch(err){
    print("Произошла ошибка: " + err);
}}]]></xp:this.action>

                    </xp:eventHandler>
 
Последнее редактирование:

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
Суть в том, что внутрь репитера добавлена панель, датасорс которой используется в полях
какой смысл её совать в репитер?
и второй момент -так принципиально использовать методы хэпагесов? Можно получить клиентские данные (CSJS) и сделать xhr запрос с PATCH нужных полей по юниду, для этого надо активировать DAS
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
Можно получить клиентские данные (CSJS)
Если правильно понимаю, для это у репитера должен быть repeatControls="true", чтобы переменная индекса была доступна, чтобы потом в свою очередь обращаться к полям по вычисленным клиентским id, а у меня при включенном этом флаге репитер ни фига не отображает почему-то...
какой смысл её совать в репитер?
Опять таки, если правильно понимаю вот этот пример, чтобы по ее id рефрешить данные в памяти
 

alexas1

Green Team
10.04.2014
1 202
225
BIT
45
какой смысл её совать в репитер?
в данном случае, чтобы датасорс был документ, что бы можно было редактировать поле
Хотя, выводить на редактирование кучу UI documents очень плохо
И сохранять эту кучу в UI тоже очень плохо
Опять таки, если правильно понимаю вот этот пример, чтобы по ее id рефрешить данные в памяти
пример помещён, скорее, из академический соображений - как на ssjs получить строку репитера, не надо ТАК редактировать доки в репитере (потому, что они будут все в UI) - вносить изменения в существующий док надо в бэке и сохранять, естественно в бэке, метод save(), который упомянул ПростоНик, уишный
 

Eugen

Green Team
22.03.2012
210
1
BIT
1
как на ssjs получить строку репитера
вот именно это я и не понял. Я бы рад собрать введенные данные в UI, а потом в бэке зафигачить их в доки, но!
Если repeatControls="true", то содержимое репитера у меня не отображается, а если false, то недоступна переменная индекса
 

alexas1

Green Team
10.04.2014
1 202
225
BIT
45
собрать введенные данные в UI, а потом в бэке зафигачить их в доки
ну вот те не только в UI, без выведения доков в редактирование, но и в сугубо клиентском ванильном JS), без никаких рефрешей, тока сейвы в бэке (RPC), одномоментно, по всем изменениям
это НЕ рецепт - это концепт))
в панели сам переделаешь, если понравится (мне в табличке было сподручнее)
 

Вложения

  • InlineViewEdit.zip
    50,6 КБ · Просмотры: 269
  • Нравится
Реакции: Eugen
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!