Використання XForms і Ajax для створення поля форми з автозаповненням (исходники), Різне, Програмування, статті

Попередні вимоги


XForms – це стандартизована технологія, однак все ще не реалізована за замовчуванням в більшості браузерів. В даній статті використовується підключається модуль Mozilla XForms. Цей модуль може застосовуватися в будь-яких заснованих на механізмі Mozilla Gecko браузерах, таких як Firefox, Seamonkey та Flock. Весь використовуваний тут XForms-код є стандартним, тому всі сумісні XForms-реалізації повинні бути аналогічними, але в даному випадку я тестував тільки модуль Mozilla XForms версії 0.8, встановлений на Mozilla Firefox 2.0. Аналогічно, JavaScript-код тестувався тільки на Firefox.


Всі Ajax-додатки повинні запитувати дані з якого-небудь сервера. В даній статті в якості серверної технології використовується Java. Отже, необхідна наявність Java 1.5 + разом з Java Web-контейнером, реалізують специфікацію Servlet 2.4. Ця програма тестувалося з Apache Tomcat 5.5.


Визначення: підказка для поля з автозаповненням


У даній статті ви розробите поле форми з автозаповненням. Це прототип функціональності Ajax. Одним з додатків, популяризували цю функціональність, є Google Suggest. В Google Suggest ви починаєте вводити ключове слово для пошуку, а додаток пропонує (підказує) пошукові вирази, грунтуючись на їх популярності. Це корисна функція для користувачів, оскільки їм не треба вводити пошук щодо повністю. Тим самим запобігають помилки введення. Даний технічний прийом зараз широко використовується в Web-додатках. Давайте розглянемо, як ця функціональність зазвичай реалізується за допомогою Ajax.


Створення поля з автозаповненням за допомогою Ajax


З точки зору функціональних можливостей Ajax поле з автозаповненням є досить зрозумілим. Ви будете використовувати JavaScript для перехоплення події введення користувачем даних в поле форми. Потім виконайте асинхронний запит на сервер для отримання підказок, заснованих на інформації, введеної користувачем на даний момент. Сервер поверне підказки. JavaScript-обробник обробить їх і змінить HTML DOM, щоб відобразити підказки і дати можливість кінцевому користувачу вибрати їх зі списку. Розглянемо кожен з цих кроків зі створення поля з автозаповненням за допомогою Ajax. Почнемо з HTML для цього поля.


HTML для поля з автозаповненням


HTML для поля з автозаповненням досить простий. Він приведений в лістингу 1.


Лістинг 1. HTML для поля з автозаповненням





<input type=”text” id=”tBox” onkeyup=”suggest();” autocomplete=”off”/>
<div id=”suggest”></div>

Тут все зрозуміло. Є звичайне текстове поле, але його атрибути дуже важливі. Перш за все, атрибут onkeyup використовується для оголошення того, що при кожному виникненні події onkeyup повинна викликатися JavaScript-функція під назвою suggest. Ми розглянемо цю функцію в наступному розділі. Відзначимо також, що атрибут autocomplete встановлений в Off. Це охороняє поля форми від автозаповнення браузером. Нарешті, зверніть увагу на те, що ми створюємо порожній елемент div. Ми заповнимо цей div підказками. Розглянемо, як запросити ці підказки.


JavaScript для передачі запиту


Ви бачили, що текстове поле викликає функцію suggest при введенні в нього символу користувачем. Ця функція приведена в лістингу 2.


Лістинг 2. JavaScript-функція suggest




                  / / Це не працює в IE 6
var suggestReq = new XMLHttpRequest();
function suggest() {
if (suggestReq.readyState == 4 // suggestReq.readyState == 0) {
var str = escape(document.getElementById(“tBox”).value);
suggestReq.open(“GET”, “/xfsuggest/suggest?root=” + str, true);
suggestReq.onreadystatechange = handleSuggestions;
suggestReq.send(null);
}
}

Функція suggest використовує об’єкт XMLHttpRequest для формування запиту до URL / xfsuggest / suggest. Наведений в лістингу 2 код не працює в Internet Explorer 6 або більш ранніх версіях Internet Explorer. Для Internet Explorer 6 необхідно знехтувати браузером і викликати новий ActiveXObject(“Microsoft.XMLHTTP”) для отримання об’єкта XMLHttpRequest. Після цього використовувати JavaScript для добування інформації, введеної користувачем в поле. Вона стає параметром root вашого запиту HTTP GET на сервер. Нарешті, зверніть увагу на те, що обробник відповіді налаштовується на JavaScript-функцію handleSuggestions. Ми розглянемо її пізніше. Тепер подивимося, як ваш сервер буде обробляти цей запит.


Java-код для створення підказок


Однією з чудових особливостей таких технологій на стороні клієнта як Ajax (і XForms) є те, що вони незалежні від технологій на стороні сервера. Ви можете використовувати PHP, Ruby або ще що-небудь. Тут ми будемо використовувати Java-сервлет. Код сервлета приведений в лістингу 3.


Лістинг 3. Сервлет Suggest





package org.developerworks.xfsuggest;
import java.io.IOException;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class SuggestServlet extends HttpServlet {
private final int listSize = 15;
private final Random gen = new Random(Calendar.getInstance().getTimeInMillis());

protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
String root = request.getParameter(“root”);
List<String> suggestions = this.getSuggestions(root);
request.setAttribute(“suggestions”, suggestions);
request.getRequestDispatcher(“/suggestions.jsp”).forward(request, response);
}
private List<String> getSuggestions(String str){
if (str.length() >= listSize){
return Collections.emptyList();
}
int size = listSize – str.length();
List<String> suggestions = new ArrayList<String>();
for (int i = 0; i<size; i++){
StringBuilder sb = new StringBuilder(str);
for (int j = 0; j < size; j++){
char ch = (char) (“a” + gen.nextInt(26));
sb.append(ch);
}
suggestions.add(sb.toString());
}
return suggestions;
}
}


Цей сервлет просто витягує параметр root запиту і викликає метод getSuggestions() для отримання списку підказок. Наведена в лістингу 3 реалізація створює випадковий список рядків підказок. Ця фіктивна реалізація створює менше підказок, при збільшенні довжини параметра root, імітуючи звуження можливостей вибору при продовженні введення даних в полі з автозаповненням. Потім список поміщається в об’єкт request. Сервлет передає управління JSP для візуалізації даних. JSP-сторінка приведена в лістингу 4.


Лістинг 4. suggestions.jsp





<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<%@ page language=”java” contentType=”text/xml; charset=ISO-8859-1″
pageEncoding=”ISO-8859-1″ %>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
<suggestions>
<c:forEach items=”${suggestions}” var=”str”>
<word>${str}</word>
</c:forEach>
</suggestions>

JSP створює XML-документ для передачі назад клієнтові. Це робиться просто шляхом ітерації за списком підказок, створених сервлетов. Тепер давайте розглянемо JavaScript-код на стороні клієнта, обробляє ці дані.


JavaScript-код для обробки відповіді


При виклику сервера з використанням об’єкта XMLHttpRequest реєструється обробник відповіді. Тобто, коли сервер повертає XML-документ, наведений в лістингу 4, Цей JavaScript-обробник активізується. Такого роду асинхронна робота є однією з найбільш типових пасток Ajax-програмування. Давайте розглянемо JavaScript-функцію handleSuggestions, Яка обробляє відповідь сервера (див. лістинг 5).


Лістинг 5. Оброблювач відповіді: JavaScript-функція handleSuggestions





function handleSuggestions() {
if (suggestReq.readyState == 4) {
var ss = document.getElementById(“suggest”)
ss.innerHTML = “”;
var xml = suggestReq.responseXML;
var root = xml.getElementsByTagName(“suggestions”).item(0);
var suggestions = new Array();
var cnt = 0;
for (var i=0; i < root.childNodes.length; i++){
var node = root.childNodes.item(i);
if (node.childNodes.length > 0){
suggestions[cnt++] = node.childNodes.item(0).data;
}
}
for(i=0; i < suggestions.length; i++) {
var val = suggestions[i];
if (val.length > 0){
var suggest = “<div
onmouseover=”javascript:suggestOver(this);” “;
suggest += “onmouseout=”javascript:suggestOut(this);” “;
suggest += “onclick=”javascript:setValue(this.innerHTML);” “;
suggest += “class=”suggest_link”>” + val + “</div>”;
ss.innerHTML += suggest;
}
}
}
}

Ця функція складається з двох основних частин. Спочатку обробляється XML шляхом проходження по документу responseXML та вилучення підказок. Вони зберігаються в масиві suggestions. Потім код динамічно створює список підказок для вибору користувачем і поміщає цей список всередині suggest div, створеного в HTML. На малюнку 1 показано, як виглядає поле з автозаповненням.


Рисунок 1. Автозаповнення з використанням Ajax
Autosugget using Ajax

Є окремий CSS і JavaScript-код для створення “ефекту підказки”. Їх можна знайти в повному вихідному коді. А зараз давайте розглянемо, як XForms спрощує код.


Створення підказок за допомогою XForms і Ajax


Двома ключовими компонентами Ajax є можливість виконання запитів на сервер без зміни переглядається в браузері сторінки, а також можливість отримання XML-даних від сервера. Перша характеристика (Асинхронні запити) – це буква “A” в Ajax. Остання характеристика – це буква “X” в Ajax. Зазвичай використовується об’єкт XMLHttpRequest, Але це безумовно не єдиний спосіб. XForms може виконати ту ж задачу і бути представленим буквами “A” і “X” в Ajax.


Парадигма XForms


XForms відокремлює модель від виду (view) в Web-додатку. Дані поділяються так, щоб їх легше можна було змінювати. Всі дані і дії (запити серверу) є частиною моделі, що притаманне типовим архитектурам Модель Вид Управління (Model View Control – MVC). У нашому додатку з автозаповненням присутні дані запиту (root, переданий на сервер), дані відповіді (підказки від сервера) і дія (HTTP-запит серверу) як частини моделі. Давайте їх розглянемо.


Налаштування XForm: Модель запиту


Дані, які ми збираємося використовувати для запиту на сервер, є першою частиною нашої моделі. Вона досить проста. Необхідний лише параметр root. Погляньте на лістинг 6.


Лістинг 6. Модель XForms: Дані запиту





<xf:instance id=”xfsuggestQuery”>
<query xmlns=””>
<root/>
</query>
</xf:instance>

Це всього лише простий XML-документ для зберігання параметра root, Який ми збираємося передати на сервер. Пізніше ви побачите його зв’язок з видом. А зараз розглянемо, як включити дані відповіді в нашу модель.


Налаштування XForm: Модель відповіді


Дані для відповіді кілька більш складні. Ми збережемо структуру, що використовувалася з Ajax-версією, оскільки вона граматично правильна і повністю сумісна з XForms. Однак на початку роботи програми у нас немає підказок, тому поки необхідно пусте місце для них (див. лістинг 7).


Лістинг 7. Модель XForms: Дані відповіді





<xf:instance id=”xfsuggestResults”>
<suggestions xmlns=””/>
</xf:instance>

Ми повністю замінимо вузол suggestions при отриманні відповіді від сервера. А зараз просто залишимо suggestions порожнім. Це дані, необхідні в нашій моделі, а тепер для моделі потрібно дію.


Налаштування XForm: Дія сервера


Дані є частиною моделі, але дії з цими даними також важливі. В даному випадку дією є HTTP-запит на сервер. У лістингу 8 показано, як легко це можна зробити за допомогою вузла XForms submission.


Лістинг 8. Модель XForms: submission





<xf:submission id=”get_suggest” action=”/xfsuggest/suggest”
method=”get” separator=”&” ref=”instance(“xfsuggestQuery”)”
replace=”instance” instance=”xfsuggestResults”/>

Дією в нашому сайті submission є URL HTTP-запиту, який ми збираємося виконати. Параметр ref вказує submission, що передавати. В даному випадку вказується передача даних з об’єкта xfsuggestQuery. Це наші дані запиту, визначені в лістингу 6. Атрибут method встановлений в get, А роздільник – амперсанд (&). Це вказує XForms, як додавати дані в HTTP-запит. Буде створюватися параметр root, Оскільки це елемент вузла xfsuggestQuery / query, а значення цього параметра буде значенням дочірнього вузла text вузла “root” XML-даних. Якби було декілька параметрів, вони поділялися б за допомогою амперсанда для створення правильно сформованого запиту HTTP GET. Ми визначили модель XForms, а тепер потрібно просто визначити вид.


Вид XForms: Введення даних


Вид в нашій XForm досить простий – це всього лише текстове поле, хоча і не зовсім звичайне, оскільки воно буде мати Ajax-функціональність автозаповнення. Його оголошення приведено в лістингу 9.


Лістинг 9. Вид XForms





<xf:input ref=”instance(“xfsuggestQuery”)/root” incremental=”true” id=”tBox”>
<xf:action ev:event=”xforms-value-changed”>
<xf:send submission=”get_suggest” />
</xf:action>
</xf:input>

Давайте проаналізуємо, що тут відбувається. Спочатку визначається поле input. Воно пов’язується з моделлю за допомогою атрибута ref. Це говорить XForms про те, що при введенні значення в поле input воно також повинно вводитися в вузол “root” XML-документа xfsuggestQuery. Потім визначається дію (action) при введенні. Дана дія викликає “send” для передачі в уявлення (submission), створене в моделі. Все це дуже типово для XForms і повинно бути добре знайоме розробникам, які мали справу з XForms.


Втім, тут використовується також кілька незвичайних можливостей XForms. Поле input має атрибут incremental, Встановлений у значення true, Що активізує подія при будь-якому инкрементной зміні, виконаному в поле input. У порівнянні з типом події onkeyup поля input (див. лістинг 1) Такий підхід більш досконалий. Цей атрибут дозволяє XForms проявляти більшу вибірковість при активізації подій, так як активізація пригнічується при швидкому введенні даних користувачем. Багато Ajax-додатки часто повинні додавати власні механізми придушення для реалізації функціональності, яку в XForms ви отримуєте автоматично.


Певний нами подія має атрибут event, встановлений в значення “xforms-value-changed”. Він вказує, як прослуховувати дію для інкрементний подій, що активізується полем введення. Тепер, коли б ці події ні активізувалися, буде викликатися дію submission, і, отже, виконуватися запит на сервер про отримання підказок для поля. Давайте розглянемо, як серверний код обробляє запит.


Використання Java на стороні сервера


Отже, як змінити сервер для обробки запитів від XForm? Нічого не треба міняти! Ваш сервер уже посилає XML назад Ajax, що відмінно працює і з XForms. Це демонстрація того, як XForms доповнює Ajax. Служби на стороні сервера, використовувані в однієї технології, можуть використовуватися і з іншого. Тепер потрібно просто обробити відповідь сервера на клієнті.


Обробка відповіді


У Ajax-додатку ми використовували JavaScript-функцію для обробки responseXML, отриманого з сервера, а також для зміни HTML DOM з метою відображення підказок. За допомогою XForms можна зробити аналогічні речі (але значно простіше), зв’язавши відповідь безпосередньо з даними. Коли дані передаються на сервер, наш вид оновлює себе автоматично. Тому замість включення порожнього елемента suggest div ми просто додаємо деякі пов’язані дані, як показано в лістингу 10.


Лістинг 10. Відображення результатів з пов’язаними XForm-даними





<div id=”suggest”>
<xf:repeat id=”results” nodeset=”instance(“xfsuggestResults”)/word”>
<div onmouseover=”javascript:suggestOver(this);”
onmouseout=”javascript:suggestOut(this);”
onclick=”javascript:setValue(this.innerHTML);” class=”suggest_link”>
<xf:output ref=”.”/>
</div>
</xf:repeat>
</div>

Тут реалізовано зв’язування вузлів “word” в документі xfsugggestResults. Природно, спочатку немає ніяких слів, але це поки немає відповіді від сервера. Після появи вузлів “word” по ним виконується ітерація для створення div зі словом. Цей div аналогічний елементу div, створюваному динамічно в JavaScript у чистій Ajax-версії. JavaScript-функції suggestOver і suggestOut, На які цей елемент посилається, залишаються незмінними. Єдине, що потрібно поміняти, – це функція setValue. Ця функція необхідна для роботи з XForms-даними замість простої зміни даних поля HTML input. Погляньте на setValue в лістингу 11.


Лістинг 11. Нова функція setValue





function setValue(value) {
var model = document.getElementById(“xfsuggestModel”);
var instance = model.getInstanceDocument(“xfsuggestQuery”);
var queryElement = model.getElementsByTagName(“query”)[0];
var rootElement = queryElement.getElementsByTagName(“root”)[0];
if (rootElement.childNodes.length == 0){
var textNode = document.createTextNode(value);
rootElement.appendChild(textNode);
} else {
rootElement.firstChild.nodeValue = value;
}
model.rebuild();
model.refresh();
document.getElementById(“suggest”).innerHTML = “”;
}

У цій функції ми звертаємося до моделі XForms, добираємося до примірника xfsuggestQuery, А потім йдемо до його елемента root і або додаємо до нього текстовий вузол, або змінюємо його значення, якщо він вже існує. Даний технічний прийом можна використовувати для прямого доступу до даних xfsuggestResults і відображення підказок точно так само, як це робилося раніше. JavaScript і XForms дуже добре працюють спільно.


Резюме


Ви побачили, як можна використовувати XForms для доповнення Ajax. Він використовує багато тих же принципів, що і Ajax, але певною мірою спрощує і оптимізує роботу. Використовуючи XForms, легше передавати і отримувати дані від сервера, а ще в XForms формуються більш “розумні” події. Також спрощується необхідний JavaScript-код, так як надається функціональність “шаблонів”. На закінчення можна сказати, що часто краще довірити саме XForms бути буквами “A” і “X” в Ajax.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*