Учебное пособие (1075724), страница 45
Текст из файла (страница 45)
Атрибут constraint задаетдополнительные ограничения на значение данных. Функция normalize-space(.)удаляет все пробелы слева и справа в текущем элементе, функция string-lengthвозвращает длину строки. Длина строки должна быть больше нуля, это означает,что строка содержит не только пробелы.<!-- Тип процессора - обязательное поле --><xforms:bind nodeset="//processor_id" required="true()" /><!-- ОП - обязательное поле целого типа в диапазоне от 0 до 4096 -><xforms:bind nodeset="//op" type="xforms:int" required="true()"constraint="(.
>= 1) and (. <= 4096)" />Атрибут type="xforms:int" означает, что это элемент целочисленного типа. Ватрибуте constraint="(. >= 1) and (. <= 4096)" проверяется, что значениетекущего элемента (точка означает текущий элемент) должно лежать в диапазонеот 1 до 4096, «>=» – это больше или равно (>=),«<=» – это меньше или равно(<=).<!-- Объем жесткого диска - обязательное поле целого типа вдиапазоне от 0 до 1000 --><xforms:bind nodeset="//hdd" type="xforms:int" required="true()"constraint="(. >= 1) and (. <= 1000)" />426<!-- Признак сервера - логического типа --><xforms:bind nodeset="//server" type="xforms:boolean" /><!-- Дата модернизации - обязательное поле типа дата --><xforms:bind nodeset="//upgrade_date" type="xforms:date"required="true()" /><!-- Описание модернизации - обязательное поле и введенные данныене состоят только из пробелов --><xforms:bind nodeset="//upgrade_description" required="true()"constraint="string-length(normalize-space(.)) > 0" /><!-- Отправка формы --><xforms:submission id="submit_id" replace="none"action="{$DataPreSaveURI}" method="post"includenamespaceprefixes=""/>Элемент xforms:submission определяет параметры сохранения заполненныхданных формы.Атрибут «id="submit_id"» определяет id элемента для дальнейших ссылок вформе.Атрибут «replace="none"» определяет, что после сохранения данных формане должна изменяться.
В нашем случае более удобным было бы значение«replace="all"», при котором форма после сохранения заменяется результатомработы серверного сценария (там может быть сообщение об успешномсохранении формы и кнопки перехода к другим формам), но этот режим неподдерживается в текущей версии XSLTForms.Атрибут «action="{$DataPreSaveURI}"» задает URI серверного сценария,которому будут передаваться данные.Атрибут «method="post"» определяет, что данные будут передаваться спомощью метода POST протокола HTTP.427Атрибут «includenamespaceprefixes=""» определяет, что в передаваемыеданные не нужно включать никакие префиксы пространств имен (в нашемпримере XML-данные не используют пространства имен).</xforms:model>),((: Данные для выбора типов процессоров :)<xforms:model id="processor_model"><xforms:instance id="processor_instance" xmlns=""src="{$ProcessorReadURI}"/>Модель «processor_model» содержит инстанс «processor_instance», в которыйзагружается список типов процессоров.
Переменная $ProcessorReadURI содержитURI сценария, который возвращает список типов процессоров (в нашем случаеэто сценарий «data_computer_1.1.xql» с параметром «list=1»).</xforms:model>)};(: ++++++++++++++++++++++++++++++++++++++++++++++ :)(: Редактирование формы :)(: ++++++++++++++++++++++++++++++++++++++++++++++ :)declare function local:EditForm($ListURI as xs:string,$DataPreSaveURI as xs:string, $DataSaveURI as xs:string) as node(){<div><table border="1" align="center" >Элементы формы форматируются с помощью таблицы HTML.<tr><th colspan="2" align="right">Наименование компьютера:</th><td><xforms:input model="computer_model" ref="computer_name"><xforms:alert>Поле не может быть пустым</xforms:alert></xforms:input>428Наименование компьютера вводится с помощью элемента xforms:input.Атрибут model="computer_model" ссылается на модель данных, а атрибутref="computer_name" на XML-элемент в модели данных.Особенностью является то, что явной ссылки на инстанс здесь нет, хотямодель «computer_model» содержит два инстанса.
По умолчанию используетсяпервый инстанс, поэтому приведенный пример должен работать корректно. Ноесли в модели поменять порядок следования инстансов, то приведенный примерработать не будет. Для явной ссылки на инстанс можно использовать XPathфункцию «instance» (она применяется в XPath-выражении в атрибуте ref), тогдаатрибут ref="instance('computer_instance')//computer_name".
При использованиифункции «instance» можно вводить данные в любой инстанс модели.Элемент xforms:alert содержит сообщение об ошибке. Если данные вводятсянеправильно (то есть нарушется какое-либо из условий, указанных в xforms:bindдля данного элемента), то справа от поля ввода появляется пиктограмма ошибки исообщение из xforms:alert. Поскольку в случае всех ошибок выдается одно и то жесообщение, то в элементе xforms:alert, вероятно, лучше не перечислять всевозможные ошибки, а задавать подсказку для правильного ввода данных.</td></tr><tr><th colspan="2" align="right">Тип процессора:</th><td><xforms:select1 model="computer_model" ref="processor_id">Данные о процессорах выбираются из выпадающего списка (xforms:select1).Атрибут model="computer_model" ссылается на модель данных, а атрибутref="processor_id" задает элемент данных, в который будет сохранено значение извыбранного пункта списка.<xforms:alert>Необходимо выбрать типпроцессора</xforms:alert><xforms:itemset model="processor_model"nodeset="//processor">429<xforms:value ref="@id"/><xforms:label ref="processor_name"/></xforms:itemset>Элементсоответствуетxforms:itemsetэлементопределяет«processor»впунктыпервомсписка.Пунктуспискаинстансемоделиданных«processor_model».Элемент xforms:value определяет данные пункта списка, которые будутзаписаны в результирующий элемент.Элемент xforms:label определяет текст, отображаемый в пункте списка.В нашем случае пункты списка читаются из первого инстанса модели данных«processor_model».
Пункту соответствует элемент «processor». В пунктах спискаотображается значение элемента «processor_name», вложенного в элемент«processor». При выборе пункта списка значение атрибута «id» выбранногоэлемента «processor» записывается в другую модель данных «computer_model» вXML-элемент «processor_id».</xforms:select1></td></tr><tr><th rowspan="2" align="right">Объем ОП:</th><th align="right">(в Мб):</th><td><xforms:input model="computer_model" ref="op"><xforms:alert>Значение должно быть целым числом вдиапазоне от 1 до 4096</xforms:alert></xforms:input>Поле «Объем ОП (в Мб)» вводится как целое число в заданном диапазоне.Эти ограничения указаны в модели данных в соответствующем элементеxforms:bind.</td></tr>430<tr><th align="right">(в Гб):</th><td><xforms:output model="computer_model"value="concat(string(round(op div 1024)), ' [без округления: ',string(op div 1024), ']')"><xforms:alert>Значение вычисляется на основе поля "ОбъемОП (в Мб)"</xforms:alert></xforms:output>Поле «Объем ОП (в Гб)» вычисляется на основе поля «Объем ОП (в Мб)» ине сохраняется в модель данных.Формула для вычисления указана в атрибуте value элемента xforms:output:(op div 1024) – деление на 1024 для перевода Мб в Гб, функция roundосуществляет округление до целого числа, функция string преобразует число встроку, функция concat соединяет строки с округленным и неокругленнымзначением.Если необходимо сделать так, чтобы вычисляемое поле сохранялось в модельданных, то необходимо:1.
Ввести новый элемент в модель данных.2. Для этого элемента определить xforms:bind с атрибутом calculate,значением атрибута calculate должна быть формула для вычисления.3. В элементе xforms:output в атрибуте value задать только имя новогоэлемента, который уже вычислен в модели на основе xforms:bind.</td></tr><tr><th colspan="2" align="right">Объем жесткого диска (вГб):</th><td><xforms:input model="computer_model" ref="hdd"><xforms:alert>Значение должно быть целым числом вдиапазоне от 1 до 1000</xforms:alert>431</xforms:input>Поле «Объем жесткого диска» вводится как целое число в заданномдиапазоне.</td></tr><tr><th colspan="2" align="right">Используется как сервер:</th><td><xforms:input model="computer_model" ref="server"><xforms:hint>Если компьютер используется в качествесервера, то флаг должен быть включен</xforms:hint></xforms:input>Поле «Используется как сервер» отображается в виде флажка, так как длянего указан логический тип данных в xforms:bind.</td></tr><tr><td colspan="3"><h2>Список модернизаций</h2><ol><xforms:repeat id="repeat_upgrades" model="computer_model"nodeset="//upgrades/upgrade[@id]" appearance="compact">Список модернизаций отображается с помощью xforms:repeat.Атрибутnodeset="//upgrades/upgrade[@id]"определяетвкачествеповторяющегося элемента элемент «upgrade», который вложен в элемент«upgrades».При этом, у элемента «upgrade» обязательно должен быть указан атрибут«id».
Это условие задается потому, что по умолчанию в элемент «upgrades»вложен один пустой элемент «upgrade» (без этого неправильно работаетдобавление новых элементов «upgrade»).432Это решение является неправильным с точки зрения XForms, так как модельданных является первичной, а все элементы ввода данных должны под нееподстраиваться, но, к сожалению, более удачного решения здесь найти неудалось.Атрибутappearance="compact"предписываетотображатьвложенныеэлементы в одной строке.<li><xforms:input model="computer_model"ref="upgrade_date"><xforms:label>Дата:</xforms:label><xforms:alert>Поле не может быть пустым и должносодержать дату</xforms:alert></xforms:input>Поле ввода даты модернизации.<xforms:textarea model="computer_model"ref="upgrade_description"><xforms:label>Описание:</xforms:label><xforms:alert>Поле не может бытьпустым</xforms:alert></xforms:textarea>Многострочное поле ввода описания модернизации.<!-- Удаление модернизации --><xforms:trigger><xforms:label>Удалить</xforms:label><xforms:delete ev:event="DOMActivate"model="computer_model" nodeset="." /></xforms:trigger>Кнопка удаления текущего элемента «upgrade».
Элемент xforms:deleteудаляет элемент из заданной модели (model="computer_model"). Удаляетсятекущий элемент «upgrade» (nodeset=".").Событие DOMActivate возникает при нажатии на кнопку или при нажатииклавиши «ввод». Атрибут ev:event="DOMActivate" элемента xforms:delete433указывает на то, что xforms:delete должен выполняться, если элементxforms:trigger активирован.Фактическиатрибутev:event="DOMActivate"означает,чтоэлементxforms:delete является обработчиком события по нажатию xforms:trigger.</li></xforms:repeat></ol><!-- Добавление модернизации --><xforms:trigger>Кнопка добавления данных о модернизации.<xforms:label>Добавить</xforms:label><!-- Действия --><xforms:action ev:event="DOMActivate">Несколько действий объединяются с помощью одного элемента верхнегоуровня xforms:action, который является обработчиком события по нажатиюкнопки (атрибут ev:event="DOMActivate").В xforms:action вложены команды, которые добавляют новый XML-элемент иустанавливают значение по умолчанию для добавленного элемента, эти командывыполняются последовательно, в указанном порядке.<!-- Добавление элемента из отдельного instance --><xforms:insert model="computer_model"nodeset="//upgrades/upgrade" at="last()" position="after"origin="instance('upgrade_instance')//upgrade" />Команда xforms:insert добавляет новый элемент «upgrade».Атрибут model="computer_model" задает модель данных.Следующие атрибуты задают приемник данных.Атрибут nodeset="//upgrades/upgrade" указывает, что при добавлении нужноориентироваться на элемент «upgrade», вложенный в «upgrades» (поэтому иприходится по умолчанию добавлять хотя бы один пустой «upgrade»), at="last()" –ориентироваться на последний элемент «upgrade», position="after" – добавлятьпосле элемента «upgrade».434Источник данных задается атрибутом origin.Атрибут origin="instance('upgrade_instance')//upgrade" указывает, что данныедобавляются из элемента upgrade, который находится в другом инстансе модели.Как только новый элемент будет добавлен, он сразу попадает в областьдействия приведенного выше xforms:repeat (то есть соответствует XPathвыражению,указанномуватрибутеnodesetэлементаxforms:repeat)иотображается как строка с информацией о модернизации.При этом сама кнопка добавления находится вне xforms:repeat.<!-- Генерация id - id генерируется как номер элемента всписке и текущие дата и время --><xforms:setvalue model="computer_model"ref="//upgrade[last()]/@id"value="concat(string(index('repeat_upgrades')), '_',string(now()))"/>С помощью xforms:setvalue устанавливается значение по умолчанию дляэлементов формы.В нашем случае добавляемый элемент «upgrade» содержит пустыевложенные поля данных, поэтому явно очищать их с помощью xforms:setvalue ненужно.С помощью xforms:setvalue мы генерируем уникальный атрибут «id» длянового элемента «upgrade».Вообще, язык XPath содержит функцию generate-id, которая генерируетуникальный идентификатор дляузла (возможно, в некоторых XForms-процессорах можно использовать эту функцию).














