В статье показывается способ применения jQuery для работы с базой данных Caché, в результате чего реализуется простой функционал по вставке и удалению данных в ajax веб-приложении.
Предполагается, что читатель обладает средним уровнем знаний HTML, CSS и Javasсript и имеет минимальный опыт работы с Intersystems Cache. Загрузить последнюю версию Caché можно здесь. Начальный опыт работы с Caché можно обрести тут.
CSP(Zen) — базовая технология, предлагаемая Caché для быстрого создания ajax веб-приложений, работающих с базой данных Caché.
Чем может помочь jQuery вашему CSP(ZEN)-приложению?
Фреймворк jQuery позволяет получать доступ к элементам c помощью синтаксиса селекторов CSS, реализуя этот функционал наиболее предпочтительным для каждого конкретного браузера способом.
Кроссбраузерность – неотъемлемое требование к современному Web-приложению. Разработчики фреймворка утверждают, что разработанный с помощью jQuery код, будет единообразно функционировать в браузерах — IE 6.0+, FF 3.6+, Safari 5.0+, Opera, Chrome.
jQuery предоставляет удобный способ для расширения своей функциональности с помощью плагинов. С момента создания фреймворка (в 2006 г.) их было написано не мало. Отдельного упоминания заслуживает библиотека клиентского интерфейса jQueryUI.
Скачайте с официального сайта сжатую версию библиотеки, поместите ее в каталог CSP приложения, укажите на csp (zen) странице, что будет использоваться файл jQuery определенной версии.
Например:
CSP
CLS
CSP, ZEN и CLS — три подхода создания серверных страниц в Caché.
Каждая CSP-страница при компиляции превращается стандартный класс Cache — наследник класса %CSP.Page — CSP. Отсюда следуюет второй способ — кодоориентированный, предполагает изначальную разработку страницы с помощью классов Cache, наследников класса %CSP.Page — CLS подход. Подробнее о различиях смотрите здесь.
Третий способ — разработка с использованием Zen объединяет два этих способа — используются как Zen-теги так и объектный код. В приводимых примерах обозначения CSP,CLS,ZEN, обозначают способы разбработки страницы, который использовался при создании примера
Для интернет-приложений предпочтительным способом будет использование сетей доставки контента (CDN – content delivery network). В этом случае файл jQuery будет находиться на серверах одной из перечисленных сетей. Пример подключения с использованием CDN:
Самая используемая функция jQuery так и называется — jQuery(), но чаще используется ее синоним — $(). Результат этой функции будет зависеть от типа и количества переданных аргументов. Основные варианты вызова этой функции:
1. В качестве аргумента передается строка:
Метод будет пытаться трактовать строку или как селектор jQuery (CSS) или как html код:
2. В качестве аргумента передается элемент страницы:
3. В качестве аргумента передается функция:
Переданная функция будет выполнена по событию загрузки документа. Такой вызов можно использовать вместо:
Кроме поиска элементов на странице, jQuery содержит методы для манипуляций с ними. Список часто используемых функций:
*Полный список функций можно посмотреть здесь
Необходимо отметить некоторые правила, реализованные в jQuery:
— результат запроса упаковывается в объект jQuery;
— большинство функций возвращают контекст вызова.
Соблюдение этих правил делает код «ненавязчивым» и позволяет использовать «цепочечный» синтаксис. Пример кода с использованием jQuery, выполняющий поиск элемента и замену его значения:
«Ненавязчивость» заключается в том, что для указанного выше кода, при отсутствии на странице элементов с классом age38, ошибки выполнения не возникает и выполнение кода не прерывается
Ниже показан пример, javascript с аналогичным функционалом, но без jQuery
Получившийся код меньше чем библиотека jQuery, но не такой универсальный и требует больших усилий от разработчика при создании и сопровождении.
Cache + jQuery
Рассмотрим небольшой пример реализации чата с минимальной функциональностью и следующим интерфейсом:

Особенности примера:
— интерфейс полностью формируется с помощью jQuery
— используются асинхронные вызовы сервера #call()#, которые возвращают ответ через вызов функции на клиенте
— данные хранятся в глобале
Исходный код страницы:
Для воспроизведения примера, откройте Студию в любой области, создайте новую CSP-страницу, вставьте скопированный код страницы из примера. Сохраните страницу с любым именем — выберите при этом какое-либо существующее CSP-приложение. Затем откомпилируйте страницу (Ctrl+F7) и откройте ее в браузере ( F5).
Использование jQuery на Zen-странице
Применение jQuery на Zen странице полностью аналогично ипользованию в CSP (поиск и изменение элементов), но с учетом того, что Zen — это клиент-серверный фреймворк, который поддерживает одинаковую объектную модель в браузере и на сервере Cache. Поэтому необходимо учитывать следующие моменты:
— Модель Zen-страницы начинает формироваться после события загрузки страницы.
— Для изменения модели страницы предпочтительно использовать методы Zen
— Zen формирует разметку с помощью дополнительных скрытых элементов
Практический пример Cache + jQuery
Приведем более сложный пример c использованием jQuery для создания и удаления объектов хранимого класса со следующим интерфейсом:
Особенности примера:
— Пример работает на Cache версии 2010 и выше.
— Используется динамическая привязка событий, весь javascript код вынесен в отдельный javascript файл
— Часть содержимого страницы генерируется непосредственно в браузере
— Не используются «гипер»-события и «динамические» (генерируемые на лету) метод-страницы
— Сервер генерирует ответы в различных форматах данных в зависимости от аргументов запроса
— Показан вывод серверного объекта в формате XML с помощью %XML.Writer и разбор ответа сервера в формате XML на стороне клиента с помощью jQuery
1. Создайте в области User хранимый класс с тестовыми данными
2. Создайте тестовые данные в test.data, выполнив из терминала Cache вызов метода класса.
3. Создайте класс-страницу:
/// Страница работы с экземплярами класса test.data
Далее приведен Javascript код, вынесенный в файл wui.testData.js. Файл должен находиться в каталоге csp-приложения. Для области USER каталог находится в [Директория установки Cache]\CSP\USER\.
Некоторые итоги:
Предполагается, что читатель обладает средним уровнем знаний HTML, CSS и Javasсript и имеет минимальный опыт работы с Intersystems Cache. Загрузить последнюю версию Caché можно здесь. Начальный опыт работы с Caché можно обрести тут.
Зачем нужен jQuery в CSP-приложении?
CSP(Zen) — базовая технология, предлагаемая Caché для быстрого создания ajax веб-приложений, работающих с базой данных Caché.
Чем может помочь jQuery вашему CSP(ZEN)-приложению?
1. Удобный доступ к любому элементу html-страницы
Фреймворк jQuery позволяет получать доступ к элементам c помощью синтаксиса селекторов CSS, реализуя этот функционал наиболее предпочтительным для каждого конкретного браузера способом.
2. Кроссбраузерность
Кроссбраузерность – неотъемлемое требование к современному Web-приложению. Разработчики фреймворка утверждают, что разработанный с помощью jQuery код, будет единообразно функционировать в браузерах — IE 6.0+, FF 3.6+, Safari 5.0+, Opera, Chrome.
Плагины
jQuery предоставляет удобный способ для расширения своей функциональности с помощью плагинов. С момента создания фреймворка (в 2006 г.) их было написано не мало. Отдельного упоминания заслуживает библиотека клиентского интерфейса jQueryUI.
Как подключить jQuery к вашей CSP (ZEN) странице?
Скачайте с официального сайта сжатую версию библиотеки, поместите ее в каталог CSP приложения, укажите на csp (zen) странице, что будет использоваться файл jQuery определенной версии.
Например:
CSP
<script type="text/javascript" src="jquery-1.7.1.min.js"></script>
ZEN
Parameter JSINCLUDES As STRING="jquery-1.7.1.min.js"
CLS
w "<script type='text/javascript' src='jquery-1.7.1.min.js'></script>"
CSP, ZEN и CLS — три подхода создания серверных страниц в Caché.
Каждая CSP-страница при компиляции превращается стандартный класс Cache — наследник класса %CSP.Page — CSP. Отсюда следуюет второй способ — кодоориентированный, предполагает изначальную разработку страницы с помощью классов Cache, наследников класса %CSP.Page — CLS подход. Подробнее о различиях смотрите здесь.
Третий способ — разработка с использованием Zen объединяет два этих способа — используются как Zen-теги так и объектный код. В приводимых примерах обозначения CSP,CLS,ZEN, обозначают способы разбработки страницы, который использовался при создании примера
Для интернет-приложений предпочтительным способом будет использование сетей доставки контента (CDN – content delivery network). В этом случае файл jQuery будет находиться на серверах одной из перечисленных сетей. Пример подключения с использованием CDN:
CSP: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> ZEN: Parameter JSINCLUDES As STRING="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"; CLS: &html< <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> >
Использование jQuery
Самая используемая функция jQuery так и называется — jQuery(), но чаще используется ее синоним — $(). Результат этой функции будет зависеть от типа и количества переданных аргументов. Основные варианты вызова этой функции:
1. В качестве аргумента передается строка:
Метод будет пытаться трактовать строку или как селектор jQuery (CSS) или как html код:
$( "div#1973" ) // вернет элементы div с идентификатором 1973 $( ".doc td" ) // вернет элементы <td> дочерние по отношению к элементам с классом doc $( "<div>Write less, do more</div>" ) // создаст* новый элемент
2. В качестве аргумента передается элемент страницы:
$( document.body ) // элемент body будет «упакован» в объект jQuery $( document.forms[0] ) // элемент первая форма страницы будет «упакована» в объект jQuery
3. В качестве аргумента передается функция:
или анонимная функция:function loadHandler() { alert( "Документ загружен" ); } $( loadHandler );
$( function (){ alert( "Документ загружен" ); } );
Переданная функция будет выполнена по событию загрузки документа. Такой вызов можно использовать вместо:
<body onload="loadHandler">
Кроме поиска элементов на странице, jQuery содержит методы для манипуляций с ними. Список часто используемых функций:
html() возвращает или установливает html-содержимое элемента. val() возвращает или устанавливает значение элемента управления (input,select) attr() возвращает или устанавливает значение аттрибута элемента append(), appendTo() добавляет элемент к другому, создает и добавляет элемент к другому remove() удаляет элемент bind(), unbind() Добавление, удаление обработчиков событий. Для основных событий вместо bind() можно использовать синонимы click(), keypress(), hover() и т.д. addClass(), removeClass(), toggleClass() добавляет, удаляет, переключает класс(ы) элемента css() возвращает или устанавливает значения стиля show(), hide() показывает, прячет элемент parents(),parent() children() возвращает родительские или дочерние элементы
*Полный список функций можно посмотреть здесь
Необходимо отметить некоторые правила, реализованные в jQuery:
— результат запроса упаковывается в объект jQuery;
— большинство функций возвращают контекст вызова.
Соблюдение этих правил делает код «ненавязчивым» и позволяет использовать «цепочечный» синтаксис. Пример кода с использованием jQuery, выполняющий поиск элемента и замену его значения:
<script type="text/javascript" src="jquery-1.7.1.min.js"></script> <script type="text/javascript"> $(function(){ $( ".age38" ) // Найти любые элементы с классом age38 .val( "Write less, do more" ) //их значение будет заменено на девиз .css( "font-size", "110%" ) // а также изменен размер шрифта .click( function(){ $(this).val(""); } ) //при клике сбросим значение // Эту «цепочку» из функций можно продолжить дальше. }); </script>
«Ненавязчивость» заключается в том, что для указанного выше кода, при отсутствии на странице элементов с классом age38, ошибки выполнения не возникает и выполнение кода не прерывается
Ниже показан пример, javascript с аналогичным функционалом, но без jQuery
<script type="text/javascript"> //объект в который будем складывать все свои переменные и функции //чтобы не "засорять" пространство имен window var page={}; // window.page=new Object(); // Функция отбора элементов страницы по их классу // вернет массив элементов с таким классом page.getByClass=(document.getElementsByClassName) ? function(clnm){ //В IE9, FireFox 3, Opera 9.5, Safari 3.1 есть специальный метод return document.getElementsByClassName(clnm); } : function(clnm){ ///в IE 6.0-IE 8.0 такого метода нет var arr=[]; /// сюда будем складывать найденные по классу элементы /// Рекурсивный проход по дочерним элементам var scanDown=function(obj,handler){ for (var child=obj.firstChild;child;child=child.nextSibling){ if (typeof(handler)=="function") handler(child); scanDown(child,handler); } }; /// определим регулярное выражение для поиска класса /// так как одному элементу может быть присвоено несколько классов var rgxp=new RegExp("(\\s|^)" + clnm + "(\\s|$)"); /// Обработчик элементов var classSelect=function( obj ){ if ( ( !obj ) || ( !obj.className )) return; var cls=obj.className; if (!cls.match( rgxp )) return; arr[arr.length]=obj; ///нашли - запомнили }; scanDown( document, classSelect ); //запускаем рекурсию return arr; } /// Определим “универсальную” функцию привязки событий page.bind=(page.ie)? function(obj,evt,func){ obj.attachEvent("on"+evt,func); } : function(obj,evt,func){ obj.addEventListener(evt,func); }; /// Основная функция обработки найденных элементов page.main=function(obj){ if (!obj) return; if (obj.nodeType!=1) return; //проверки и еще раз проверки obj.value="Write less, do more"; var FS="110%"; if (obj.style) { obj.style.fontSize=FS; } else { obj.style="font-size:"+FS; } page.bind(obj,"click",function(){ obj.value=""; }); }; /// Запускаем после загрузки page.bind( window, "load", function() { var arr=page.getByClass("age38"); //найдем элементы for (var i in arr){ page.main(arr[i]); //обработаем каждый из них } }); </script>
Получившийся код меньше чем библиотека jQuery, но не такой универсальный и требует больших усилий от разработчика при создании и сопровождении.
Cache + jQuery
Использование jQuery на CSP-странице
Рассмотрим небольшой пример реализации чата с минимальной функциональностью и следующим интерфейсом:

Особенности примера:
— интерфейс полностью формируется с помощью jQuery
— используются асинхронные вызовы сервера #call()#, которые возвращают ответ через вызов функции на клиенте
— данные хранятся в глобале
Исходный код страницы:
<!DOCTYPE html> <html><head><title> jqChaté </title> <style type="text/css">.msg span {padding: 0px 0px 0px 5px}</style> </head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript"> $( function(){ var USERNAME="#($USERNAME)#" //храним в переменной пользователя Cache , box=$( "<div/>" ).css("overflow","auto") //создали окошко, добавили прокрутку .css("border","1px solid #ccc").width( 340 ).height( 280 ) //формат .appendTo( $(document.body) ) //и добавили в документ ; box.parent() //перешли от окошка чата к body //добавляем к body input, который сразу форматируем и подписываем .append( $("<input />").css( "width",200 ) .attr("maxlength",50).before( USERNAME+": ") ) .append( //добавляем кнопку $("<button/>").text( "Send" ) //к ней текст и обработчик .click( function(){ //асинхронно передадим на сервер #call(..Add($(this).prev().val()))#; //значение элемента перед кнопкой (input) $("input").val("").focus(); //textbox очистим, и вернем ему фокус ввода }) ); var drawMsg=function(/*[id,time,user,msg]*/ array ){ //вывод сообщения var USER=2, MSG=3, SOFT="#999", BRIGHT="#339" //константы , msg = $( "<div><span>" + array.join("</span><span>") + "</span></div>") //html сообщения .appendTo( box ).hide() //добавили и спрятали - вдруг служебное сообщение .addClass("msg") //выставили класс .children(":first").hide() //id - скрытое поле .next().css("color", SOFT) //time //подсветка пользователя .next().css("color", (USERNAME==array[USER]) ? SOFT : BRIGHT ).append(": ") .parent() //восстановили контекст и вернули в переменную msg ; if (array[MSG]!=="") { // сообщение не служебное msg.show(); //отображаем var div=msg.get(0); //получаем доступ непосредственно к html-элементу if (div) div.scrollIntoView(); //подкручиваем в область видимости } }; //drawMsg window.chat=function(array){ //главная функция if ( $.isArray(array) ) drawMsg( array ); //есть данные - выводим их //ждем немного и спрашиваем сервер - какое следующее? setTimeout( //Последнее полученное ищем с помощью jQuery function(){ #call(..GetNext($(".msg:last span:first").text()))# } , #($get(^chatSettings("timeout"),300))# ); //настройки тоже на сервере }; //window.chat chat(); //запускаем цикл запрос-ответ }); </script><body></body></html> <script runat="server" method="Add" arguments="msg:%String" language="cache"> #; просто записываем данные s ^chat($increment(^chat))=$listbuild( $zt( $now() ), $USERNAME, msg ) </script> <script runat="server" method="GetNext" arguments="lastMsg:%String" language="cache"> #; разбираемся c переданными аргументами set lastMsg=$get(lastMsg), prevMsg=$order( ^chat(lastMsg),-1 ), isNewUser=( lastMsg = "" ) set callBack="window.parent.chat(" ; set isNewChat=( isNewUser && (prevMsg="") ) if ( isNewChat ) write callBack,")" Quit if ( isNewUser ) write callBack,"[", prevMsg, ",'','',''])" Quit ;инициализация set nextMsg=$order( ^chat( lastMsg ) ) if ( nextMsg="" ) write callBack,")" Quit set stored=$get(^chat(nextMsg)) ;выводим сообщение write callBack,"[",nextMsg,", ", ..QuoteJS( $listget(stored,1) ) , ",", ..QuoteJS( $listget(stored,2) ) , ",", ..QuoteJS( ..EscapeHTML( $listget(stored,3 ))) , "])" </script>
Для воспроизведения примера, откройте Студию в любой области, создайте новую CSP-страницу, вставьте скопированный код страницы из примера. Сохраните страницу с любым именем — выберите при этом какое-либо существующее CSP-приложение. Затем откомпилируйте страницу (Ctrl+F7) и откройте ее в браузере ( F5).
Использование jQuery на Zen-странице
Применение jQuery на Zen странице полностью аналогично ипользованию в CSP (поиск и изменение элементов), но с учетом того, что Zen — это клиент-серверный фреймворк, который поддерживает одинаковую объектную модель в браузере и на сервере Cache. Поэтому необходимо учитывать следующие моменты:
— Модель Zen-страницы начинает формироваться после события загрузки страницы.
— Для изменения модели страницы предпочтительно использовать методы Zen
— Zen формирует разметку с помощью дополнительных скрытых элементов
Практический пример Cache + jQuery
Приведем более сложный пример c использованием jQuery для создания и удаления объектов хранимого класса со следующим интерфейсом:
Особенности примера:
— Пример работает на Cache версии 2010 и выше.
— Используется динамическая привязка событий, весь javascript код вынесен в отдельный javascript файл
— Часть содержимого страницы генерируется непосредственно в браузере
— Не используются «гипер»-события и «динамические» (генерируемые на лету) метод-страницы
— Сервер генерирует ответы в различных форматах данных в зависимости от аргументов запроса
— Показан вывод серверного объекта в формате XML с помощью %XML.Writer и разбор ответа сервера в формате XML на стороне клиента с помощью jQuery
1. Создайте в области User хранимый класс с тестовыми данными
/// Класс с тестовыми данными
Class test.data Extends (%Persistent, %Populate, %XML.Adaptor) {
/// Обозначение
Property code As %String;
/// Наименование
Property name As %String;
/// Переопределенный "конструктор", рассчитанный на прием данных непосредственно со страницы
Method %OnNew(ByRef args as %String="") As %Status [ Private, ServerOnly = 1 ] {
s ..code=$g(args("code",1)), ..name=$g(args("name",1))
Quit $$$OK
}
}2. Создайте тестовые данные в test.data, выполнив из терминала Cache вызов метода класса.
USER>d ##class(test.data).Populate()3. Создайте класс-страницу:
/// Страница работы с экземплярами класса test.data
Class wui.testData Extends %CSP.Page { /// Рекомендуемое значение Parameter CHARSET="utf-8"; /// Переопределим метод вывода страницы ClassMethod OnPage() As %Status { #; Эта страница обрабатывает три типа запросов #; 1.просто вывод данных #; 2.запрос на создание объекта #; 3.запрос на удаление объекта #; Тип запроса различаются по значению аргумента <var>oper</var> m args=%request.Data ;Заберем все данные из запроса if $d(args("oper")){ //если определен аргумент oper s oper=$g(args("oper",1)) //узнаем тип запроса Q:oper="add" ..Add(.args) //перейдем к созданию объекта в методе этого класса Q:oper="del" ..Del(.args) //перейдем к удалению объекта } #; в остальных случаях просто выводим страницу &html<<html><head><title>Класс test.data</title> <!-- Часть оформления вынесем в CSS --> <style type="text/css"> table {border-collapse: collapse; border: 1px solid #777;} td, th {border: 1px solid #777;} td {padding: 2px;} th {font-weight: normal; color:#fff;background-color:#aaa;} </style> </head> <body> <table><caption>Объекты класса test.data</caption> <thead><tr><th>ID</th><th>code</th><th>name</th><th><!--Кнопка--></th></tr></thead> <tbody>> #; Выведем имеющиеся объекты в виде таблицы s sql="Select ID,code,name From test.data" s rs=##class(%SQL.Statement).%ExecDirect(.stm, sql) ; У вас версия Cache > 2009 ? while rs.%Next() { w !,"<tr id='",rs.ID,"'>" , "<th>",rs.ID,"</th>" ;порядковый номер строки , "<td>",rs.code,"</td>" , "<td>",rs.name,"</td>" , "</tr>" } &html<</tbody></table> <!--подключаем jQuery--> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <!—весь клиентский код вынесем в отдельный файл--> <script src="wui.testData.js"></script> </body></html>> Quit $$$OK } ///Добавление объекта на стороне сервера и ответ клиенту в формате XML ClassMethod Add(ByRef args as %String="") as %Status{ #; выполним добавление нового объекта s obj=##class(test.data).%New(.args), sc=obj.%Save() #; выведем результат добавления и сам объект в виде xml s wr=##class(%XML.Writer).%New() ;начнем вывод xml d wr.RootElement("response") ; <response , wr.WriteAttribute("id",obj.%Id()) ; id='' #;новый объект в виде xml d wr.Object(obj) ; ><data><code>123</code><name>Name</name></data> if $$$ISERR(sc) { d wr.Element("error") ;<error> d wr.WriteChars($system.Status.GetOneErrorText(sc)) ;errorText d wr.EndElement() ;</error> } d wr.EndRootElement() ;</response> Q $$$OK } ///Удаление объекта на стороне сервера и ответ в виде обычного текста ClassMethod Del(ByRef args as %String="") as %Status{ s id=$g(args("id",1)), sc=##class(test.data).%DeleteId(id) w $CASE(sc ,1: 1 , : $system.Status.GetOneErrorText(sc) ) Q $$$OK } }
Далее приведен Javascript код, вынесенный в файл wui.testData.js. Файл должен находиться в каталоге csp-приложения. Для области USER каталог находится в [Директория установки Cache]\CSP\USER\.
$(function(){ //обработчик document.ready //Добавим к таблице интерфейс для создания объектов var footer=[ //используется один из вариантов объявления массива "<tfoot><tr>" ,"<th>*</th>" //колонка "порядковый номер" ,"<th><input /></th>" //колонка "код" ,"<th><input /></th>" //колонка "наименование" ,"<th><button> + </button></th>" //кнопка сохранения новой записи ,"</tr></tfoot>" ].join( "" ); //Объединим в строку (оптимизация работы со строкой) //Создадим элемент с таким содержимым $( footer ).appendTo( $( "table" ) ); //И добавим его к таблице //доберемся до только что созданной кнопки добавления записи $( "tfoot button" ).click( callAdd ); //и привяжем к ней обработчик //к каждой tr из tbody (строки с данными test.Data) добавим кнопку удаления $("tbody tr").each( addDelBtn ); //создание кнопок удаления //Функция добавления кнопки удаления к строке с данными function addDelBtn (){ //для каждой строки данных создадим кнопки удаления var $tr=$(this); //упакуем контекст (tr из tbody) в jQuery $( "<th><button class='bDel'></button></th>" ) //создание элемента .appendTo( $tr ) //добавим в конец строки ячейку с кнопкой удаления .children( ".bDel" ) //для дочерних элементов c классом bDel .html( "X" ) //Заменить содержимое кнопки .attr( "title", "Удалить запись" ) // добавить подсказку .css( "color", "#f00" ) //изменить цвет надписи на предупреждающий .click( callDel ) //при клике на кнопку вызываем удаление данных ; }; // Функция удаления данных на клиенте и сервере function callDel(){ //контекст вызова - кнопка удаления var $btnDel=$( this ).hide(); //спрячем кнопку и сохраним ссылку на нее var $row=$button.parents( "tr" ); //ищем родительский элемент tr var id=$row.attr( "id" ); //узнаем код объекта // Отправим запрос на сохранение данных с помощью // функции $.ajax- http://api.jquery.com/jQuery.ajax/ $.ajax({ //ajax options url: window.location //вызов адреса страницы - wui.testData.cls ,data: "oper=del&id="+id //параметры запроса ,dataType: "text" //ожидаем ответ в формате text ,success: function(txt){ //при успешном выполнении запроса if ( txt!="1" ) { //при удалении произошла ошибка $btnDel.show(); //вернем видимость кнопке удаления alert(txt); //покажем ошибку return; } $row.remove(); //удалим строку на клиенте } }); //ajax() }; // Функция создания данных чуть сложнее function callAdd(){ var values = [] // в этот массив соберем значения для новой записи , $inputs = $( "tfoot input" ) //найдем элементы ввода //и для каждого из них .each( function(){ values.push( //в массив значений поместим $( this ).val() //значение input ) } //function ) //each ; //var //проверим, что введены хоть какие-нибудь данные if ( values.join( "" ) == "" ){ alert( "Укажите хотя бы одно значение" ); return; }; //до выполнения операции на сервере прячем интерфейс добавления var $addRow = $( "tfoot tr" ).hide(); // Отправим запрос на сохранение данных с помощью функции // $.ajax- http://api.jquery.com/jQuery.ajax/ $.ajax( { //настройки вызова сервера url: window.location //адрес - wui.testData.cls //,async: true // по умолчанию запрос выполняется асинхронно , type: "POST" // тип запроса - POST или GET , data: { //передаваемые на сервер данные в виде объекта oper: "add" //операция добавления , code: values[0] //значение кода , name: values[1] //значение наименования } , dataType: 'text' //обработаем ответ сервера как строку. //если вызов завершен успешно , success: function( text ){ // ожидаем c сервера текст в XML следующего вида // <response id='newid'> // <data><code>Code</code><name>Name</name></data> // <error>Error Text</error> // </response> // разбираем документ с помощью функции jQuery var xml=$.parseXML(text) , $xml=$( xml ) //оборачиваем его в jQuery , error=$xml .find("error") //ищем node с ошибкой .text() //получаем текстовое значение ; if ( error!=="" ){ //если была alert(error); //вывод ошибки return; } //Разбор ответа на составляющие элементы var id=$xml.find("response").attr("id") , code=$xml.find("code").text() , name=$xml.find("name").text(); var tr=[ //сформируем строку с полученными данными "<tr id='",id,"'>" , "<th>",id,"</th>" , "<td>",code,"</td>" , "<td>",name,"</td>" ,"</tr>" ].join( "" ); $( tr ) .appendTo( $("table tbody") ) //добавим строку в таблицу //для новой строки вызовем функцию добавим кнопку удаления .each( addDelBtn ) ; $inputs.val( "" ) //очистим элементы ввода .focus() //установим фокус ; } //success , error: function(err){ //если вызов завершен с ошибкой alert("Error: "+err); } //обработчик события, возникающего после success и error , complete: function(){ $addRow.show(); //покажем строку добавления объекта } } //настройки ); //$.ajax }; //callAdd }); //document.ready
Некоторые итоги:
- Использование библиотеки jQuery значительно упрощает разработку web-интерфейса;
- jQuery позволяет удобно разделить динамическое и статическое содержимое страницы;
- в jQuery несложно вынести большую часть логики интерфейса на сторону браузера, тем самым снизив нагрузку на сервер Caché.

