Добавление пользовательских элементов управления через SSJS (или динамически любым другим способом)

Я хотел бы добавить настраиваемый элемент управления через SSJS, точно так же, как я могу добавить компонент ("Component Tree Injection" http://openntf.org/XSnippets.nsf/snippet.xsp?id=component-tree-jection), но я не могу заставить его работать.

Я хочу создать кнопку «New Person» на странице, которая будет добавлять Custom-Control каждый раз, когда пользователь нажимает на нее.

Сначала я попытался выполнить это с помощью RepeatControl, используя repeatControl = "true", но это было невозможно, потому что я не могу позволить себе перезагрузить всю Xpage, чтобы создать новые CC и потерять все остальные данные в этом процессе. (См. Блок кода)

Если вы знаете о какой-либо другой возможности динамического добавления настраиваемого элемента управления без перезагрузки страницы, не стесняйтесь объяснять. ;-)

Большое спасибо!

<xp:button value="New Person" id="newPersonButton">
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
        <xp:this.action>
            <![CDATA[#{javascript://
                viewScope.counter = viewScope.counter + 1;
            }]]>
        </xp:this.action>
    </xp:eventHandler>
</xp:button>
<xp:repeat id="repeat1" rows="30" repeatControls="true" var="rowData" indexVar="rowIndex">
    <xp:this.value><![CDATA[#{javascript:return new Array(Number(viewScope.counter))}]]></xp:this.value>
    <xc:ccPersondata id="persondata_${rowIndex}"></xc:ccPersondata>
</xp:repeat>

Решение. Для окончательного решения я объединил ответ Михала Саиза (вы только что сделали мой день! :)) с Динамически привязать поле редактирования в настраиваемом элементе управления к управляемому bean-компоненту и придумал следующий код:

XPage

<xp:repeat id="repeat1" rows="30" var="rowData" indexVar="rowIndex">
    <xp:this.value><![CDATA[#{javascript://
    var person = function(name,age){
        this.name = name;
        this.age = age;
    }
    if(!viewScope.containsKey('list')){
        viewScope.list = [];
        list.push(new person("victor","24"));
        list.push(new person("Igor","24"));
    }
    return viewScope.list;}]]></xp:this.value>
    <xp:panel>
        <xc:ccPersondata id="ccPersondata" BindTo="rowData" />          
    </xp:panel>
</xp:repeat>
<xp:button value="addPerson" id="button1">
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
        <xp:this.action><![CDATA[#{javascript:
    var person = function(name,age){
        this.name = name;
        this.age = age;
    }
    var emptyPerson = new person('none','0');
    viewScope.list.push(emptyPerson);}]]></xp:this.action>
    </xp:eventHandler>
</xp:button>

Пользовательский элемент управления: ccPersondata

<xp:label value="Name:" id="label1">
    <xp:inputText id="name">
        <xp:this.value><![CDATA[${javascript:"#{"+compositeData.BindTo+".name}"}]]></xp:this.value>
    </xp:inputText>
</xp:label>
<xp:label value="Age:" id="label2">
    <xp:inputText id="age">
        <xp:this.value><![CDATA[${javascript:"#{"+compositeData.BindTo+".age}"}]]></xp:this.value>
    </xp:inputText>
</xp:label>

person Dennis Kronbügel    schedule 12.03.2014    source источник


Ответы (1)


Зачем добавлять пользовательское руководство по управлению, если у вас уже есть повторяющийся элемент управления, который может создавать любое количество ccPersondata. Вместо добавления руководства по управлению с помощью внедрения компонента я бы просто добавил еще одно пустое значение в ваш повторяющийся массив (например, пустой объект / массив Person, что бы вы ни использовали для хранения данных человека) и обновил бы элемент управления повтором.

Вот небольшой пример того, что я имею в виду:

<xp:repeat id="repeat1" rows="30" var="rowData" indexVar="rowIndex">
    <xp:this.value><![CDATA[#{javascript://
        var person = function(name,age){
            this.name = name;
            this.age = age;
        }
        if(!viewScope.containsKey('list')){
            viewScope.list = [];
            list.push(new person("victor","24"));
            list.push(new person("Igor","24"));
        }
        return viewScope.list;}]]></xp:this.value>
        <xp:panel>
            <xp:text
                escape="true"
                id="computedField1"
                value="#{rowData.name}">
            </xp:text>
            <br></br>
                                <!-- here is your ccPersonData -->
    </xp:panel>
</xp:repeat>
<xp:button value="addPerson" id="button1">
<xp:eventHandler
    event="onclick" submit="true" refreshMode="partial" refreshId="repeat1">
    <xp:this.action><![CDATA[#{javascript:
        var person = function(name,age){
            this.name = name;
            this.age = age;
        }
        var emptyPerson = new person('none','0');
        viewScope.list.push(emptyPerson);}]]></xp:this.action>
</xp:eventHandler>
</xp:button>

В вашем случае вместо объектов SSJS я бы использовал класс или документы java в зависимости от ваших потребностей. Также я бы использовал класс java, который обрабатывает данные для повтора, чтобы вы могли обрабатывать функции (новые лица или сохранить человека) с этим классом .. maby, включая метод addPersonOnPsoition () ....

person Michael Saiz    schedule 12.03.2014