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

Zeka

Well-known member
01.09.2009
219
0
#1
Есть xp:repeat который отображает несколько строк с документами. Каждая строка содержит некий компонент (например xe:dialog).
Вопрос - как в SSJS развернуть диалог находящемуся на N-ой строчке репита?

Как вообще можно получить доступ к компоненту на определённой строке?
 

hosm

* so what *
18.05.2009
2 442
6
#2
Соррь, я не в теме по вопросу, но форум xpages не для этого???

Добавлено: в общем, я перенесу с оставленной ссылкой тут. Если что, вернут)
 

Zeka

Well-known member
01.09.2009
219
0
#3
Соррь, я не в теме по вопросу, но форум xpages не для этого???

Добавлено: в общем, я перенесу с оставленной ссылкой тут. Если что, вернут)
Упс... Я и не знал, что по xPages есть отдельная ветка....
Да, это вопрос чисто по xPages...
 

Dragon108

Well-known member
19.01.2010
265
0
#4
Есть примерно такой же вопрос:

Есть рипит контрол - отображает данные из представления. В каждой строчке рипита так же есть: поле (Input Box) и Кнопка. По клику на Кнопку надо брать данные из инпут бокса (соответствующего данной строчке рипита) - туда данные вводят вручную, и обрабатывать их на сервере. Так вот как это можно сделать?

Пробовал по такому сценарию: http://stackoverflow.com/questions/1001756...-repeat-control . Не подходит - инпут поля в рипите множатся, но алиас у них один :( Введенные данные на сервере берутся некорректно.

Пробовал так же в Data Source Инпут поля прописывать ['Alias' + rowIndex] через Scope переменную, где rowIndex - Index name в Рипит контроле. Выдается ошибка
com.sun.faces.el.impl.ElException: An exception occured trying to convert String "Alias" to type "java.lang.Long"
An exception occured trying to convert String "Alias" to type "java.lang.Long"


P.S. Есть ли вообще такая техническая возможность при помощи обычного рипит контрола? Или стоит копать в пользу готовых контролов - например Dojo Data Grid?
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#5
можно сделать немного по другому.
Можно использовать один диалог для всех документов. Причем диалог грузить динамически и передавать в него документ.
Вызывать диалог, например, по клику на строку документа или по кнопке в репитконтроле
 

Dragon108

Well-known member
19.01.2010
265
0
#6
можно сделать немного по другому.
Можно использовать один диалог для всех документов. Причем диалог грузить динамически и передавать в него документ.
Вызывать диалог, например, по клику на строку документа или по кнопке в репитконтроле
А можно чуть поподробнее?
Т.е. при клике на док в рипит контроле открывается всплывающее окно (диалог бокс) с Интпут боксом куда вводятся необходимые данные? и дальше, после закрытия всплывающего окна, данные обрабатываются на сервере?
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#7
А можно чуть поподробнее?
Т.е. при клике на док в рипит контроле открывается всплывающее окно (диалог бокс) с Интпут боксом куда вводятся необходимые данные? и дальше, после закрытия всплывающего окна, данные обрабатываются на сервере?
Именно.

документ из репитера
JavaScript:
<Collection name>.getDocument()
Идентификатор из репитера
JavaScript:
<Collection name>.getNoteID()
<Collection name>.getUniversalID()
Есть функция динамической загрузки кастом-контролов
JavaScript:
function loadCC( Name: String, parent: String, index, delChildren: boolean ){

//get panel control as parent of the custom control to include
//var objParent = getComponent( "panel_0" );

var objParent = getComponent( parent );

if( delChildren == true ){

if (objParent.getChildren().size() > 0) {
objParent.getChildren().clear();
}
}

//page name of the custom control to include
var strPageName = "/" + Name;

//create new UIIncludeComposite
var objControl = new com.ibm.xsp.component.UIIncludeComposite();

//set the page name to the UIIncludeComposite object
objControl.setPageName(strPageName);

//Ensure a unique id for this control
objControl.setId( "i_"+ index );       

//objControl.setId( index );

//Create a builder object from XPages Extension Library
var objBuilder = new com.ibm.xsp.extlib.builder.ControlBuilder();

//to use the builder you need ControlImpl objects.
//Because this builder only can work with those objects
//get the class of ControlImpl
var classControlImpl = objBuilder.getClass().getDeclaredClasses()[1];

//create an ControlImpl object of the parent panel
var objImplParent = new classControlImpl(objParent);

//create an ControlImpl object of the custom control
var objImplControl = new classControlImpl(objControl);

//add the new custom control to the parent
objImplParent.addChild(objImplControl);

//build the updated parent control
objBuilder.buildControl(facesContext,objImplParent,false);   

}
На входе имя кастом-котрола. Например Name = "cc_test.xsp". Расширение в коде обязательно! Хотя в списке дизайнера указывается только имя!
index - имя, которое присвоится кастом-контролу . После загрузки к этому имени допишется префикс "i_"
parent - имя контрола, в который будем добавлять свой кастом-контрол.
Я для этого добавляю в конец страницы пустую панель. В ней не жалко удалять не нужные объекты по delChildren.

Если у кастом-контрола есть Property Definition - берем свойства и присваиваем то что надо. Типы данных обязательно соблюдаем.
Передать можно строки, числа, объекты. Подробнее
Для просмотра контента необходимо: Войти или зарегистрироваться
или читаем
Вот пример как передать юнид документа в кастом-контрол. При условии что в кастом-контроле есть уже объект документа. В самом же кастом-контроле параметр берется через compositeData
JavaScript:
var cmp:com.ibm.xsp.component.UIIncludeComposite = getComponent( "i_" + ndex );
cmp.getPropertyMap().setString("docUnid", document1.getUniversalID() );
Если надо передать именно объект документа в кастом-контрол:
JavaScript:
var cmp:com.ibm.xsp.component.UIIncludeComposite = getComponent( "i_" + ndex );
cmp.getPropertyMap().setProperty("document", document1);
Соответственно все работы в кастом-контроле ведутся через compositeData.
Если же кастом-контрол является частью одного документа - в кастом-контроле не нужны никакие объекты документа.
В свойствах Data Binding контрола в кастом-контроле можно просто написать Data source и Bind to объект основной страницы

Чтоб открыть диалог - все как всегда при помощи SSJS или CSJS
JavaScript:
var d = getComponent( "dialog1" );
d.show()
Для пущего феншуя в кастом-контрол с диалогом добавляю параметры для рефреша компонентов после закрытия диалога и так же передаю код, который может выполняться по кнопке Ok в диалоге

Таким методом можно создавать динамические страницы. Определять кастом-контролы до загрузки страницы.
Этим методом разношу логику. В дизайнере работать удобно. Страницы получаются практически пустые.
 
Последнее редактирование модератором:
A

alexas

#8
Поддерживаю технологию, которую описал NickProstoNick. Сам дизайню так-же.
Работать очень удобно и вся логика абсолютно прозрачна. Особенно для тех, кто только пришёл в xpages из классического клиента.
У новичков всегда возникает вопрос: как в хепагах дизайнить фреймы?
Вот так - с помощью loadCC (у меня ещё replaceCC) грузить кастом-контролы или задизайненные страницы(!) (тут надо быть внимательным - не каждая хепага загрузится без ошибок!) в нужные места предварительно размеченной главной страницы (дивами, панелями, таблицей... кому что нравится).
Т.е. это эквивалент связки SetTargetFrame & OpenPage(Form...) в классике.
Результат - полностью динамичная страница.
Часто всё WEB приложение обходится ей одной (если не нужен функционал с параллельной логикой в двух и более вкладках браузера).
Как вообще можно получить доступ к компоненту на определённой строке?
Делаете имя Вашего контрола, который размножаете в репитере, вычисляемым - например Name: MyControl_${rptIndex}, где rptIndex - это Index Name репитера (Options).
Name (id) контрола в Properties дизайнер поправить не даст - надо править в коде (Sourse).
Далее, как обычно, получаете компонент по id: getComponent('MyControl_' + i), где i - индекс компонента в строке (или колонке) репитера.
 

Dragon108

Well-known member
19.01.2010
265
0
#9
Делаете имя Вашего контрола, который размножаете в репитере, вычисляемым - например Name: MyControl_${rptIndex}, где rptIndex - это Index Name репитера (Options).
Name (id) контрола в Properties дизайнер поправить не даст - надо править в коде (Sourse).
Далее, как обычно, получаете компонент по id: getComponent('MyControl_' + i), где i - индекс компонента в строке (или колонке) репитера.
Можно, если не сложно, пример.
При прописывании в атрибуте id - MyControl_${rptIndex} в теге xp:inputText - в итоговой html странице элементы inputText имеют id-шники MyControl_. :(


P.S. Да и вообще нашел вот такую вещь - http://publib.boulder.ibm.com/infocenter/d..._inputText.html

The identifier must be a static value.
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#10
rptIndex - это значение свойства Index control репитера
И что должны были вынести из твоей ссылки?

Вообще - надо понимать что вообще надо делать!
А то каким местом связаны диалоговые окна с доступом к какому-то определенному контролу в репитере?

Как будет определяться в какой строке репитера надо обратиться?
 

Dragon108

Well-known member
19.01.2010
265
0
#11
rptIndex - это значение свойства Index control репитера
И что должны были вынести из твоей ссылки?
То, что значение id у элемента (в данном случае это InputBox) - всегда статично, т.е. насколько я понял (ссудя из ссылки хелпа выше) вычислять его нельзя - можно только "намертво вбить". Или я чего то не понял/не знаю и прошу рассказать как можно это id - вычислять.
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#12
блин.. руками вбить!
Тебе же написали
Делаете имя Вашего контрола, который размножаете в репитере, вычисляемым - например Name: MyControl_${rptIndex}, где rptIndex - это Index Name репитера (Options).
Name (id) контрола в Properties дизайнер поправить не даст - надо править в коде (Sourse).
Далее, как обычно, получаете компонент по id: getComponent('MyControl_' + i), где i - индекс компонента в строке (или колонке) репитера.
У репитера надо указать 3 свойства:
  1. Data Source
  2. var (оно же Collection name)
  3. indexVar (оно же Index name) надо в нем написать rptIndex

В свойстве Name поля написать код
Код:
"MyControl_" + rptIndex
 

Dragon108

Well-known member
19.01.2010
265
0
#13
Видимо вы меня неправильно поняли ... бывает :(

Был бы рад простому примеру как у вас получилось вот это:

В свойстве Name поля написать код
Код:
"MyControl_" + rptIndex

P.S. Если в поле прописать id="MyControl_${rptIndex}", где rptIndex - indexVar (оно же Index name). то в итоговой html-странице все поля в репит контроле получаются с id: MyControl_.
Все остальное (из вашей инструкции - уже сделано)
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 809
21
#14
Код:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">

<xp:repeat id="repeat1" rows="30" var="colName" indexVar="rptIndex"
repeatControls="true">
<xp:this.value><![CDATA[#{java script:var tmp = []
tmp.push("1111111111") 
tmp.push("2222222222")
tmp.push("3333333333")
tmp.push("4444444444")
tmp.push("5555555555")
return tmp}]]></xp:this.value>
<xp:inputText value="#{java script:colName}">

<xp:this.id><![CDATA[${java script:"MyControl_" + rptIndex}]]></xp:this.id>
</xp:inputText>

<xp:br></xp:br>
</xp:repeat>
</xp:view>
 
A

alexas

#15
Dragon108
Может так будет понятней
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

<xp:text escape="true" id="sourceRepeat"><xp:this.value><![CDATA[#{java script:['111','222','333','444','555']}]]></xp:this.value></xp:text>
<xp:br></xp:br>
<xp:repeat id="repeat2" rows="30" indexVar="rptIndex"
repeatControls="true">
<xp:this.value>
<![CDATA[#{java script:getComponent("sourceRepeat").getValue()}]]>
</xp:this.value>


<xp:inputText id="inText_${rptIndex}">
<xp:this.defaultValue><![CDATA[#{java script:var a = getComponent("sourceRepeat").getValue();
return a[rptIndex]
}]]></xp:this.defaultValue>
</xp:inputText>

</xp:repeat>
<xp:button value="value 0" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="valueRepeat">
<xp:this.action><![CDATA[#{java script:var a = getComponent('inText_0').getValue();

getComponent('valueRepeat').setValue(a)}]]></xp:this.action>
</xp:eventHandler></xp:button><xp:button value="value 1" id="button6">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="valueRepeat">
<xp:this.action><![CDATA[#{java script:var a = getComponent('inText_1').getValue();

getComponent('valueRepeat').setValue(a)}]]></xp:this.action>
</xp:eventHandler></xp:button><xp:button value="value 2" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="valueRepeat">
<xp:this.action><![CDATA[#{java script:var a = getComponent('inText_2').getValue();

getComponent('valueRepeat').setValue(a)}]]></xp:this.action>
</xp:eventHandler></xp:button><xp:button value="value 3" id="button3">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="valueRepeat">
<xp:this.action><![CDATA[#{java script:var a = getComponent('inText_3').getValue();

getComponent('valueRepeat').setValue(a)}]]></xp:this.action>
</xp:eventHandler></xp:button><xp:button value="value 4" id="button4">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="valueRepeat">
<xp:this.action><![CDATA[#{java script:var a = getComponent('inText_4').getValue();

getComponent('valueRepeat').setValue(a)}]]></xp:this.action>
</xp:eventHandler></xp:button>



    <xp:text escape="true" id="valueRepeat" style="color:rgb(0,128,255);font-weight:bold"></xp:text>
</xp:view>


Вообще-то в хэпагах вычисляется всё
 

KingGLEB

Active member
08.05.2008
30
0
#16
Тоже наступил на грабли. :rolleyes:
Не создается нормальный id в repeat, если у repeat не указан repeatControls="true".
Может кому полезно будет.