Содержание


XPages без сложностей

Comments

Примечание редактора. Хорошо знаете эту тему? Хотите поделиться своим опытом? Примите участие в wiki-программе IBM Lotus software today.

Разработка XPages-страниц, в сущности, базируется на двух традиционных элементах дизайна: формах (form) для определения данных и представлениях (view) для вывода данных. Однако это не являются абсолютным требованием. Для перемещения данных между элементами управления и хранилищем данных Lotus Domino можно использовать JavaScript, и это несложно.

Возможно, вам не хочется использовать JavaScript по различным причинам:

  • Формы и представления позволяют визуально определять сложные структуры.
  • После объединения необходимых форм и представлений процесс разработки протекает довольно легко. Например, связывание формы с элементом управления на XPage состоит просто в перемещении поля на элемент управления.
  • Если вы помещаете XPages в существующее приложение IBM Lotus Domino Designer, то, наверное, захотите полностью использовать возможности существующих форм и представлений.

Но новичкам в Lotus Domino Designer для изучения форм и представлений требуется время. И даже если у вас есть опыт работы с Lotus Domino Designer, формы и представления потребуют выхода за рамки парадигмы XML. Вам придется иметь дело с @-функциями и LotusScript®.

В данной статье представлена информация по использованию JavaScript для создания, просмотра, редактирования и удаления документов в приложении IBM Lotus Domino. В ней рассказывается, как связать данные из этих документов с элементами управления на XPage.

В статье также приводится вводная информация по использованию JavaScript в XPages. При использовании JavaScript в XPages в вашем распоряжении обширная библиотека инструментов для облегчения управления пользовательской средой и серверным хранилищем данных. Если вы знакомы с LotusScript, вам известны NotesSession, NotesDatabase, NotesDocument и многие другие объекты Domino Objects. Такие же объекты доступны и в JavaScript, но работать с ними в исходном коде проще.

Наконец, в данной статье демонстрируется, где и как подключать JavaScript в пользовательском интерфейсе XPages. JavaScript можно использовать, например, для возврата значения вычисляемого поля. Можно подключить JavaScript к событию onclick кнопки. Можно использовать JavaScript для определения значения (true или false) свойства Visual элемента управления.

Первое приложение

Запустите Lotus Domino Designer и создайте приложение. Ниже названия приложения слева (навигатор) щелкните правой кнопкой мыши на XPages и выберите New XPage. Дайте странице XPage название main и нажмите кнопку OK. После этого в центральной части страницы отобразится редактор, а справа – набор элементов управления. Если элементы управления отсутствуют или вы по какой-либо причине закрыли вкладку, их можно восстановить, выбрав Window - Show Eclipse Views - Controls.

Начните проектирование новой страницы – перетащите Computed Field из вкладки Controls (возможно, придется прокрутить окно вниз) в центр палитры. Другой способ - дважды щелкнуть на Computed Field, после чего оно отобразится в редакторе. Ваше окно с выбранной вкладкой Properties и вычисляемым полем должно выглядеть примерно так, как изображено на рисунке 1.

Рисунок 1. XPage с элементом управления Computed Field
Рисунок 1. XPage с элементом управления Computed Field
Рисунок 1. XPage с элементом управления Computed Field

Давайте установим значение для данного вычисляемого поля. Выберите Value (в Properties) и JavaScript. Сценарий можно вводить непосредственно в отображаемом окне, но давайте нажмем кнопку Open Script Dialog, расположенную в правой части окна, как показано на рисунке 2.

Рисунок 2. Выбор JavaScript для установки значения
Рисунок 2. Выбор JavaScript для установки значения
Рисунок 2. Выбор JavaScript для установки значения

Обратите внимание на глобальные объекты в левой части редактора сценариев, показанные на рисунке 3. (Если вкладка Reference не выбрана, перейдите на нее. Если не выбраны Global Objects, выберите их из ниспадающего меню под пунктом Libraries.) Прокрутите список вниз и дважды щелкните левой кнопкой мыши на элементе session. Он отобразится в редакторе. Введите точку и подождите секунду. Отобразится список методов. Найдите строку getCommonUserName(): и дважды щелкните левой кнопкой мыши на ней.

Рисунок 3. Информационный помощник для глобального объекта session
Рисунок 3. Информационный помощник для глобального объекта session
Рисунок 3. Информационный помощник для глобального объекта session

Глобальные объекты являются входными точками для иерархии объектов, доступных для XPages JavaScript на сервере Lotus Domino. Объект session предоставляет доступ к сеансу Lotus Domino и его дочерних объектов. Откройте объект session в панели Reference в левой части окна, как показано на рисунке 4. Вы увидите те же методы, которые видели в редакторе при вводе точки после session.

Рисунок 4. Развертывание объекта session в панели Reference
Рисунок 4. Развертывание объекта session в панели Reference
Рисунок 4. Развертывание объекта session в панели Reference

Теперь выберите Domino в ниспадающем списке, расположенном под Libraries. Найдите и откройте NotesSession. Вы снова увидите этот же список (см. рисунок 5). Фактически глобальный объект session является объектом Lotus Domino NotesSession для текущего пользователя.

Рисунок 5. Развертывание объекта Domino NotesSession в панели Reference
Рисунок 5. Развертывание объекта Domino NotesSession в панели Reference
Рисунок 5. Развертывание объекта Domino NotesSession в панели Reference

Измените исходный код следующим образом:

return "Hello " + session.getCommonUserName()

Ключевое слово return подразумевается по умолчанию, поэтому можно написать так:

"Hello " + session.getCommonUserName()

Закройте редактор сценариев и сохраните изменения, нажав кнопку OK.

Можно просмотреть выполненную работу, выбрав Design - Preview в Web Browser (или Preview в ярлыке Web Browser), а затем выбрав браузер. (Сначала необходимо добавить Anonymous в список управления доступом к приложению с привилегиями не меньше author.) Для предварительного просмотра Lotus Domino запускает на вашем компьютере минисервер.

URL-адрес просматриваемой страницы имеет вид http://localhost/foo.nsf/main.xsp. Можно ввести этот URL непосредственно в браузер, если вы уже просматривали страницу ранее и Lotus Domino Designer продолжает работать, поскольку в этом случает минисервер должен работать. Если приложение расположено на сервере Lotus Domino, используйте имя сервера вместо localhost.

При использовании Lotus Domino Designer 8.5.1 можно также выбрать Design - Preview в Notes (либо Preview в ярлыке Notes).

Для настройки вашего приложения на запуск в Lotus Notes® с XPage выберите Application Properties в нижней части навигатора. После отображения свойств приложения выберите вкладку Launch. Установите параметр Launch в значение Open designated XPage (Standard client) и укажите XPage.

Далее вы узнаете, как переходить с одной XPage на другую после запуска приложения. При работе с элементом дизайна, не принадлежащим XPage, можно указать URL-адрес Lotus Notes отображаемой формы в следующей формуле (этот пример является действием в представлении):

@URLOpen("notes:///foo.nsf/main.xsp?OpenXPage")

При работе с сервером вставьте его имя:

@URLOpen("notes://myserver/foo.nsf/main.xsp?OpenXPage")

Есть еще один интересный момент, который стоит упомянуть перед переходом к работе с данными. В нижней части экрана выберите Source, как показано на рисунке 6. Отобразится XML, определяющий вашу XPage###. Вместо работы с визуальным редактором можно непосредственно редактировать XML. Выберите Design для возврата в редактор.

Рисунок 6. Исходный XML-код для XPage
Рисунок 6. Исходный XML-код для XPage
Рисунок 6. Исходный XML-код для XPage

Работа с данными

Давайте поместим на XPage еще одно вычисляемое поле ниже первого. Нажмите клавишу Enter и дважды щелкните левой кнопкой мыши или перетащите еще один элемент управления Computed Field. Нажмите Value в панели Properties, выберите JavaScript и нажмите кнопку Open Script Dialog.

Снова отобразится редактор сценариев. Однако открывать редактор сценариев необязательно. Как уже говорилось ранее, можно редактировать сценарий в окне под кнопкой JavaScript, как показано на рисунке 2. Можно также редактировать сценарий в XML-коде, используя вкладку Source. В то же время редактор сценариев предоставляет больше места и имеет слева вкладки Reference и Outline.

Прокрутите список Global Objects на вкладке Reference и дважды щелкните левой кнопкой мыши на элементе database, как показано на рисунке 7. После его отображения в редакторе введите точку и подождите появления списка методов. Это еще одна очень полезная глобальная переменная. Она создает объект NotesDatabase для текущей базы данных, т.е. приложение, содержащее данную XPage.

Рисунок 7. Информационный помощник по глобальному объекту database
Рисунок 7. Информационный помощник по глобальному объекту database
Рисунок 7. Информационный помощник по глобальному объекту database

Дважды щелкните левой кнопкой мыши на getAllDocuments(): NotesDocumentCollection. После ввода еще одной точки отобразится список методов, принадлежащих объекту NotesDocumentCollection, одним из которых является getCount(): int. Дважды щелкните левой кнопкой мыши на этом методе и опять введите точку. На этот раз появится список методов для класса String, находящегося в библиотеке Standard. Дважды щелкните левой кнопкой мыши на строке toFixed():. Ваш сценарий выглядит так:

database.getAllDocuments().getCount().toFixed()

Этот сценарий получает количество всех документов в текущей базе данных в виде строки. Измените его следующим образом:

return "Number of documents in database: " + database.getAllDocuments().getCount().toFixed()

Нажмите кнопки OK, save и preview. Для нового приложения в окне предварительного просмотра отобразится нулевое количество документов в базе данных.

В качестве дополнительной информации (не относящейся к нашему примеру приложения) ниже приводится исходный код для получения количества документов в указанной базе данных. Первый параметр session.getDatabase – имя сервера (значение null означает локальную систему). Второй параметр – это имя приложения относительно каталога data Lotus Notes.

return session.getDatabase(null, "fooA.nsf").getAllDocuments().getCount().toFixed()

А в листинге 1 приведен код получения названий всех NSF-приложений в локальном каталоге Lotus Notes. Объект, возвращаемый session.getDbDirectory, имеет тип NotesDbDirectory. Его методы getFirstDatabase и getNextDatabase возвращают объекты типа NotesDatabase.

Листинг 1. Исходный код получения названий всех NSF-приложений
	var list = "";
	var dir = session.getDbDirectory(null);
	var db = dir.getFirstDatabase(1247); // 1247 = type DATABASE
	while (db != null) {
		if (!list.isEmpty()) list = list + ", ";
		list = list + db.getFileName();
		db = dir.getNextDatabase();
	}
	return list

Создание документа

Первая задача при создании документа заключается в получении пользовательских данных из XPage. С этой целью давайте создадим два поля – строковое и числовое.

  1. Создайте таблицу 2 на 2. Найдите элемент управления Table в Container Controls.
  2. В первый столбец поместите элементы управления Label, обозначающие тему (subject) и количество (number).
  3. Во второй столбец поместите элементы управления Edit Box.

Визуальный редактор должен выглядеть примерно так, как показано на рисунке 8.

Рисунок 8. Поля редактирования для темы и количества
Рисунок 8. Поля редактирования для темы и количества

Назначением поля редактирования является, естественно, ввод пользователем какой-либо информации. Но как обратиться к этим данным? Если бы XPage поддерживалась формой Lotus Domino, нужно было бы связывать каждое поле редактирования с полем формы. Данный подход кратко рассматривается в конце статьи. Для программирования мы свяжем каждое поле с глобальной переменной.

Выберите первое поле редактирования и Data под Properties. Выберите Advanced. В ниспадающем списке выберите Scoped Variable. В поле Parameter выберите Request Scope из списка. Наконец, придумайте имя переменной. Давайте назовем ее subject (см. рисунок 9).

Рисунок 9. Связывание поля с переменной с ограниченной областью видимости (scoped)
Рисунок 9. Связывание поля с переменной с ограниченной областью видимости (scoped)
Рисунок 9. Связывание поля с переменной с ограниченной областью видимости (scoped)

Эта переменная доступна странице, когда сервер обрабатывает страницу при запросе URL. Когда сервер завершает обработку URL-запроса, доступ теряется и память освобождается. В ниспадающем списке можно увидеть, что существует четыре типа переменных с заданной областью видимости (scoped). Это, в порядке уменьшения области видимости, Application Scope, Session Scope, View Scope и Request Scope.

Аналогичным способом свяжите второе поле редактирования с переменной типа Request Scope с именем number. Здесь необходимо также указать одну дополнительную характеристику. Очень важно изменить тип отображения на Number, поскольку мы хотим интерпретировать введенные данные как числовые (см. рисунок 10).

Рисунок 10. Связывание поля со scoped-переменной типа Number
Рисунок 10. Связывание поля со scoped-переменной типа Number
Рисунок 10. Связывание поля со scoped-переменной типа Number

Теперь приступим к созданию документа. Это нетрудно!

Поместите элемент управления Button ниже полей редактирования. Смените надпись на Create document.

Перейдите на вкладку Events. Слева расположены события, которые можно использовать с этим элементом управления. Нам нужно событие onclick, которое выделяется по умолчанию. Затем выберите Script Editor и убедитесь в том, что выбрана вкладка Server (по умолчанию) (см. рисунок 11).

Рисунок 11. Указание события для кнопки
Рисунок 11. Указание события для кнопки
Рисунок 11. Указание события для кнопки

Можно ввести сценарий непосредственно в окне или нажать кнопку Open Script Dialog справа. При этом отобразится модальное окно редактора сценариев со справочной вкладкой с левой стороны.

В листинге 2 показан сценарий.

Листинг 2. Код JavaScript для создания документа
	var doc = database.createDocument();
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	doc.save();
	requestScope.subject = null;
	requestScope.number = null

В первой строке создается объект NotesDocument. В следующих двух строчках объект заполняется значениями элементов на основе значений глобальных переменных, связанных с нашими элементами управления – полями редактирования. Обратите внимание, что спецификация представляет собой область видимости, за которой после точки следует имя переменной. Ожидается, что пользователи уже ввели значения в эти поля. Отметим, что subject и number заключаются в кавычки. Определять имена элементов в документе должны вы. В хранилище данных ничего не происходит до тех пор, пока не выполнится метод save. По завершении scoped-переменные очищаются, т.е. старые значения не показываются в пользовательском интерфейсе и не мешают будущим событиям.

Сохраните и просмотрите страницу. Введите значения subject и number, затем нажмите кнопку Create document. Нажатие кнопки вызывает передачу URL с информацией о странице на сервер Lotus Domino (или на минисервер в случае предварительного просмотра). Сервер обрабатывает код события и отправляет измененную страницу обратно в браузер (или в клиентское приложение Lotus Notes). Повторив эти действия несколько раз, вы увидите, что количество документов увеличилось.

Просмотр документов

Поскольку количество документов растет, внутри что-то происходит. Полезно рассмотреть это подробнее. Обычным методом просмотра документов в Lotus Domino является использование элемента дизайна View. XPages имеет элемент управления view, содержащий элемент дизайна view. Но мы собираемся использовать элемент управления Data Table и немного JavaScript.

Выберите место под кнопкой. В Container Controls дважды щелкните левой кнопкой мыши на элементе управления Data Table или перетащите его. В Properties выберите JavaScript и введите сценарий, возвращающий коллекцию (collection) документов. Вторая важная спецификация в данном примере – это имя набора, rowdoc, указываемое вами (см. рисунок 12).

Рисунок 12. Указание элемента управления Data Table
Рисунок 12. Указание элемента управления Data Table
Рисунок 12. Указание элемента управления Data Table

Таблица данных работает с указанным набором документов. Данный пример возвращает набор всех документов в базе данных. Существует множество способов программного изменения набора для возврата подмножества документов, например, полнотекстовый поиск.

Щелкните правой кнопкой мыши внутри таблицы данных и выберите Insert Column или Append Column. Обратите внимание, что отображаемый столбец имеет три строки. Используйте верхнюю строку в качестве заголовка; вставьте элемент управления Label с меткой subject.

Средняя строка – это, по существу, элемент управления Repeat. Элементы управления Repeat очень полезны. В случае с таблицей данных элемент Repeat предоставляет переменное число строк, зависящее от количества объектов в базовом наборе. Каждая строка выступает как один элемент набора. В данном примере используется набор NotesDocumentCollection всех документов в текущей базе данных. Каждый элемент набора является объектом типа NotesDocument. Помните набор под названием rowdoc? Это название указывает на объект NotesDocument, ассоциированный с текущей строкой, т.е. строкой, с которой работает пользователь.

Выберите среднюю строку. В Core Controls дважды щелкните левой кнопкой мыши на элементе управления Computed Field или перетащите его. Ниже Properties выберите Value. В качестве значения выберите JavaScript и введите сценарий. Сценарий вызывает метод rowdoc getItemValueString (объект NotesDocument, как упоминалось ранее) для получения значения элемента subject (см. рисунок 13).

Рисунок 13. Указание значения для повторения строки
Рисунок 13. Указание значения для повторения строки
Рисунок 13. Указание значения для повторения строки

Замечание по информационному помощнику. К сожалению ввод точки после rowdoc не вызывает появления списка методов, поскольку редактор не знает о типе rowdoc. Необходимо следить за правильным вводом названий методов, используя справочную панель или документацию. В справочной панели можно дважды щелкнуть левой кнопкой мыши для отображения метода в редакторе. Также можно применить хитрость и заставить информационного помощника работать, введя сначала строку кода, идентифицирующую тип. В приведенном ниже исходном коде информационный помощник знает, что rowdoc имеет тип NotesDocument, и показывает его методы.

rowdoc:NotesDocument == null;
return rowdoc.

Предварительный просмотр отображает таблицу с одним столбцом с заголовком subject и строку, содержащую значение subject для каждого документа в текущей базе данных.

Выберите таблицу данных (не столбец), щелкните правой кнопкой мыши и выберите Append Column. Аналогичным образом создайте столбец для элемента number. На этот раз сценарий для вычисляемого поля выглядит следующим образом:

return rowdoc.getItemValueDouble("number")

Наконец, добавьте третий столбец для отображения даты изменения. Вот код сценария:

return rowdoc.getLastModified()

Теперь при предварительном просмотре отображаются три столбца с темой, количеством и датой изменения.

Редактирование и удаление

Давайте реализуем возможность редактирования существующих документов.

Добавьте еще один столбец в таблицу данных. Дважды щелкните левой кнопкой мыши на элементе управления Button или перетащите его в среднюю строку и измените надпись на edit. Перейдите в вкладку Events и убедитесь в том, что выбраны событие onclick и вкладка Server. Выберите Script Editor. Введите следующий сценарий:

sessionScope.docUnid = rowdoc.getUniversalID();
requestScope.subject = rowdoc.getItemValueString("subject");
requestScope.number = rowdoc.getItemValueDouble("number")

Этот код назначает глобальным переменным значение универсального идентификатора документа и значения двух элементов. Для универсального идентификатора необходима переменная типа sessionScope, поскольку он используется в двух запросах.

Последние две переменные связаны с полями редактирования. При нажатии пользователем кнопки edit адрес URL отсылается на сервер Lotus Domino. Сервер посылает обратно страницу с двумя областями редактирования, заполненными значениями из соответствующей строки таблицы данных. Пользователь может изменить эти данные. На рисунке 14 изображена ситуация после нажатия пользователем кнопки edit для второй строки.

Рисунок 14. Получение строки данных для редактирования
Рисунок 14. Получение строки данных для редактирования
Рисунок 14. Получение строки данных для редактирования

Теперь понадобится кнопка для выполнения замены. Поместите эту кнопку рядом с кнопкой Create document и назовите ее Replace document. Для начала можно скопировать кнопку Create document. В ее событии onclick используйте JavaScript-код, приведенный в листинге 3. Этот код аналогичен кнопке Create document, за исключением первой строки, в которой вместо создания документа извлекается существующий документ по его универсальному идентификатору.

Листинг 3. JavaScript для замены значений в документе
	var doc = database.getDocumentByUNID(sessionScope.docUnid);
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	doc.save();
	requestScope.subject = null;
	requestScope.number = null

Возможно, вы захотите также создать кнопку Cancel с приведенным ниже кодом. Она очищает поля редактирования без выполнения каких-либо изменений в базе данных.

requestScope.subject = null;
requestScope.number = null

Если хотите, добавьте следующую строку в событие onclick кнопки edit для повышения удобства работы:

sessionScope.editMode = true

Добавьте следующую строку кода в событие onclick кнопок Replace document и Cancel:

sessionScope.editMode = false

Это дополнение устанавливает глобальную переменную editMode в значение true только во время выполнения процедуры редактирования пользователем. В противном случае ее значение не инициализировано или равно false. Теперь перейдите к свойствам для трех кнопок выше таблицы. Найдите свойство Visible. Нажмите на ромбик и выберите значение Compute. Для кнопки Create document используйте следующий сценарий:

sessionScope.editMode != true

Для кнопок Replace document и Cancel используйте следующий код сценария:

sessionScope.editMode == true

Теперь, когда пользователь переходит к документу, видна только кнопка Create document. После нажатия кнопки edit кнопка Create document исчезает, а две другие кнопки появляются.

Удалить документ просто. Добавьте еще один столбец и поместите кнопку в среднюю строку. Назовите ее remove. Для ее события onclick используйте следующий код:

rowdoc.remove(true)

Весь код, который мы рассматривали до сих пор, размещается на стороне сервера. Он выполняется после того, как браузер или клиентское приложение Lotus Notes отправит страницу на сервер. За несколькими исключениями, JavaScript является стандартным, но он имеет доступ к дополнительным библиотекам, в частности, к библиотеке Domino Objects.

Можно также использовать JavaScript на стороне клиента. Этот код выполняется в браузере или клиентском приложении Lotus Notes до отправки страницы на сервер. JavaScript является стандартным для используемых клиентских приложений и имеет доступ к стандартной модели Web DOM.

Для одного и того же события можно задать как серверные (server-side), так и клиентские сценарии. Клиентский сценарий может предотвратить выполнение операции на стороне сервера, возвратив значение false.

В нашем примере приложения мы используем клиентский сценарий для подтверждения удаления документа. Вернитесь к событию onclick для кнопки remove. В нем уже имеется серверный код. Перейдите на вкладку Client, выберите Script Editor и введите следующий код (см. рисунок 15):

return window.confirm(“Do you really want to delete this document?”)

Рисунок 15. Клиентский код для события
Рисунок 15. Клиентский код для события
Рисунок 15. Клиентский код для события

Когда пользователь нажимает кнопку, клиентский сценарий отображает окно подтверждения. Нажатие кнопки OK возвращает значение true, и сценарий на стороне сервера выполняется. Нажатие кнопки Cancel возвращает значение false, и серверный сценарий не выполняется.

Использование нескольких страниц

Рассмотрим более общий сценарий, когда пользователь отправляет данные с отдельных страниц. Перед началом работы сделайте копию XPage-страницы main.

Создайте XPage-страницу под названием create. Вырежьте таблицу 4 на 4 с полями редактирования из XPage-страницы main и поместите ее на XPage-страницу create. Скопируйте (не вырезайте) кнопки Create document и Cancel с main и поместите их на XPage-страницу create. На XPage-странице create выберите кнопку Create document и измените ее название на Submit. Для обеих кнопок измените свойство Visible так, чтобы они были видимы всегда (см. рисунок 16).

Рисунок 16. XPage для создания документа
Рисунок 16. XPage для создания документа

Поля редактирования уже готовы, а код кнопки нужно изменить. Откройте редактор сценариев с событием onclick для кнопки Submit. Первые четыре строки, где создается документ, работают аналогично. Две строки, очищающие поля редактирования, не нужны, потому что мы собираемся покинуть эту страницу. Наконец, нужно добавить строку для возврата пользователя на главную страницу. Код выглядит так, как показано в листинге 4.

Листинг 4. JavaScript для создания документа и открытия другой страницы
	var doc = database.createDocument();
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	doc.save();
	context.redirectToPage("main")

Глобальный объект context в библиотеке XSP имеет тип XSPContext.

Для кнопки Cancel мы хотим удалить существующий код и заменить его последней строкой из сценария Submit. Т.е. мы хотим возвратить пользователя на главную страницу. Есть и еще один простой способ выполнить эту задачу. Перейдите к событию onclick для кнопки. Выберите Simple Actions (нажмите кнопку OK при появлении предупреждения) и затем Add Action. В отобразившемся окне проверьте, что Action установлено в Open Page; при необходимости выберите это значение из ниспадающего меню. Затем нажмите кнопку OK (см. рисунок 17).

Рисунок 17. Простое действие для открытия другой страницы
Рисунок 17. Простое действие для открытия другой страницы
Рисунок 17. Простое действие для открытия другой страницы

В качестве дополнительной информации сообщим, что существует третий способ возврата на главную страницу. Установите тип кнопки как Cancel и удалите весь код события. Перейдите во вкладку Properties для страницы и установите для Next page (if update fails) значение main.

Теперь вернитесь к XPage main и выберите кнопку Create document. Удалите код для события onclick. По этой кнопке мы хотим переходить на XPage-страницу create. Можно использовать следующий JavaScript-код.

context.redirectToPage("create")

Можно также использовать простое действие.

Просмотрите страницу в окне предварительного просмотра. Нажмите кнопку Create document. Введите какие-либо данные. Попробуйте нажать кнопку Submit. Попробуйте нажать кнопку Cancel.

Затем создайте XPage-страницу под названием replace. Скопируйте все содержимое XPage-страницы create и поместите в replace. Для этой страницы необходимо связать поля редактирования с переменными типа sessionScope, поскольку данные передаются по нескольким запросам.

Кнопку Submit нужно откорректировать. Вместо создания документа мы хотим получить существующий документ при помощи универсального идентификатора, заданного на XPage-странице main. Также необходимо изменить глобальные переменные на переменные типа sessionScope. После использования переменных sessionScope присвойте им значение null, как показано в листинге 5.

Листинг 5. JavaScript-код для замены значений в документе и открытия другой страницы
	var doc = database.getDocumentByUNID(sessionScope.docUnid);
	doc.replaceItemValue("subject", sessionScope.subject);
	doc.replaceItemValue("number", sessionScope.number);
	doc.save();
	sessionScope.subject = null;
	sessionScope.number = null;
	context.redirectToPage("main")

Вернитесь на XPage-страницу main, измените кнопку edit, связав ее с переменными типа sessionScope для установки значений текущего элемента, и откройте XPage-страницу replace, как показано в листинге 6.

Листинг 6. JavaScript-код открытия страницы для редактирования существующего документа
	sessionScope.docUnid = rowdoc.getUniversalID();
	sessionScope.subject = rowdoc.getItemValueString("subject");
	sessionScope.number = rowdoc.getItemValueDouble("number");
	context.redirectToPage("replace")

Теперь у нас есть три страницы: main, create и replace. Пользователь открывает приложение на странице main. Нажатие кнопки Create document отправляет его на страницу create с пустыми полями редактирования. Действие submit или cancel возвращает пользователя на страницу main. Нажатие кнопки edit отправляет пользователя на страницу replace с заполненными полями. Действие submit или cancel снова возвращает на страницу main.

Форматированный текст

Работа с форматированным текстом (rich text) требует особого подхода. Нельзя просто устанавливать и получать значения переменных. Если вы не сможете сразу разобраться в представленном в данном разделе исходном коде, используйте его в качестве рецепта.

В форме create дважды щелкните левой кнопкой мыши на элементе управления Rich Text или перетащите его ниже областей редактирования и выше кнопок. При желании настройте его размер. Перейдите во вкладку Data под properties, выберите Advanced и свяжите элемент управления с переменной типа RequestScope под названием body.

Перейдите к событию onclick кнопки Submit. Настройте сценарий на чтение, как показано в листинге 7. Новый код начинается в строке 4 созданием объекта NotesStream и заканчивается в строке 8 закрытием этого объекта. Глобальная переменная requestScope.body, связанная с элементом управления rich text, имеет тип com.ibm.xsp.http.MimeMultipart. Ее метод getHTML получает содержимое элемента управления rich-text в виде XML-кода. Затем создайте элемент rich-text на сервере как объект NotesMIMEEntity и используйте XML-содержимое из элемента управления для установки его значения. Объект NotesStream необходим в качестве посредника.

Листинг 7. JavaScript-код для создания документа с форматированным текстом
	var doc = database.createDocument();
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	var stream = session.createStream();
	stream.writeText(requestScope.body.getHTML());
	var entity = doc.createMIMEEntity("body");
	entity.setContentFromText(stream,"text/html;charset=UTF-8", 1725);
	stream.close()
	doc.save();
	context.redirectToPage("main")

Для получения данных с сервера в элемент управления rich-text можно использовать метод getContentAsText объекта NotesMIMEEntity. На странице replace добавьте элемент управления Rich Text ниже областей редактирования как на странице create, но свяжите его с переменной типа sessionScope под названием body, а не с переменной requestScope. На странице main перейдите к событию onclick для кнопки edit. Настройте исходный код на чтение, как показано в листинге 8. Новый код расположен в строках с 4 по 6. Форматированный документ извлекается с сервера как объект NotesMIMEEntity, затем с помощью его метода getContentAsText устанавливается значение элемента управления rich-text. Операция копирования в строке 6 потребуется в дальнейшем на странице replace для сравнения.

Листинг 8. JavaScript-код открытия страницы для редактирования существующего документа, содержащего форматированный текст
	sessionScope.docUnid = rowdoc.getUniversalID();
	sessionScope.subject = rowdoc.getItemValueString("subject");
	sessionScope.number = rowdoc.getItemValueDouble("number");
	var entity = rowdoc.getMIMEEntity("body");
	sessionScope.body = entity.getContentAsText();
	sessionScope.bodyCopy = sessionScope.body;
	context.redirectToPage("replace")

На странице replace кнопку Submit необходимо изменить, чтобы она записывала значение элемента управления rich-text, но только в том случае, если это значение изменилось. Можно скопировать код из XPage-страницы create, но не забудьте выполнить необходимые изменения (см. листинг 9).

Листинг 9. JavaScript-код замены значений в документе с форматированным текстом
	var doc = database.getDocumentByUNID(sessionScope.docUnid);
	doc.replaceItemValue("subject", sessionScope.subject);
	doc.replaceItemValue("number", sessionScope.number)
	if(!sessionScope.body.toString().equals(sessionScope.bodyCopy.toString())) {
		var stream = session.createStream();
		stream.writeText(sessionScope.body.getHTML());
		var entity = doc.getMIMEEntity("body");
		entity.setContentFromText(stream,"text/html;charset=UTF-8", 1725);
		stream.close();
	}
	doc.save();
	sessionScope.subject = null;
	sessionScope.number = null;
	sessionScope.body = null;
	context.redirectToPage("main")

Выполнение тех же действий с использованием формы

Для полноты изложения и сравнения давайте заново разработаем страницы create и replace, связывая данные с формой и не используя JavaScript. Если вы хотите сохранить имеющийся проект, скопируйте XPage-страницы.

Щелкните правой кнопкой мыши на элементе Forms в навигаторе и выберите New Form. Назовите новую форму main и нажмите кнопку OK. Командой Create - Field создайте три поля: с именем subject и типом Text, именем number и типом Number, именем body и типом Rich Text (см. рисунок 18).

Рисунок 18. Форма с тремя полями
Рисунок 18. Форма с тремя полями
Рисунок 18. Форма с тремя полями

Поля можно поместить в любое место формы. В данном примере внешний вид не имеет значения. Сохраните форму.

Откройте XPage-страницу create. Выберите саму XPage, затем выберите XPage ниже Properties и установите для Next page (success or cancel) значение main. Это будет означать, что после нажатия кнопки Submit или Cancel в браузер (или клиентское приложение Lotus Notes) должна передаваться страница main (объяснение приведено далее). См. рисунок 19.

Рисунок 19. Указание следующей открываемой страницы
Рисунок 19. Указание следующей открываемой страницы
Рисунок 19. Указание следующей открываемой страницы

Выберите Data и добавьте источник данных Lotus Domino Document. Укажите текущее приложение, форму main и Create document для действия по умолчанию. Имя document1 можно оставить. В результате форма становится источником определений данных для XPage-страницы (см. рисунок 20).

Рисунок 20. Указание формы в качестве источника данных для Xpage
Рисунок 20. Указание формы в качестве источника данных для Xpage
Рисунок 20. Указание формы в качестве источника данных для Xpage

Теперь выберите первое поле редактирования. Выберите Simple data binding. Укажите в качестве источника данных document1 и свяжите элемент управления с subject. Это ссылка на поле subject в форме main. То же самое сделайте для второго поля редактирования, но свяжите его с number (см. рисунок 21). Можно также выполнить связывание путем перемещения поля с палитры данных справа на элемент управления.

Рисунок 21. Связывание элемента управления с полем формы
Рисунок 21. Связывание элемента управления с полем форме
Рисунок 21. Связывание элемента управления с полем форме

Выберите элемент управления rich-text. Свяжите его с body. Теперь ваши элементы управления XPage связаны с данными, определенными в форме.

Измените тип первой кнопки на Submit. Под Events проверьте, что код события отсутствует. Для кнопки этого типа код не требуется (см. рисунок 22).

Рисунок 22. Указание кнопки типа Submit
Рисунок 22. Указание кнопки типа Submit
Рисунок 22. Указание кнопки типа Submit

Измените тип второй кнопки на Cancel. Аналогично убедитесь в отсутствии какого-либо кода события или простого действия.

Этот процесс работает со страницей create. Он заменяет JavaScript-код связываниями формы и специальными типами кнопок.

Страница replace переопределяется аналогичным образом. Связывание данных для элементов управления такое же, как и на странице create. Кнопки аналогичны. Единственное различие заключается в том, что действием по умолчанию для данных XPage является Edit document.

Теперь перейдем к странице main. Удалите код события onclick кнопки edit и переопределите его как простое действие Open Page. Возможно, вы захотите открыть страницу replace в режиме Edit document. Вычислите редактируемую страницу, используя переменную rowdoc (из таблицы данных) для получения UNID документа, который хотите редактировать (т.е. нужно немного JavaScript-кода). См. рисунок 23.

Рисунок 23. Простое действие для открытия страницы, предназначенной для редактирования документа
Рисунок 23. Простое действие для открытия страницы, предназначенной для редактирования документа
Рисунок 23. Простое действие для открытия страницы, предназначенной для редактирования документа

Кнопку Create document, открывающую страницу create, можно оставить как есть. Кнопки Replace document и Cancel можно удалить.

Готово. JavaScript-код для создания и замещения документов удален. Эти функции теперь реализованы путем связывания данных с формой, использования кнопок с типом Submit и Cancel, настройки следующей страницы после действия submit или cancel. Кнопка remove оставлена как есть, поскольку JavaScript-решение является самым простым.

Можно также создать элемент дизайна View и использовать его в качестве основы для элемента управления View вместо таблицы данных. Функции кнопок edit и remove можно реализовать в полученном представлении.

Заключение

Lotus Domino Designer хранит свои серверные данные как записи документов (document notes) в приложении Lotus Domino (файл NSF), используя протоколы Lotus Notes. Традиционный доступ осуществляется через элементы дизайна, называемые формами и представлениями. Формы определяют данные и способ отображения документа, а представления являются средством отображения и работы с наборами документов.

Элемент дизайна XPages теперь инкапсулирует весь пользовательский интерфейс. Для определения данных можно связать элементы управления XPages с полями форм. В качестве альтернативы можно обращаться к данным посредством JavaScript и объектов Domino Objects. Аналогично можно использовать представления для отображения и доступа к наборам документов, но также можно использовать таблицы данных и JavaScript.


Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Lotus
ArticleID=794549
ArticleTitle=XPages без сложностей
publish-date=02202012