XForms repeat - спросить пользователя о количестве строк
Я хотел бы спросить пользователя через xf:input, "сколько элементов" вы хотите за определенный повтор, а затем, основываясь на ответе пользователя, представить повтор с таким количеством строк (что, я думаю, также генерироваться в xf:instance).
Я знаком с использованием триггеров для вставки и удаления строк.
Здесь я спрашиваю, как запросить у пользователя начальное количество строк, которые будут созданы и представлены.
Например, предположим, что пользователь хотел 10 строк. Я предполагаю, что повторяющиеся данные могут быть неактуальными, пока они не ответят на этот вопрос, и когда они ответят на него, какое-то действие может динамически создать строки, а затем сделать повторные данные релевантными.
Но как это сделать?
Обновление 20 декабря
Разметка ниже представляет поле ввода и в более удобной форме добавляет строки к экземпляру при нажатии кнопки. Тем не менее, betterForm не отображает данные в пользовательском интерфейсе (хотя, я думаю, это сугубо отдельный вопрос). Я не пробовал другие реализации.
<xhtml:head>
<xf:model id="m">
<xf:instance id="main-instance">
<data>
<items>
<item1>item 11</item1>
<item2>item 12</item2>
<item3>item 13</item3>
</items>
</data>
</xf:instance>
<xf:instance id="variable">
<variable xmlns="">
<iteration-count/>
</variable>
</xf:instance>
</xf:model>
</xhtml:head>
<xhtml:body>
<!-- Simple field to enter the number of iterations -->
<xf:input ref="instance('variable')/iteration-count">
<xf:label>How many iterations?</xf:label>
</xf:input>
<xf:trigger>
<xf:label>Insert with while</xf:label>
<xf:action ev:event="DOMActivate">
<xf:action while="instance('variable')/iteration-count != 0">
<xf:insert ev:event="DOMActivate" nodeset="items"/>
<xf:setvalue ref="instance('variable')/iteration-count" value=". - 1"/>
</xf:action>
<!--<xf:refresh model="m"/>-->
</xf:action>
</xf:trigger>
<table>
<tbody id="r-attrs" xf:repeat-nodeset="items">
<tr>
<td>
<xf:output ref="item1"></xf:output>
</td>
<td>
<xf:output ref="item2"></xf:output>
</td>
<td>
<xf:output ref="item3"></xf:output>
</td>
</tr>
</tbody>
</table>
</xhtml:body>
3 ответа
Атрибуты while и iterate в действии будут повторять это действие.
Одним из способов получения информации от пользователя является привязка входного виджета к элементу во вспомогательном документе (я часто называю этот документ ui
поскольку он содержит информацию о состоянии пользовательского интерфейса) и контролирует вставку и отображение из этого. Если вы хотите заставить пользователя предоставить значение, вы можете сделать его по умолчанию 0; если вы этого не сделаете, вы можете предоставить какой-то вероятный номер по умолчанию, который пользователь может переопределить, если пожелает.
Вы задаете два отдельных вопроса, если я хорошо понимаю:
- как подсказать пользователю
- как вставить заданное количество итераций
Вот
Чтобы подсказать пользователю, вы можете использовать диалог (
xforms:dialog
стандартизирован XForms 2.0, а Orbeon Forms поддерживаетxxforms:dialog
расширение). Вы также можете использоватьxforms:switch
показать / скрыть поле против повторения.Как только значение получено, вы можете, как говорит Ален, использовать
while
илиiterate
атрибут для выполнения действия вставки несколько раз. Или, если у вас XPath 2.0, вы можете использоватьfor
вorigin
выражение.
Вот полный пример, который показывает два способа вставки:
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events">
<xh:head>
<xf:model>
<xf:instance id="repeats">
<repeats/>
</xf:instance>
<xf:instance id="count">
<count/>
</xf:instance>
</xf:model>
</xh:head>
<xh:body>
<!-- Simple field to enter the number of iterations -->
<xf:input ref="instance('count')">
<xf:label>How many iterations?</xf:label>
</xf:input>
<!-- Variant 1 -->
<xf:trigger>
<xf:label>Insert with for</xf:label>
<xf:insert
ev:event="DOMActivate"
if="instance('count') castable as xs:integer"
context="instance('repeats')"
ref="repeat"
origin="for $i in 1 to instance('count')
return xf:element('repeat')"/>
</xf:trigger>
<!-- Variant 2 -->
<xf:trigger>
<xf:label>Insert with while</xf:label>
<xf:insert
ev:event="DOMActivate"
if="instance('count') castable as xs:integer"
context="instance('repeats')"
while="count(repeat) lt xs:integer(instance('count'))"
ref="repeat"
origin="xf:element('repeat')"/>
</xf:trigger>
<xf:trigger>
<xf:label>Clear</xf:label>
<xf:delete ev:event="DOMActivate" ref="instance('repeats')/*"/>
</xf:trigger>
<!-- Your repeat -->
<xf:repeat ref="repeat">
<xf:output value="position()"/>
</xf:repeat>
</xh:body>
</xh:html>