Особое программирование

Программирование и железки

  • Главная
  • О блоге

25

May

Галерея LightBox и ее клоны

Опубликовал admin  Рубрика JavaScript, Программирование, Языки

Почему решил написать этот обзор? Во-первых, предыдущая статья про LightBox безнадежно устарела. Во-вторых, мне LightBox нравится. Правда было время, когда разработчики плагина убирали оттуда поддержку ie6, но потом, видимо одумавшись, вернули ее. В общем, всем хорош плагин LightBox, но вот заточен он только под фото. А если приперло вывести видео с YouTube или вообще какой-нибудь контент в iframe? Да, да, знаю, есть галерея FancyBox, сам пользуюсь, но LightBox все равно больше нравится. Поэтому и было решено покопаться среди многочисленных клонов галереи LightBox.

Галерея LightBox

Начинаем, так сказать, с первоисточника и сразу же смотрим демо, замечая при этом нюансы, чтобы потом сравнить с другими галереями.

Ясно, что для использования плагина нужно подключить к веб-странице файл библиотеки jquery-1.3.2.js, файл плагина jquery.lightbox.js и файл стилевого оформления плагина jquery.lightbox.css. Не забудьте, что в папке images полученного архива, хранятся изображения элементов управления, необходимые для работы плагина.

<link type="text/css" href="js/jquery.lightbox.css" rel="stylesheet" />
<script src="js/jquery-1.3.2.js" type="text/javascript"></script>
<script src="js/jquery.lightbox.js" type="text/javascript"></script>

Теперь о том, как собственно организовать галерею. Естественно понадобятся изображения из которых будет состоять галерея – миниатюры и соответствующие им полноразмерные изображения. Общая конструкция такая:

<a rel="lightbox" href="images/large.jpg" title="Какой-то текст">
<img src="images/small.jpg" />
</a>

Картинка-миниатюра заключена в тэг а, атрибут href которого указывает на соответствующее полноразмерное изображение. В атрибуте rel содержится ключевое слово – lightbox. Такого кода достаточно, чтобы при клике по миниатюре в отдельном слое открылось большое (именно большое, потому что по умолчанию оно масштабируется, если не помещается в области просмотра) изображение. Текст, содержащийся в атрибуте title тэга a станет комментарием к открывшемуся изображению.

В рассмотренном примере функциональность плагина применена к отдельному изображению, а нам нужно сделать тоже самое для группы. Смотрим следующую разметку:

<a rel="lightbox-tour" href="images/large.jpg" title="Какой-то текст">
<img src="images/small.jpg" />
</a>

К ключевому слову lightbox просто добавили произвольный суффикс, в данном случае -tour. Добавляйте какое-то количество таких конструкций в свой код, назначайте им одинаковый суффикс и плагин автоматически объединит изображения в группы. Естественно, в этом случае, кроме комментариев, которые также будут создаваться из содержимого атрибута title, появятся элементы управления для перемещения по галерее.

Если по каким-то причинам Вам нежелательно использовать атрибут rel, можно обойтись и без него. Создать галерею можно используя простой jQuery-код.

$(function(){
  $('a.gallery').lightbox();
});

Если этот код использовать с приведенной ниже разметкой, то все элементы а, имеющие класс gallery, получат функциональность плагина, и атрибут rel тут не потребуется.

<a class="gallery" href="images/large.jpg" title="Какой-то текст">
<img src="images/small.jpg" />
</a>

Плагин LightBox имеет некоторое количество пользовательских настроек, с помощью которых можно переопределить поведение по умолчанию. Обычно jQuery-плагины принимают такие настройки в виде объекта, передаваемого методу в качестве аргумента. Здесь дело обстоит несколько иначе – для настройки вызывается отдельный метод. Ниже приведен пример кода, который создаст галерею из изображений, заключенных в тэг а с классом gallery и передаст плагину некоторые настройки.

$(function(){
  $("a.gallery").lightbox();
  $.Lightbox.construct({
    text: {
      image: "Фото",
      of: "из"
    },
    download_link: false,
    opacity: 0.5,
    show_linkback: false
  });
});

Кстати, помимо использования $.Lightbox.construct(); есть другая возможность передать настройки – в строке запроса. Примерно так:

<script src="js/jquery.lightbox.js?show_linkback=false&amp;text.image=Фото&amp;text.of=из" type="text/javascript"></script>

ПРИМЕЧАНИЕ: В плагине подразумевается поддержка IE6 и она включена по умолчанию. Для IE6 передача параметров возможна только в строке запроса (остальные браузеры тоже понимают такой способ). Если попытаться использовать $.Lightbox.construct(); то в IE плагин перестает работать. По крайней мере у меня не получилось.

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

show_linkback – по умолчанию true, показывает ссылку на страницу плагина на сайте plugins.jquery.com в правом верхнем углу. Передаем false, чтобы скрыть ссылку.
show_helper_text – по умолчанию true, показывает текст (Click to close) в правом верхнем углу и всплывающую подсказку (Hover to interact) при наведении указателя мыши на этот текст. Используем false, чтобы убрать текст (и подсказку естественно тоже).
show_info – по умолчанию ‘auto’, показывает информацию (текст, содержащийся в атрибуте title) под открывшимся изображением только в том случае, если указатель мыши находится над изображением. Чтобы показывать эту информацию независимо от положения указателя мыши используем значение true.
show_extended_info – по умолчанию ‘auto’, показывает дополнительную информацию (Image 1 of nn) при указатель мыши прошел над область, где показывается основная информация (текст, содержащийся в атрибуте title). Чтобы показывать эту информацию независимо от положения указателя мыши используем значение true.
download_link – по умолчанию true, предоставляет возможность открыть полноразмерное изображение в новом окне (вкладке) браузера, воспользовавшись ссылкой, которой является текст комментария к изображению (текст, содержащийся в атрибуте title). Чтобы запретить использование этой возможности, надо передать false.
auto_resize – по умолчанию true, автоматически изменяет размеры картинки, если она слишком большая и не вписывается в область просмотра. Необходимо передать false, чтобы отменить это поведение.
ie6_support – по умолчанию true, включена поддержка IE6. Чтобы отключить ее, надо передать false.
ie6_upgrade – по умолчанию true, показывает сообщение, призывающее пользователей IE6 проапгрейдить свое ПО (у меня почему-то не сработало).
speed – число, определяющее количество миллисекунд, которые отводятся на переход между двумя изображениями. По умолчанию установлено 400.
baseurl – по умолчанию null, но можно указать url для автоматического подключения файлов, которые использует скрипт (стили, картинки).
files – объект, в свойствах которого можно передать местоположение требуемых файлов (используется, если названия файлов менялись). Можно использовать следующие свойства: js.lightbox, js.colorBlend, css.lightbox, images.prev, images.next, images.blank, images.loading.
text – объект, в свойствах которого можно передать текст частей интерфейса. Используется для перевода на нужный язык. Можно использовать следующие свойства: image, of, close, closeInfo, download, help.close, help.interact, about.text, about.title, about.link.
keys – объект, в свойствах которого можно определить «горячие клавиши» для перемещения по галерее вперед и назад, а также для закрытия галереи. Используются свойства close, prev, next.
opacity – прозрачность слоя, который появляется при просмотре галереи между большими изображениями и основным содержимым страницы. Значение может изменяться от 0 до 1. По умолчанию используется значение 0.9.
padding – по умолчанию null, но можно указать число, которое будет определять отступы вокруг просматриваемого изображения.
rel – по умолчанию ‘lightbox’, определяет значение в атрибуте rel тега а (см. пример html-разметки), исходя из которого плагин автоматически формирует галереи. Можно передать строку, в которой определить любое удобное значение.
auto_relify – по умолчанию true, плагин должен автоматически искать и формировать галереи. Чтобы отменить такое поведение следует передать значение false.

Выводы: Плюсы – неплохое оформление, большинство опций действительно полезны. Минусы – сложности с настройкой плагина с учетом поддержки IE6, не все опции удается использовать так, как заявлено разработчиком, не работает ни с каким другим контентом, кроме фото. Имхо, минусов больше, причем перечислены еще не все.

Галерея NFLightBox

По сравнению с обычным LightBox не имеет таких заморочек с настройкой под все основные браузеры, но точно также работает только с фото. Однако имеет возможность автоматической смены изображений – слайдшоу.

Смотрим демо, замечаем отличия от LightBox…

Подключается просто:

<link type="text/css" href="css/nf.lightbox.css" rel="stylesheet" />
<script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="js/NFLightBox.js" type="text/javascript"></script>

В разделе HEAD надо указать пути к файлу стилевого оформления, файлу библиотеки jQuery и файлу плагина. Требования к разметке точно такие же, как и у LightBox.

<a href="images/large.jpg" title="Какой-то текст">
<img src="images/small.jpg" />
</a>

Создается галерея с помощью следующего jQuery-кода:

$('a').lightBox({
  overlayBgColor: '#363',
  txtImage: 'Фото',
  txtOf: 'из',
  txtPrev: ' Назад',
  txtNext: ' Вперед',
  keyToClose: 'q',
  keyToPrev: 'z',
  keyToNext: 'c'
});

Этот плагин тоже имеет приличное количество настроек. Использование некоторых показано в приведенном выше коде. Довольно полезная опция overlayBgColor – позволяет менять цвет промежуточного слоя между просматриваемым изображением и содержимым веб-страницы. В LightBox для этого пришлось бы править css-файл.

Чуть подробнее про опции, которые можно использовать для настройки.

overlayBgColor – по умолчанию #000 (черный), используется для задания цвета промежуточного слоя.
overlayOpacity – по умолчанию 0.8, задает прозрачность промежуточного слоя. Можно использовать значения от 0 до 1.
imageLoading, imageBtnPrev, imageBtnNext, imageBtnClose, imageBlank, imageBtnBottomPrev, imageBtnBottomNext, imageBtnPlay, imageBtnStop – во всех этих опциях можно передать строку, содержащую путь к файлу изображения соответствующего элемента управления.
containerBorderSize – по умолчанию 10, определяет ширину рамки вокруг просматриваемого изображения.
containerResizeSpeed – по умолчанию 500, время в миллисекундах, за которое будет изменяться размеры области просмотра изображения при переходе от одного изображения к другому.
txtImage, txtOf, txtPrev, txtNext – вполне понятные опции. Например задав значения txtImage: ‘Фото’ и txtOf:’из’ Вы уже будете видеть не Image 1 of 8, а Фото 1 из 8.
keyToClose, keyToPrev, keyToNext – с помощью этих опций можно задать «горячие» клавиши. Например keyToClose:’q’ – при нажатии клавиши ‘q’ просмотр будет прекращен.
slideShowTimer – по умолчанию 5000, т.е.если Вы запустите слайдшоу, то изображения будут меняться каждые 5 секунд.

Выводы: Плюсы – неплохое оформление, большинство опций действительно полезны, есть автоматическая смена фото при просмотре, нет сложностей с настройкой. Минусы – png-файлы для элементов управления не очень здорово выглядят в IE6 (и к сожалению jquery.pngfix.js тут не поможет), не работает ни с каким другим контентом, кроме фото. Имхо, лучше, чем стандартный LightBox, но все же не то, что хочется.

Галерея PrettyPhoto

Так и хочется написать – PrettyPhoto мой выбор! Во-первых, этот плагин позволяет работать не только с фото. В области просмотра можно выводить видео с YouTube, ролики в формате .mov (Apple QuickTime), содержимое во flash-формате и наконец вообще любой контент через iframe. Во-вторых, этот плагин имеет свой API, чего нет в рассмотренных ранее плагинах.
Смотрим демо, отмечаем отличия от других галерей и начинаем разговор про PrettyPhoto.

Сначала необходимо подключить к веб-страницы файл библиотеки jquery-1.3.2.js, файл плагина jquery.prettyPhoto.js и файл стилевого оформления плагина prettyPhoto.css.

<link type="text/css" href="css/prettyPhoto.css" rel="stylesheet" />
<script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="js/jquery.prettyPhoto.js" type="text/javascript"></script>

Организация галереи (или галерей) почти не отличается от того, как это делается в LightBox.

<a rel="prettyPhoto

[gallery_1]

" href="max/1.jpg" title="Фото номер 1">
<img src="min/1.jpg" alt="Фото номер 1" />
</a>

Картинка-миниатюра заключена в тэг а, атрибут href которого указывает на соответствующее полноразмерное изображение. В атрибуте rel содержится ключевое слово – prettyPhoto. Чтобы создать несколько различных галерей на обной веб-странице, в атрибуте rel следует указать например – prettyPhoto[gallery_easy]

для условной первой галереи, prettyPhoto[other_gallery] – для другой и так далее…

С помощью jQuery-кода создаем галерею. Используем настройки, установленные по умолчанию.

$(function(){
  $("a[rel^='prettyPhoto']").prettyPhoto();
});

Опции, которые можно использовать для настройки prettyPhoto:
animationSpeed – по умолчанию ‘normal’. Другие возможные значения – ‘fast’ и ’slow’. Скорость анимации изменения размеров окна просмотра при переходе от одного изображения к другому.
padding – по умолчанию 40. Число, опредяляющее отступы вокруг изображения.
opacity – по умолчанию 0.80, прозрачность промежуточного слоя. Изменяется от 0 до 1.
showTitle – по умолчанию true. Заголовок (содержимое атрибута title тэга а), который отображается в левом верхнем углу над областью просмотра. Чтобы отключить надо использовать значение false.
allowresize – по умолчанию true. По умолчанию полноразмерное изображение масштабируется, если ему не хватает места для отображения в полном размере. Можно отменить это поведение, передав false.
counter_separator_label – по умолчанию ‘/’. Разделитель в счетчика изображений галереи.
theme – по умолчанию ‘light_rounded’. Да! Плагин поддерживает несколько тем оформления. Кроме light_rounded возможны также dark_rounded, light_square, dark_square. Вот только для IE6 принудительно используется тема light_square (светлый фон и нескругленные углы).
hideflash – по умолчанию false. Скрывает все flash-объекты на странице при просмотре галереи, чтобы они не отображались поверх. Если этого не требуется, можно установить значение true.
modal – по умолчанию false. Если установить true, будет использоваться модальный режим, т.е. завершить просмотр галереи можно будет только нажатием на картинку ‘close’.

Еще две полезные опции, в которых можно определить callback-функции, вызываемые при наступлении определенного события.
changepicturecallback – функция, определенная в этой опции, будет вызываться каждый раз при смене изображения галереи.
callback – функция, определенная в этой опции, будет вызываться при завершении просмотра.

Плюс ко всем этим полезным опциям, плагин предоставляет четыре метода.

$.prettyPhoto.open(‘path/to/image’,’Title’,’Description’) – метод позволяет открыть нужную галерею. Пример будет чуть позже.
$.prettyPhoto.changePage(‘next’) – с помощью этого метода можно осуществить переход к следующему изображению галереи.
$.prettyPhoto.changePage(‘previous’) – с помощью этого метода можно осуществить переход к предыдущему изображению галереи.
$.prettyPhoto.close() – с помощью этого метода можно закрыть галерею.

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

В общем эта галерея может удовлетворить наверное все потребности веб-мастеров. Кроме одной – слайд-шоу. Чтобы не было обидно, давайте попробуем немного доработать предыдущий пример. Мы дополнительно подключим плагин jquery.timers.js и воспользуемся тем фактом, что в опциях changepicturecallback и callback можно определить функции. В html-разметке добавим select, откуда можно будет выбирать значения задержки при смене изображений. Что из этого получилось, смотрите демо, там же можно посмотреть и исходный код.

В опции changepicturecallback, пользуясь возможностями плагина jQuery Timers, при смене изображений каждый раз запускаем одноразовый таймер со значением, полученным из выбранной опции в селекте. По срабатыванию таймера вызываем метод $.prettyPhoto.changePage(‘next’) заставляя плагин показывать следующее изображение. В опции callback определяем функцию, которая останавливает таймер, если галерея была закрыта и заодно, с помощью alert благодарим за просмотр.

На самом деле такое решение небезгрешно, но зато сделано «на колене в 5 секунд», поэтому кто имеет желание, может в комментариях предлагать свои идеи по этому поводу.

Все примеры, использованные в этой статье, лежат в этом архиве.

Для тех, кто хочет самостоятельно изучить первоисточники, пожалуйста, ссылки: LightBox, NFLightBox, PrettyPhoto.

Выводы: для себя выбрал именно PrettyPhoto…. по крайней мере пока не появилось что-нибудь еще лучше.

Источник: http://www.linkexchanger.su/2009/112.html

Нет комментариев

25

May

jqGrid Часть 2 – Базовые возможности

Опубликовал admin  Рубрика JavaScript, Программирование, Языки

Итак в предыдущей статье (jqGrid Часть I:Знакомство) мы с вами подготовили платформу для опытов и выполнили «пробный запуск» плагина, с самыми «базовейшими» параметрами. Согласно которым таблица запрашивает данные с сервера в XML разметке, при этом у нас есть возможность сортировать данные в столбцах.

В данной статье мы продолжим эксперименты и прощупаем еще ряд замечательных возможностей jqGrid, вот план действий:
читать далее "jqGrid Часть 2 – Базовые возможности"

Нет комментариев

25

May

jqGrid Часть III: Расширенные возможности

Опубликовал admin  Рубрика JavaScript, Программирование, Языки

Введение
Я рад приветствовать вас, дорогие читатели в третьей статье цикла, посвященного плагину jqGrid. Прошу прощения за столь долгое отсутствие, сейчас все свободное время отдаю изучению и освоению другого монстра – ExtJS.
Напомню, что в предыдущей статье (jqGrid Часть II: Базовые возможности) мы перешли от basic к advanced уровню использования этого замечательного плагина. Но прежде чем мы начнем я хотел бы сообщить, что jqGrid обновилась до версии 3.6.5 и соответственно и мы будем использовать новую версию.

Итак план работ на эту статью:

  • jqGrid и «деревья»
    • Общие сведения о деревьях
    • jqGrid и SQL деревья
    • jqGrid и статические деревья
  • Связывание данных в jqGrid
    • Простая подтаблица (subgrid)
    • jqGrid как subgrid
    • Ведущая и ведомая jqGrid


I.jqGrid и «деревья»

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

Древовидная структура является одним из способов представления иерархической структуры в графическом виде. Древовидной структурой называется благодаря тому, что граф выглядит как перевернутое дерево. По этой же причине говорят, что корневой узел (корень) находится на самом верху, а листья — внизу.

В принципе более или менее сносное определение, несмотря на то, что оно навивает академическую скуку я все же настоятельно рекомендую ознакомиться с материалом по древовидным структурам. Поверьте моему не большому опыту, абсолютно каждый программист рано или поздно станет перед необходимостью использовать дерево, и тут одним из помошников может стать jqGrid. Плагин может работать с двумя самыми распространенными в вычислительной технике типами деревьев: на основе «вложенных множеств» (Nested Sets) и «матрицы смежностей» (adjacency matrix). Вообще говоря тема деревьев очень серьезна, это один из разделов теории графов на изучение которых отводится не одна лекция в ВУЗах, но от себя посоветую те материалы которые мне в свое время очень помогли. Столкнувшись впервые с проблемой хранения деревьев я наткнулся на материал по подходу вложенных множеств (Хранение древовидных структур в Базах данных) и сразу же остановился на нем, наверное потому что для работы с таким деревом существует готовый PHP класс. Но в процессе написания статьи я все же прочел статью Работа с «MySQL. Деревья» в которой рассматривается подход матрицы смежностей.

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

2) jqGrid и SQL деревья
Для того, чтобы jqGrid могла работать с древовидными структурами, она должна быть загружена с модулем Tree Grid. Плагин может работать с обоими типами деревьев, упомянутых в предыдущем пункте. При этом jqGrid может работать с деревьями подгрузив все дерево за один раз или же подгружая ветви и листья по мере необходимости. Собственно загрузку дерева за один раз я рассматривать не буду, не интересно, а вот автоподгрузку мы разберем детально. И на этой ноте давайте перейдем к просмотру ДЕМО3.1, ссылка для скачивания

$(function(){
     $('#table_nested').jqGrid({
                     treeGrid: true,
                     treeGridModel: 'nested',
                     ExpandColumn: 'title',
                     ExpandColClick: true,
                     url: 'p3e1_n.php',
                     datatype: "json",
                     mtype: "POST",
                     colNames:["id","Раздел"],
                     colModel:[
                                   {name:'cid',index:'cid', width:1, hidden:true, key:true},
                                   {name:'title',index:'title', width:180}
                                  ],
                     treeIcons: {plus:'ui-icon-folder-collapsed',minus:'ui-icon-folder-open',leaf:'ui-icon-document'},
                     height: 'auto',
                     caption: 'вложенныe множества',
                     hidegrid: false
     });

     $('#table_adjacency').jqGrid({
                     treeGrid: true,
                     treeGridModel: 'adjacency',
                     ExpandColumn: 'title',
                     ExpandColClick: true,
                     url: 'p3e1_a.php',
                     datatype: "json",
                     mtype: "POST",
                     colNames:["cid","Раздел"],
                     colModel:[
                                   {name:'cid',index:'cid', width:1, hidden:true, key:true},
                                   {name:'title',index:'title', width:180}
                                   ],
                     treeIcons: {plus:'ui-icon-circle-plus',minus:'ui-icon-circle-minus',leaf:'ui-icon-person'},
                     height: 'auto',
                     caption:'матрица смежностей',
                     hidegrid: false
    });
});

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

  • treeGrid: true – самый главный параметр, указывает что jqGrig будет работать с древовидной структурой, а не с простыми табличными данными
  • treeGridModel: ‘adjacency’ / ‘nested’ – это свойство определяет какой алгоритм дерева использовать
  • ExpandColumn: ‘title’ – определяет при клике по какому столбцу происходит открытие и(или) загрузка ветви
  • ExpandColClick: true – необходимо, чтобы открытие ветви происходило при клике на колонку, а не на иконку
  • colModel:[... key:true},...] – свойство key в массиве colModel позволяет указать данные какого столбца следует использовать как уникальный идентификатор записи при запросе данных с сервера. Т.е. благодаря этому свойству, можно переопределить идентификатор. Но только в одном столбце может быть указан key. Плагин будет использовать первый, найденный столбец как ключевой.
  • treeIcons: – позволяет переопределить стандартные ({plus:’ui-icon-triangle-1-e’,minus:’ui-icon-triangle-1-s’,leaf:’ui-icon-radio-off’}) иконки листьев и ветвей.

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

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

В режиме ‘nested’ (на примере метода POST)

  • POST['nodeid'] – идентификатор узла (ветви)
  • POST['n_left'] – позиция узла «слева»
  • POST['n_right'] – позиция узла «справа»
  • POST['n_level'] – уровень вложенности узла

В режиме ‘adjacency’ (на примере метода POST)

  • POST['nodeid'] – идентификатор узла (ветви)
  • POST['parentid'] – идентификатор родительского узла
  • POST['n_level'] – уровень вложенности узла

кроме этого, на сервер также передаются стандартные для jqGrid параметры (на примере метода POST)

  • POST['page'] – номер страницы, для «листалки»
  • POST['rows'] – количество записей, для ограничения при выборке данных
  • POST['sidx'] – значение index: в colModel, имя столбца по которому необходимо отсортировать результат
  • POST['sord'] – направление сортировки
  • После получения данных, серверный скрипт выполняет запрос данных из БД и сроит и выводит результат в следующих форматах.

    В режиме ‘nested’ (на примере XML ответа)

    • пользовательские столбцы
    • level – уровень узла в иерархии
    • lft – позиция узла «слева»
    • rgt – позиция узла «справа»
    • isLeaf – логический признак (true/false), определяет этот узел является «веткой»(есть подузлы) или «листом»(нет подузлов)
    • expanded – логический признак (true/false), нужно ли показывать подузлы если этот узел является веткой, т.е. загрузить «открытым» или «закрытым»

    В режиме ‘adjacency’ (на примере XML ответа)

    • пользовательские столбцы
    • level – уровень узла в иерархии
    • parent – идентификатор родительского узла
    • isLeaf – логический признак (true/false), определяет этот узел является «веткой»(есть подузлы) или «листом»(нет подузлов)
    • expanded – логический признак (true/false), нужно ли показывать подузлы если этот узел является веткой, т.е. загрузить «открытым» или «закрытым»

    Ядро (ридеры) jqGrid разбирают ответ и вставляют данные в таблицу. Вот теперь серверные скрипты будут более-менее понятны.

    Вложенные множества (p3e1_n.php)(опущены подключение к БД и вывод результата)

    // Получаем параметры от таблицы
        # ВНИМАНИЕ!!!
        # Данный код не имеет проверок запрашиваемых данных
        # что может стать причиной взлома! Обязательно проверяйте все данные
        # поступающие от клиента
    
        $node  = intval($_POST['nodeid']);
        $left  = intval($_POST['n_left']);
        $right = intval($_POST['n_right']);
        $level = intval($_POST['n_level']);
    
    // Настраиваем условие для выбора ветки
        $WHERE = '';
        if($node > 0) {
           $level = $level + 1;  // нужно выбрать следующий уровень
           $WHERE = " AND cleft > ".$left." AND cright < ".$right." AND clevel = ".$level;
        }else{
           $level = 0;
        }
    
    // Выбираем подразделы
        $query = "SELECT cid, title, clevel, cleft, cright FROM tree_nested_sets WHERE cleft BETWEEN cleft AND cright ".$WHERE." GROUP BY title ORDER BY cleft;";
        $result = mysql_query($query);
    
    // Формируем результат
        $response->page = 1;
        $response->total = 1;
        $response->records = 1;
    
        $i = 0;
        while($row = mysql_fetch_assoc($result)) {
            //-------------------------------------
            // Определяем является ли выбранный узел "листом"
            if($row['cright'] == $row['cleft']+1)
                $leaf = 'true';
            else
                $leaf='false';
            //-------------------------------------
    
            if($level == $row['clevel']){
                $response->rows[$i]['cell'] = array($row['cid'], $row['title'], $row['clevel'], $row['cleft'], $row['cright'], $leaf, 'false');
            }
            $i++;
        }
    

    Матрица смежностей(p3e1_a.php)(опущены подключение к БД и вывод результата)

    // Выбираем все разделы без подразделов (листья)
        $query_feafs = "SELECT t1.cid FROM tree_adjacency_matrix AS t1 LEFT JOIN tree_adjacency_matrix AS t2 ON t1.cid = t2.id_parent WHERE t2.cid IS NULL";
        $sql_leafs = mysql_query($query_feafs);
    
        while($row = mysql_fetch_assoc($sql_leafs)) {
           $leafs[] = $row['cid']; // Массив для хранения "листьев"
        }
        unset($row);
    
    // Получаем параметры от таблицы
        # ВНИМАНИЕ!!!
        # Данный код не имеет проверок запрашиваемых данных
        # что может стать причиной взлома! Обязательно проверяйте все данные
        # поступающие от клиента
    
        $level  = intval($_POST['n_level']);
        $node   = intval($_POST['nodeid']);
    
    // Настраиваем условие для выбора ветки
        if($node > 0) {
           $level = $level + 1;            // нужно выбрать следующий уровень
           $WHERE = 'id_parent ='.$node;
        } else {
           $WHERE = 'id_parent IS NULL';   // выбрать корень(ни)
        } 
    
    // Выбираем подразделы
        $query  = "SELECT cid, title, id_parent FROM tree_adjacency_matrix WHERE ".$WHERE;
        $result = mysql_query($query);
    
    // Формируем результат
        $response->page      = 1;
        $response->total     = 1;
        $response->records   = 1;
    
        $i = 0;
        while($row = mysql_fetch_assoc($result)) {
           //-------------------------------------
           // Определяем ID родителя этого узла
           if(!$row['id_parent'])
               $parent = 'NULL';
           else
              $parent = $row['id_parent'];
           //-------------------------------------
           // Определяем является ли выбранный узел "листом"
           if(in_array($row['cid'], $leafs))
               $is_leaf = 'true';
           else
               $is_leaf = 'false';
           //--------------------------------------
    
           $response->rows[$i]['cell'] = array($row['cid'], $row['title'], $level, $parent, $is_leaf, FALSE);
    
           $i++;
        }

    Я считаю комментировать в этих листингах особо нечего, кроме того что данные поступающие с сервера не ограничиваются по кол-ву записей и не сортируются. А практически все остальное является повторением примеров из предыдущих статей или специфическими вещами при работе с деревьями, описанными в статьях приложенных выше. Также обращу ваше внимание на то, что пример работы с Nested Set Model описанный в документации разработчиком не хотел работать, пришлось его доводить, за что мне большое спасибо :) .

    3)jqGrid и статические деревья
    Название статические деревья оносительно, того что мы делали немного ранее. Безусловно данные «загруженные» таким способом могут быть построены и скриптом динамически, но все же бывают такие задачи, когда дерево уже есть необходимо лишь вывести его в дружественной для пользователя форме как в ДЕМО3.2 . Не правда ли что-то напоминает? Да! это меню из демо jqGrid от разработчика.

    Листинг клиентской части:

      $('#table').jqGrid({
                url: "tree.xml",
                datatype: "xml",
                height: "auto",
                pager: false,
                loadui: "disable",
                colNames: ["id","Items","url"],
                colModel: [
                    {name: "id",width:1,hidden:true, key:true},
                    {name: "menu", width:150, resizable: false, sortable:false},
                    {name: "url",width:1,hidden:true}
                ],
                treeGrid: true,
                        caption: "jqGrid Demos",
                ExpandColumn: "menu",
                width: 200,
                rowNum: 200,
                ExpandColClick: true,
                treeIcons: {leaf:'ui-icon-document-b'}
     });
    

    Полностью идентичные параметры плагина, за исключением того, что я отключил обработчик события onSelectRow.
    Из листига должно стать понятно, что таблица запрашивает статичный(оносительно) файл tree.xml, который выглядит так

    <?xml version='1.0' encoding="utf-8"?>
    <rows>
        <page>1</page>
        <total>1</total>
        <records>1</records>
        <row><cell>1</cell><cell>Loading Data</cell><cell></cell><cell>0</cell><cell>1</cell><cell>10</cell><cell>false</cell><cell>false</cell></row>
        <row><cell>2</cell><cell>XML Data</cell><cell>xmlex.html</cell><cell>1</cell><cell>2</cell><cell>3</cell><cell>true</cell><cell>true</cell></row>
        <row><cell>3</cell><cell>JSON Data</cell><cell>jsonex.html</cell><cell>1</cell><cell>4</cell><cell>5</cell><cell>true</cell><cell>true</cell></row>
    
    ...
    
    </rows>
    

    Т.е. jqGrid просто разбирает данные из этого файла и строит TreeGrid.

    II. Связывание данных в jqGrid

    Иногда при построении какого либо приложения необходимо как то сгруппировать данные для экономии визуального пространства на странице и при этом иметь возможность как можно быстрее и комфортнее получить доступ к более детальной информации или связанной с текущей. Немного сумбурно получилось :) , но надеюсь вы меня поняли, а если не поняли то примеры разложат все по полочкам.

    1)Простая подтаблица (subgrid)

    Это весьма полезная опция у этого плагина. На ДЕМО3.3 обратите внимание на крестик в крайнем правом столбце таблицы. При клике на нем под выбранной строкой распахивается «карман» в котором находится небольшая табличка с названиями городов и прочей «рыбой». Вот пример группировки. Теперь давайте перейдем к листингам.

    $('#table').jqGrid({
           url:'p3e3.php',
           datatype: 'json',
           mtype: 'POST',
           colNames:['Код страны','Cтрана',''],
           colModel :[
              {name:'country_code', index:'country_code', width:80, hidden: true},
              {name:'country_name', index:'country_name', width:60},
              {name:'description', width:200, sortable: false}
              ],
           pager: $('#tablePager'),
           rowNum: 100,
           scroll: true,
           viewrecords: true,
           sortname: 'country_name',
           sortorder: 'asc',
           width: 700,
           height: 400,
           subGrid: true,
             subGridUrl: 'p3e3.php?get=subgrid',
             subGridModel:[{
                         name :  ['&nbsp;','Город', 'Широта', 'Долгота'],
                         width:  [40, 200, 150, 150],
                         align:  ['center','left','right','right'],
                         params: ['country_code','country_name']
                     }]
    });
    

    Как видите, абсолютно обыкновенный jqGrid, но в «настройках» есть несколько интересных моментов:

    • subGrid: – в строке 19. Эта опция позволяет использовать подтаблицу.
    • subGridUrl: – указывает путь к скрипту, который должен вернуть данные для построения подтаблицы. В данном случае происходит запрос к тому же скрипту, который «обслуживает» и таблицу-родителя при этом передав ему параметр get со значением subgrid
    • subGridModel: – свойство которое задает параметры подтаблицы. Аналогично colModel таблицы-родителя

    subGridModel: – представляет из себя массив с объектом, у которого есть свои параметры. name, width и align уверен их имена говорят сами за себя, это тексты заголовков столбцов, ширины соответствующих столбцов и выравнивание в них соответственно. Более интересным будет свойство params. Оно позволяет передать значения из каких то ячеек родительской таблицы на сервер при запросе подтаблицы. Иными словами, когда вы нажмете на крестик , открывающий подтаблицу, происходит запрос к серверу которому передается клоч (id) записи (в нашем случае это country_code) и плос к этим данным можно передать дополнительные (в нашем случае серверу будет передан еще и country_name). А вот на сервере получив значения нужных параметров (в этом примере серверный скрипт просто игнорирует значение параметра country_name) вы выполняем запрос к БД и выводим JSON объект с данными.

    ...
    $get = $_REQUEST['get'];  // Параметр указывающий на то
                                        //  что мы запросили информацию для подтаблицы
    ...
    switch ($get){
        case 'subgrid':
            // Выбрать города запрошенной страны
            $id =$_REQUEST['id'];
    
            // Запрос данных
            $query = "SELECT id, country_code, region_code, city, latitude, longitude, nbip FROM cities  WHERE country_code LIKE '".$id."'";
    
            $result = mysql_query($query);
            if(mysql_num_rows($result) >= 1){
                // Строки данных для таблицы
                $i = 0;
                while($row = mysql_fetch_assoc($result)) {
                    $data->rows[$i]['cell'] = array($i+1,'<strong><em>'.$row['city'].'</em></strong>',$row['latitude'],$row['longitude']);
                    $i++;
                }
            }
            break;
    
        default:
            // Выбрать названия стран и сосчетать города
            ...
    
    }
    // Вывести результат
    ...
    

    Серверный скрипт особо ничем не отличается от рассмотренных в предыдущих примерах. При этом он разбит на две части оператором switch. Который по умолчанию выполняет «стандартную» обработку и вывод данных для главной таблицы. А вот если этот скрипт запустить передав ему параметр get (я выбрал такое имя только ради наглядности) тогда будет выполнена выборка данных для подтаблицы. Ну и если у вас чешутся руки поковырять пример, вы можете скачать его.

    Подтаблицы это замечательный инструмент, который позволяет очень элегантно организавать данные, но при этом имеет один существенный недостаток – подтаблица «не живая». Т.е. данные в подтаблице не могут сортироваться, нет возморжности реализовать поиск и т.д. А это очень критично если в подтаблице будет выводиться много записей. Однако это ограничение отпадает само собой при использовании jqGrid как подтаблицы.

    2)jqGrid как subgrid
    Итак начнем с промотра ДЕМО3.4. Как видите все тот же «родной» jqGrid с названиями стран, и кол-вом городов в этой стране, но при этом подтаблица теперь представляет из себя самую настоящую jqGrid со всеми свойствами и методами. Согласитесь, что так работать намного приятнее и удобнее.

    А вот здесь самое интересное – клиентский код (в листинге опущены все настройки родительской таблицы, кроме одного свойства):

    ...
    subGrid: true,
    subGridRowExpanded: function(subgrid_id, row_id) {
        var subgrid_table_id;
        subgrid_table_id = subgrid_id+'_t';
    
        $('#'+subgrid_id).html('<table id="'+subgrid_table_id+'"></table><div id="'+subgrid_table_id+'_pager"></div>');
        $('#'+subgrid_table_id).jqGrid({
            url: 'p3e4.php',
            datatype: 'json',
            mtype: 'POST',
            postData: {'get':'subgrid', 'id':row_id},
            colNames: ['Город', 'Широта', 'Долгота'],
            colModel: [
                {name: 'city', index: 'city', width:130},
                {name: 'latitude', index: 'latitude', width:80, align: 'right'},
                {name: 'longitude', index: 'longitude', width:80, align: 'right'}
                ],
            height: 'auto',
            autowidth: true,
            rownumbers: true,
            rownumWidth: 40,
            rowNum: 10,
            sortname: 'city',
            sortorder: 'asc',
            pager: $('#'+subgrid_table_id+'_pager'),
            rowNum:10,
            rowList:[10,20,50,100]
        });
    }
    ...
    

    Настройки таблицы-родителя идентичные предыдущему примеру, но при этом появилось новое свойство subGridRowExpanded. Думаю самые догадливые поняли, а самые любопытные прочли в документации в секции Subgrid, что subGridRowExpanded не просто свойство, а событие.

    subGridRowExpanded – это событие возникает когда пользователь кликает на крестик раскрытия подтаблицы и выполняет определенную функцию при распахивании «кармана» для подтаблицы. При этом в функцию обработчик будут переданы 2 параметра:

    • pID – уникальный идентификатор «кармана» (контейнера, если хотите) который открывается под выбранной строкой
    • id – идентификатор записи под которой открылся «карман»

    Безусловно существуют еще события, о которых вы можете узнать из документации. А мы пока пробежимся по листингу. Итак когда пользователь «тыцнул» на крестик, открывается контейнер и выполняется функция. Которая получает 2 параметра subgrid_id и row_id. Далее в строке 5 создаем строковое значение для атрибута id и в 6й строке используем метод jQuery, который вставляет в «карман» (кстати сказать что это обыкновенный DIV) html разметку таблицы и DIV’a. А далее идет бональная инициализация jqGrid для только что созданной разметки. Т.е. фактически мы просто напросто динамически создали разметку и создали jqGrid! В этот момент я воскликнул «Тааак!» и потер руки. Почему? Да потому, что зная id объекта (<div id="someid">…</div>) с помощью jQuery можно сотворить с ним все что угодно. Но прежде чем мы перейдем к следующему примеру я приведу ссылку на раздаточный материал по теме – это пример который только что расмотрели.
    А теперь зная id контейнера давайте, еще добавим наглядности нашему примеру со странами и городами, например как на ДЕМО3.5. Как видите все эта же, скучная таблица со странами, но теперь при клике на крестик открывается подробная информация и флаг выбранной строки. Под которой свернутая jqGrid таблица с перечнем городов. Этот пример вы можете скачать перейдя по этой ссылке. Внутри архива все скрипты, но наибольший интерес представляет клиентский код. Я условно разделю его на 2 части, первая (нижняя) часть:

    $('#table').jqGrid({
              ...
              subGrid: true,
              subGridRowExpanded: function(subgrid_id, row_id) {
                           getCountryDetails(subgrid_id, row_id);
                       }
    
    });
    

    Это таблица из предыдущего примера, но теперь при возникновении события subGridRowExpanded будет выполнена пользовательская функция getCountryDetails(), которая и является 2 половиной клиентского скрипта:

    function getCountryDetails(container, countryCode){
        $.ajax({
                type: 'post',
                url: 'p3e5.php',
                data: ({'id': countryCode, 'get': 'details'}),
                dataType: 'json',
                success: function(server){
                    $('#'+container).html('<div class="c_detail"><img src="files/images/'+server.flag+'"><ul><li><strong>Столица:</strong> '+server.capital+'</li><li><strong>Дата независимости:</strong> '+server.independence_date+'</li><li><strong>Официальные языки:</strong> '+server.off_lng+'</li><li><strong>Форма правления:</strong> '+server.government+'</li><li><strong>Глава правительства:</strong> '+server.president+'</li><li><strong>Валюта:</strong> '+server.currency+'</li><li><strong>Интернет-домены:</strong> '+server.domains+'</li><li><strong>Телефонный код:</strong> '+server.dialing_code+'</li><li><strong>Часовой пояс:</strong> '+server.time_zone+'</li></ul></div>');
    
                    var subgrid_table_id = container+'_t';
    
                    $('#'+container).append('<table id="'+subgrid_table_id+'"></table><div id="'+subgrid_table_id+'_pager"></div>');
                    $('#'+subgrid_table_id).jqGrid({
                              caption: 'Города',
                              hiddengrid: true,
                              url: 'p3e4.php',
                              datatype: 'json',
                              mtype: 'POST',
                              postData: {'get':'subgrid', 'id':countryCode},
                              colNames: ['Город', 'Широта', 'Долгота'],
                              colModel: [
                                {name: 'city', index: 'city', width:130},
                                {name: 'latitude', index: 'latitude', width:80, align: 'right'},
                                {name: 'longitude', index: 'longitude', width:80, align: 'right'}
                              ],
                              height: 'auto',
                              autowidth: true,
                              rownumbers: true,
                              rownumWidth: 40,
                              rowNum: 10,
                              sortname: 'city',
                              sortorder: 'asc',
                              pager: $('#'+subgrid_table_id+'_pager'),
                              rowNum:10,
                              rowList:[10,20,50,100]
                    });
                }
        });
    }
    

    В теле этой функции выполняется AJAX запрос, передающий серверному скрипту 2 параметра методом POST:

    • id – идентификатор записи, в нашем случае это сокращенный код страны
    • get – этот параметр указывает, что мы хотим получить с сервера детальную информацию по выбранной стране

    После того как запрос будет успешно выполнен (см. строку 8), в открывшийся под выбранной строкой контейнер будет помещена какая-то HTML разметка с полученными с сервера данными. В данном примере такая разметка представлена не нумированным списком в картинкой – флагом страны. После этого в этот же контейнер помещается разметка для дочерней таблицы и производится инициализация дочерней таблицы.

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

    Как вы понимаете в контейнер для подтаблицы можно помещать не только какую-то примитивную разметку, но и формы, флеш, другие «вкусные» и полезные вещи.

    3)Ведущая и ведомая jqGrid

    Однако не всегда можно сгруппировать данные и засунуть их в подтаблицу. Иногда данные могут быть полностью самостоятельными и при этом иметь некую связь. Например однажды передо мной стала задача вывести пользователю перечень счетов и платежей по этим счетам, и при этом обеспечить возможность просмотра счетов, платежей и платежей по выбранному счету. И тут то мне очень помогла методика «ведущий-ведомый». Работа которой проиллюстрирована в ДЕМО5.6.

    Имеется две jqGrid, отображающие страны и города, которые можно менять местами благодаря плагину sortable. Также в верхней части документа есть checkbox который включает функцию фильтрации содержимого ведомой (нижней) таблицы, на основе выбранной записи в ведущей (верхней) таблице. При этом вся фильтровка осуществляется на стороне сервера, с этого и начнем разбор примера. Для удобства две таблицы запрашивают данные у двух отдельных серверных скриптов, один для городов, другой для стран.
    Скрипт для таблицы «Города» (т.к. основная структура скрипта «стандартна» я привожу лишь основные моменты):

    // Получение параметров page, rows и т.д.
    ...
    if($_REQUEST['filterBy'] != 'null')  // Фильтр
        $WHERE = " WHERE country_code = '".$_REQUEST['filterBy']."' ";
    else
        $WHERE = '';
    ...
    // Запрос подсчета суммарного кол-ва записей
    $result = mysql_query("SELECT COUNT(*)AS count FROM cities".$WHERE);
    ...
    // Запрос выборки данных
    $result = mysql_query("SELECT city, latitude, longitude FROM cities ".$WHERE." ORDER BY ".$sidx." ".$sord." LIMIT ".$start.", ".$limit);
    

    В данном случае клиентский код при запросе данных с сервера помимо «стандартных» параметров, отправляет еще и дополнительный параметр filterBy, который по сути и определяет критерий по которому нужно выбрать записи из БД и вернуть клиенту. Что и проиллюстрировано в последующих запросах.

    Скрипт для таблицы «Страны»:

    // Получение параметров page, rows и т.д.
    ...
    if($_REQUEST['filterBy'] != 'null'){
         $country = @mysql_fetch_array(mysql_query("SELECT country_code FROM cities WHERE id = ".$_REQUEST['filterBy']));
         $WHERE = " WHERE country_code = '".$country['country_code']."' ";
    }else{
         $WHERE = '';
    }
    ...
    // Запрос подсчета суммарного кол-ва записей
    $result = mysql_query("SELECT COUNT(*)AS count FROM countries ".$WHERE);
    ...
    // Запрос выборки данных
    $result = mysql_query("SELECT * FROM countries ".$WHERE." ORDER BY ".$sidx." ".$sord." LIMIT ".$start.", ".$limit);
    

    Как видите полная аналогия предыдущего листинга, но теперь если передано определенное значение фильтра, происходит дополнительный запрос для уточнения кода страны.
    На этом все премудрости серверной стороны заканчиваются и начинается клиентский код, но прежде чем перейти к его рассмотрению пара слов о разметке страницы:

    <input type="checkbox" id="link">
    <label for="link">Связать таблицы</label>
    
    <div id="interfaceBody" style="margin: 10px 10px 10px 10px; padding: 0px 10px 10px 10px; border: 2px solid gray">
    <div class="grid" id="countries" style="padding: 10px 10px 10px 10px; margin-top: 10px; border: 2px solid red">
        <table id="table_countries"></table>
        <div id="table_countriesPager"></div>
    </div>
    <div class="grid" id="cities" style="padding: 10px 10px 10px 10px; margin-top: 10px; border: 2px solid green">
        <table id="table_cities"></table>
        <div id="table_citiesPager"></div>
    </div>
    </div>
    

    Если не обращать внимание на ужасно длинные inline-стили, то разметка достаточно проста. Сначала идет код checkbox’a с меткой, а следом контейнер всего интерфейса, внутри которого два дочерних контейнера, по одному для каждой таблицы.

    И наконец клиентский скрипт:

    //-------------------------------------------------------------------
    // Функция-обработчик
    function stickTogether(){
        if($('#link').is(':checked')){
            // Флаг "Связать таблицы" утановлен
            var masterId        = $('#interfaceBody > DIV:first').attr('id');                //Определяем ID контейнера "ведущей таблицы"
            var masterPostData  = $('#table_'+masterId).jqGrid('getGridParam','postData');   //Получаем весь объект postData "ведущей таблицы"
            var selId    = $('#table_'+masterId).jqGrid('getGridParam','selrow');            //Получаем id записи в выделенной строке
                                                                                             //не путайте с rowIndex
            // Проверяем какое текущее значение фильтра ведущей таблицы, он должен быть сброшен (например null)
            if(masterPostData.filterBy){
                $('#table_'+masterId).jqGrid('setGridParam',{'postData':{'filterBy':null}}); //Сбрасываем значение фильтра
                $('#table_'+masterId).trigger('reloadGrid');                                 //Перезагружаем данные в таблицу
            }
    
            var slaveId  = $('#interfaceBody > DIV:last').attr('id');                        //Определяем ID контейнера "ведомой таблицы"
            $('#table_'+slaveId).jqGrid('setGridParam',{'postData':{'filterBy':selId}});     //Применяем в качестве фильтра ведомой таблицы
                                                                                             //id выбранной записи в ведущей таблице
            $('#table_'+slaveId).trigger('reloadGrid');                                      //Перезагружаем данные в таблицу
        }else{
            // Флаг "Связать таблицы" не утановлен
            var coutriesT       = $('#table_countries');
            var countriesPost   = coutriesT.jqGrid('getGridParam','postData');
    
            if(countriesPost.filterBy){ //Сбрасываем фильтр т.к. ничего не нужно фильтровать
                coutriesT.jqGrid('setGridParam',{'postData':{'filterBy':null}})
                coutriesT.trigger('reloadGrid');
            }
            //-----------------------
            var citiesT       = $('#table_cities');
            var citiesPost    = citiesT.jqGrid('getGridParam','postData');
    
            if(citiesPost.filterBy){ //Сбрасываем фильтр т.к. ничего не нужно фильтровать
                citiesT.jqGrid('setGridParam',{'postData':{'filterBy':null}})
                citiesT.trigger('reloadGrid');
            }
        }
    }
    //-------------------------------------------------------------------
    // Настройка плагинов
    var tcountries = $('#table_countries').jqGrid({
                              caption: 'Страны',
                              hidegrid: false,
                              url:'p3e6_countries.php',
                              postData: {'filterBy':null},
                              datatype: 'json',
                              mtype: 'POST',
                              colNames:['Код страны','Cтрана','Столица','Домены'],
                              colModel :[
                                        {name:'country_code', index:'country_code', width:80, hidden: true},
                                        {name:'country_name', index:'country_name', width:60},
                                        {name:'capital', index:'capital', width:60},
                                        {name:'domains', index:'domains', width:60}
                                        ],
                              pager: $('#table_countriesPager'),
                              rowNum: 100,
                              scroll: true,
                              viewrecords: true,
                              sortname: 'country_name',
                              sortorder: 'asc',
                              height: 200,
                              autowidth: true,
                              onSelectRow: stickTogether
                    });
    
    var tcities = $('#table_cities').jqGrid({
                              caption: 'Города',
                              hidegrid: false,
                              url: 'p3e6_cities.php',
                              postData: {'filterBy':null},
                              datatype: 'json',
                              mtype: 'POST',
                              colNames: ['Город', 'Широта', 'Долгота'],
                              colModel: [
                                {name: 'city', index: 'city', width:130},
                                {name: 'latitude', index: 'latitude', width:80, align: 'right'},
                                {name: 'longitude', index: 'longitude', width:80, align: 'right'}
                              ],
                              height: 200,
                              autowidth: true,
                              rownumbers: true,
                              rownumWidth: 40,
                              rowNum: 100,
                              sortname: 'city',
                              sortorder: 'asc',
                              pager: $('#table_citiesPager'),
                              scroll: true,
                              viewrecords: true,
                              onSelectRow: stickTogether
                    });
    
    $("#interfaceBody").sortable({
            connectWith: '.grid',
            placeholder: 'ui-state-error',
            opacity: 0.7,
            stop: stickTogether
    });
    
    //-------------------------------------------------------------------
    // Назначаем обработчик на событие
    $('#link').change(stickTogether);
    

    При всем своем объеме код достаточно груб и прост. Начнем пожалуй с назначения обработчика на изменение checkbox’a, самая последняя строка в листинге. Как видите при изменении checkbox’a будет вызвана функция stickTogether. В теле которой происходит проверка состояния флажка и если он не установлен, то произойдет сброс всех «фильтров» таблиц и перезагрузка данных в таблице.
    Но самое интересное это код в «положительной» ветке if’а, когда флажок установлен. Мы знаем, что ведущая таблица расположена вверху, значит для начала узнаем какая же таблица в данный момент находится там. Для этого получаем значение атрибута id первого контейнера (строка 6). Теперь зная какая таблица ведущая – получаем объект postData, который, напомню, содержит все параметры и их значения для отправки серверу. В 7й строке получим Id записи в выделенной строке ведущей таблицы. Далее проверив значение фильтра ведущей таблицы, при необходимости сбросим его. Это необходимо если пользователь поменял таблицы местами.
    В строке 16 узнаем id контейнера ведомой таблицы. И применяем фильтр, записав id выделенной строки в ведущей таблице, и перезагружаем данные.
    У данного скрипта есть один недостаток – расплата за универсальность. Из-за того что на событие onSelectRow: в обоих таблицах определен один и тот же обработчик stickTogether, при выделении строки в ведомой таблице, происходит постоянное обновление ее записей. Но уверен что те кому потребуется такой функционал jqGrid без труда смогут это исправить.

    Заключение
    Подведя итоги проделанной работы можно сказать, что в данной статье мы рассмотрели практически все варианты расширенного использования плагина. Научились работать с древовидными данными и подтаблицами, а также попробовали управлять содержимым ведомой таблицы посредством данных из ведущей. В следующей части я рассмотрю еще одну экзотическую интересную опцию jqGrid – «drag’n’drop записей между jqGrid’ами».
    Ну и как всегда если у вас возникли вопросы задавайте их на форуме ну а комментарии используйте для предложений и пожеланий.

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

    • Расширенные возможности jqGrid
      • drag’n’drop записей между jqGrid’ами
    • Поиск данных в jqGrid
      • «inline» поиск
      • поиск с использованием встроенной формы
      • расширенный поиск с использованием встроенной формы
      • поиск с использованием внешней формы

    Источник: http://www.linkexchanger.su/2010/523.html

    Нет комментариев

    25

    May

    Yii framework. Часть 1 : Введение

    Опубликовал admin  Рубрика JavaScript, Программирование, Языки

    Предисловие

    В этом цикле статей я хочу рассказать о таком замечательном фреймворке, как yii. Предполагается, что у читателя есть некоторый навык работы с php5, особенно с его объектно-ориентированной частью. Я буду стараться охватить как можно больше разных аспектов создания веб-приложений на базе yii, добавляя от себя разные тонкости и хитрости; но не ждите от меня копипаста документации или api. И то и другое Вы можете найти на официальном сайте.

    Введение

    Что такое Yii?

    Yii это свободный(распространяется под new BSD licence) высокопроизводительный объектно-ориентированный расширяемый php-фрэймворк для разработки веб-приложений.

    Зачем он нужен?

    Для удобной разработки веб-приложений и чтобы не изобретать сто раз изобретенный велосипед.

    Основные особенности :

    • MVC-архитектура
    • Работа с базами данных
    • Поддержка кэширования на разных уровнях
    • Большое количество встроенных компонентов
    • Возможность простого подключения сторонних библиотек
    • Интеграция с jQuery

    Подготовка:

    Системные требования:

    • Веб-сервер(рекомендуется Apache)
    • PHP версии не ниже 5.1.0
    • PDO-совместимая СУБД (MySql, PostgreSQL, SqLite, Microsoft SQL, Oracle8) и соответствующее php-расширение для её поддержки.

    Рекомендуемые расширения для php:

    • gd – для работы с графикой.
    • mcrypt – для функций кодирования.
    • MemCache или APC – для кэширования, ускорения работы.

    Такой нехитрый набор в наше время можно найти почти на любом хостинге.

    Для домашнего тестирования на linux можно установить пакеты из стандартных репозитариев.Если же Вы предпочитаете на windows, могу порекомендовать в качестве готового решения denwer.

    Для пользователей денвера:

    (В данном случае, Z: это диск, монтируемый денвером)
    1. Для начала прописываем в переменные окружения путь  Z:\usr\local\php5\
    2. Открываем /usr/local/php5/php.ini, ищем строчку extension_dir = «/usr/local/php5/ext», заменяем на extension_dir = «Z:\usr\local\php5\ext»
    3. session.save_path = «/tmp» на session.save_path = «Z:\tmp»

    Установка:

    На момент написания статьи, последняя стабильная версия была 1.1.0. Скачать её можно в виде архива по адресу  http://yiiframework.com/download
    Вся установка сводится к распаковке содержимого архива.Для начала рекомендую распаковать всё в директорию доступную из веб и открыть папку requirments в браузере, чтобы убедиться в наличии всех необходимых компонентов.

    Для создания приложения необходимо использовать коммандную строку(ssh при удалённом доступе). Нужно запустить файл yiic.bat(для windows) или yiic(для linux и других unix-based систем) с параметрами webapp /full/path/to/new/wbebapp/.
    Например :

    $ /var/www/framework/yiic webapp /var/www/testing

    Убедитесь, что у вас есть права записи в директорию, где Вы хотите создать веб-приложение и она доступна из web. Можно зайти в нее через браузер и увидеть возможности, предоставлямые yii «из коробки».

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

    Модель – Представление – Контроллер(MVC) – это модульная архитектура, применяющийся в веб-программировании(в частности и в yii). Она направлена на разделение логики(контроллер), управления данными(модель) и пользовательского интерфейса(представление) с целью возможности изменять одни части не внося изменения в другие.

    Основные части, из которых состоит yii:

    В yii имена всех системных классов начинается с перфикса C , с целью недопущения коллизии имён. По этому, пожалуйста, воздержитесь от использования этого префикса в своих классах.

    Входной файл
    Входной файл(обычно index.php) это единственный скрипт, с которым контактирует пользователю. Вобщем-то, всё что он делает, это читает конфигурацию и создаёт экземпляр класса CWebApplication.
    Приложение(application)
    Приложение(экземпляр класса CWebApplication) обрабатывает запрос пользователя, выполняет роутинг и передаёт его на исполнение соответствующему контроллеру.
    Контроллер(controller)
    Контроллер(экзэмпляр класса CController или производного от него) определяет основную логику приложения, взаимодействует с моделями и отображениями. Контроллеры обычно находятся в папке /protected/controllers. По соглашению, класс контроллера и имя файла с ним : NameController.php
    Действие(action)
    Действие это тип действия, выполняемого пользователем, например просмотр статьи в блоге или отправка комментария. Обычно является методом контроллера(вида actionName), но может быть вынесенно в отдельный класс.
    Модель (model)
    Модель представляет собой сущность данных. Например таблица в базе данных(CActiveRecord) или форма на веб-странице(CForm). Она занимается непосредственной обработкой данных: созданием, получением, изменением. Также представляет интерфейс доступа к валидаторам(validator), проверяющим корректность введённых пользователем данных. Модели находятся в папке /protected/models. Модель обычно имеет имя, соответствующее таблице в бд, которую она представляет.
    Представление(view)
    Представление генерирует готовые части страницы, отдаваемой пользователю.Оно не использует логики, кроме как условий и циклов. Представления для каждого контроллера обычно раздельны и хранятся в /protected/views/controllername/.
    Макет (layout)
    Макет это специальное представление для вставки других представлений. Обычно он содержит части пользовательского интерфейса, используемого другими представлениями. Например, основной макет может содержать в себе шапку и подвал страницы, места для подключения других представлений и виджетов. Макеты храняться в /protected/views/layouts. По умолчанию используется макет main.php.
    Виджет(widget)
    Виджет это компонент для генерации самодостаточного элемента пользовательского интерфейса(например, верхнее меню в тестовом приложении). В zii (библиотеке расширений, поставляемых вместе с yii) имеется большое количество готовых виджетов.
    Компонент(component)
    Представляет сущность какого-либо аспекта веб-приложения. Например, авторизация пользователей. В yii много готовых компонентов, которые могут использоваться как в готовом виде, так и расширяться веб-разработчиками.
    Модуль(module)
    Модуль, это самодостаточная единица, состоящая из контроллеров, моделей, отображений, и.т.д. Модули используются для разделения сайта на логические части, например форум и блог.

    Заключение

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

    И на последок хочу дать несколько полезных ссылок:

    Оффициальный сайт (en)

    Русскоязычное сообщество (ru)

    Блог, посвящённый yii (ru)

    В следующей статье:

    В следующей статье мы познокомимся со внутренним устройством фреймворка, научимся делать собственные контроллеры, модели и отображения, изучим основы ActiveRecord.

    Источник: http://www.linkexchanger.su/2010/418.html

    Нет комментариев

    25

    May

    jQuery. Сборник рецептов

    Опубликовал admin  Рубрика JavaScript, Программирование, Языки

    Несколько дней назад в интернет-магазинах появилась в продаже книга «jQuery. Сборник рецептов». Книга вышла в издательстве «БХВ-Петербург». Написана она мной – автором этого блога.

    • Геннадий Самков
    • jQuery. Сборник рецептов (+ CD-ROM)
    • Издательство: БХВ-Петербург, 2010 г.
    • Мягкая обложка, 410 стр.
    • ISBN 978-5-9775-0495-9
    • Тираж: 1500 экз.
    • Формат: 70×100/16

    jQuery. Сборник рецептов

    Аннотация:
    Книга является сборником решений наиболее часто встречающихся задач при веб-программировании пользовательских интерфейсов с использованием библиотеки jQuery. Рассмотрены практически все методы и вспомогательные функции jQuery, в том числе обеспечивающие взаимодействие jQuery и AJAX. Подробно рассказано о надстройке UI jQuery и приведены описания всех настроек для виджетов, входящих в ее состав, что позволяет использовать книгу в качестве справочника. Приведено большое количество примеров использования наиболее популярных плагинов для jQuery – создание графиков и диаграмм, фотогалерей, навигационных меню, всплывающих подсказок, работа с веб-формами, таймерами и cookies, обработка табличных данных. Компакт-диск содержит примеры, разобранные в книге, файлы библиотеки jQuery версий 1.2.6 и 1.3.2, файлы надстройки UI jQuery, а также файлы рассмотренных в книге расширений сторонних разработчиков.

    От себя могу добавить, что книга написана в таком же духе, как и предыдущая: «AJAX. Программирование для Интернета«, т.е. примеры, примеры и еще раз примеры плюс подробные разъяснения….

    Полное содержание:

    Введение 1
    Структура книги 1
    Как работать с книгой 2
    Источники информации 3
    Благодарности 4

    ЧАСТЬ I. МЕТОДЫ БИБЛИОТЕКИ JQUERY

    5

    Глава 1. Выбор элементов

    7
    1.1. Базовые правила 7
    1.2. Выбор элементов с учетом иерархии 14
    1.3. Основные фильтры 18
    1.4. Фильтрация по содержимому 24
    1.5. Фильтры видимых и невидимых элементов 28
    1.6. Фильтры атрибутов 29
    1.7. Фильтры элементов форм 35
    1.8. Фильтры состояния элементов форм 37
    1.9. Фильтры элементов-потомков 42

    Глава 2. Атрибуты элементов

    48
    2.1. Управление атрибутами элементов 48
    2.2. Работа с атрибутом class 53
    2.3. Работа с HTML и текстом 54
    2.4. Работа с атрибутом value 57

    Глава 3. Визуальные эффекты

    64
    3.1. Как показывать и скрывать элементы 64
    3.2. Эффекты «скольжения» и «затухания» 67
    3.3. Создание анимации 71
    3.4. Эффекты UI jQuery 76

    Глава 4. Работа с CSS-свойствами

    81
    4.1. Как получать и устанавливать значения CSS-свойств элементов 81
    4.2. Ширина и высота элементов 85
    4.3. Позиционирование элементов 88

    Глава 5. Некоторые методы ядра библиотеки jQuery

    92
    5.1. Примеры работы с объектом jQuery 92
    5.2. Сохранение и извлечение данных 97

    Глава 6. Манипуляции над элементами

    101
    6.1. Изменение содержимого элементов 101
    6.2. Как вставлять элементы в DOM 103
    6.3. Замена, удаление и копирование элементов 113

    Глава 7. Перемещение по элементам

    120
    7.1. Поиск нужных элементов в DOM 120
    7.2. Фильтрация элементов набора 131
    7.3. Перемещение по цепочке вызовов 138

    Глава 8. События и их обработка

    142
    8.1. Готовность документа 142
    8.2. Назначение, удаление и вызов событий 144
    8.3. Взаимодействие с элементами 152
    8.4. События 155

    Глава 9. Взаимодействие jQuery и AJAX

    161
    9.1. Самое простое 161
    9.2. GET- и POST-запросы 166
    9.3. Вспомогательная функция $.ajax(options) 174
    9.4. Для чего нужна функция $.ajaxSetup(options) 180
    9.5. События AJAX 183

    Глава 10. Утилиты jQuery

    190
    10.1. Некоторые операции с массивами и объектами в jQuery 190

    ЧАСТЬ II. РАСШИРЕНИЯ ДЛЯ БИБЛИОТЕКИ JQUERY

    201

    Глава 11. Меню для веб-сайта

    203
    11.1. Плагин jQuery Multi Level Menu 203
    11.2. Плагин jQuery Drop Line Menu 207
    11.3. Плагин jQuery TreeView 210
    11.4. Делаем меню похожее на Accordion 216

    Глава 12. Работа с таблицами

    219
    12.1. Плагин jQuery DataTables 219

    Глава 13. Графики и диаграммы

    229
    13.1. Плагин jqPlot 229

    Глава 14. AJAX-формы

    242
    14.1. Плагин jQuery Autocomplete 242
    14.2. Плагин jQuery Form 252
    14.3. Плагин jQuery Validate 257
    14.4. Плагин jQuery Uploadify 264

    Глава 15. Фотогалереи для сайта

    274
    15.1. Фотогалерея FancyBox 274
    15.2. Простая фотогалерея 282

    Глава 16. Несколько полезных плагинов

    286
    16.1. jQuery Cookie 286
    16.2. jQuery Corner 288
    16.3. jQuery Timers 293
    16.4. jQuery Cluetip 297

    Глава 17. UI jQuery — виджеты

    303
    17.1. Виджет Accordion 303
    17.2. Виджет Datepicker 314
    17.3. Виджет Dialog 326
    17.4. Виджет Progressbar 334
    17.5. Виджет Slider 337
    17.6. Виджет Tabs 343

    Глава 18. UI jQuery — взаимодействие с элементами страницы

    354
    18.1. Draggable — перемещение элементов 354
    18.2. Droppable — «сброс» элементов 364
    18.3. Resizable — изменение размеров элементов 371
    18.4. Selectable — выбор элементов 377
    18.5. Sortable — сортировка элементов 385
    Литература 397
    Приложение. Описание компакт-диска 398
    Предметный указатель 400
    Оглавление

    Источник: http://www.linkexchanger.su/2010/115.html

    Нет комментариев

    25

    May

    JavaScript мастер-классы

    Опубликовал admin  Рубрика JavaScript, Программирование, Языки

    Недавно узнал, что 20-21 февраля в Москве и 27-28 февраля в Санкт-Петербурге пройдут мастер-классы по Javascript, которые будет вести Илья Кантор – создатель сайтов algolist.manual.ru и javascript.ru.

    Это мой уважаемый коллега, человек с большим опытом разработки сложных приложений, в прошлом один из разработчиков javascript-фреймворка Dojo Toolkit.

    » Профессиональное javascript-программирование
    » Сложный AJAX и COMET: тонкости Web 2.0
    » Мастер-класс по клиентской оптимизации
    » Секреты jQuery

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

    И еще, очень интересно! Принять участие в мастер-классе «Секреты jQuery» можно будет в режиме on-line.

    Исходное объявление на javascript.ru »

    Для понимания материала необходимо знать javascript на минимальном уровне, писать простые скрипты. Содержание мастер-классов построено так, чтобы максимально глубоко раскрыть темы за короткий срок.

    Теперь подробнее о содержании мастер-классов.

    «Профессиональное javascript-программирование»

    - Javascript, browser tips & tricks.
    - Фишки DOM, функции/замыкания, ООП – понятно и в деталях.
    - Малоизвестные возможности javascript и браузеров.
    - Javascript-фреймворки. Сравнение современных возможностей. jQuery в деталях.
    - Полезный инструментарий, который сделает вашу разработку быстрее и качественнее. Гораздо больше, чем Firebug.
    - Обмен информацией между окнами с разных доменов
    - HTML5: что уже есть, а что нас ждет уже скоро.

    Этот мастер класс – отнюдь не об основах javascript, здесь присутствует много информации для профессионалов.
    Москва: суббота, 20 февраля, 11.00
    Санкт-Петербург: суббота, 27 февраля, 11.00
    Продолжительность – 4 часа.

    «Клиентская оптимизация»

    - Способы и принципы сжатия javascript, что делать, чтобы код сжимался эффективнее.
    - Идеальное кеширование. Скрипты и серверная часть.
    - Эффективная оптимизация javascript. Подходы, цифры, рецепты.
    - Основные приемы оптимизации jQuery.
    - Ускорение загрузки страницы через HTTP pipelining.
    - Оптимизация с Google Gears и HTML5.
    - Google Closure Compiler в деталях
    - Удобные инструменты для оптимизации и профайлинга.

    Про то, как ускорить страницу, почти ничего не делая, и как серьезно ускорить страницу и сайт, если что-то сделать.
    Москва: воскресенье, 21 февраля, 11.00
    Санкт-Петербург: воскресенье, 28 февраля, 11.00
    Продолжительность – 4 часа.

    «Сложный AJAX и COMET: тонкости Web 2.0″

    - Асинхронная подгрузка событий с сервера (COMET) – различные варианты, сравнение и примеры реализации.
    - Кнопки back-forward, закладки и история с AJAX.
    - Cпособы написания чата/оповещающего демона, аспекты производительности и решения.
    - Кросс-доменные ограничения, способы их преодоления.
    - Асинхронный try..catch. Удобная работа с асинхронностью.
    - Инструменты для разработки и отладки сложных AJAX-приложений.
    - Специализированный COMET-сервер, установка, расширение, интеграция. Поднимем COMET прямо на мастер-классе.

    Мастер-класс сделает современные подходы простыми и понятными для вас, позволит улучшить те приложения, которые есть сейчас, и перейти к качественно новой разработке в будущем.
    Москва: суббота, 20 февраля, 16.00
    Санкт-Петербург: суббота, 27 февраля, 16.00
    Продолжительность – 4 часа.

    «Секреты jQuery»

    1. Как работает поисковой движок jQuery $(‘…’).
    - Внутреннее устройство. Алгоритм поиска. No magic.
    - Почему некоторые очевидные запросы тормозят, и как их ускорять.
    - Расширение поискового движка, добавление своих фильтров.
    2. Система событий в jQuery.
    - Внутреннее устройство.
    - Слабо- и недокументированные фичи, отсутствующие в обычных javascript-событиях.
    - Влияние системы событий на быстродействие и DOM-манипуляции. Что тормозит и почему.
    - Обход утечек памяти.
    3. Фишки AJAX.
    - Особенные фичи AJAX в jQuery, которых нет в других библиотеках и полезные приемы работы с ними.
    4. $.изнутри.
    - Внутреннее устройство функции $. Что она делает быстро, а что – нет.
    - Создание плагинов. Внутренний механизм работы $.fn.plugin.
    5. jQuery UI.
    - Обзор и устройство jQuery UI.
    - Написание собственных виджетов. Объявление, вызов методов и т.п. Примеры.
    - Приемы для более удобной работы с виджетами.
    6. Профайлинг jQuery-приложения
    - Как из каши $(вызовов) получить читаемый профиль.
    7. Дополнительно.
    - Общий обзор библиотеки jQuery, ее сильных и слабых мест. Сравнение с другими фреймворками. Новое в jQuery 1.4.

    Мастер-класс посвящен слабо документированным особенностям и устройству фреймворка jQuery. Это не вводный курс. Знакомство и опыт работы с фреймворком jQuery – обязательны.
    Москва: воскресенье, 21 февраля, 16.00
    Санкт-Петербург: воскресенье, 28 февраля, 16.00
    Продолжительность – 3 часа.
    On-line: суббота, 27 февраля, 20.00-21.50 и воскресенье, 28 февраля, 20.00-21.50

    Дополнительная информация, запись на мастер-классы »

    Источник: http://www.linkexchanger.su/2010/117.html

    Нет комментариев

    25

    May

    jQuery 1.4

    Опубликовал admin  Рубрика JavaScript, Программирование, Языки

    Сегодня (по Москве почти в полночь) официально объявлено о выпуске jQuery версии 1.4. Выход новой версии, как и в прошлом году, приурочен к дню рождения библиотеки, которой исполнилось уже 4 года. Собственно, интересующиеся этой тематикой уже могли ознакомиться с релизами jQuery 1.4 Alpha 1 от 4 декабря 2009 года и jQuery 1.4 Alpha 2 от 18 декабря 2009 года. А 12 января появился релиз-кандидат jQuery 1.4rc1. Подробное знакомство с новшествами еще впереди, но я не мог не дать краткий обзор изменений и новых возможностей, которые появились в очередной версии. Начнем знакомство?

    Метод .addClass(className) теперь может принимать в качестве аргумента не только имя класса (или классов), но и функцию .addClass(function), которая должна возвратить один или более имен классов, которые должны быть добавлены элементу. Если имен классов более одного, они должны быть разделены пробелами. На примере:

    $('ul li:last').addClass(function() {
        return 'item-' + $(this).index();
    });

    Аналогичные изменения претерпели методы .removeClass(className) и .toggleClass(className), которые также теперь могут принимать функцию в качестве аргумента.

    Похожие изменения внесены в методы .after(content), .before(content), .append(content) и .prepend(content). Все эти методы начиная с версии 1.4 могут принимать в качестве аргумента функцию, которая должна возвращать строку html-кода.

    Аналогичным образом дополнены методы .html(htmlString) и .text(textString). Если до версии 1.4 эти методы принимали аргументом соответственно строку html-кода и обычный текст, то теперь аргументом может быть также функция – .html(function) и .text(function). Функции должны возвращать соответственно html-код и текст.

    Дополнен метод .val(). Теперь при установке нужного значения можно использовать не только собственно значение, но и функцию, которая должна возвращать требуемое значение.

    Дополнен метод .css(). Если раньше для того, чтобы установить значение какого-либо css-свойства мы использовали .css(propertyName, value) или .css(map) для того, чтобы установить значения сразу нескольких css-свойств элемента, то теперь получили возможность использовать во втором аргументе функцию, возвращающую то значение, которое должно быть установлено этому css-свойству .css(propertyName, function).

    Чтобы сохранить произвольные данные, связав их с выбранным элементом мы должны были передать методу .data(key, value) соответствующие пары ключ/значение. Теперь аргументом этого метода может быть и непосредственно объект .data(obj). Чтобы получить доступ к сохраненным данным требуется указать .data(key) имя под которым были сохранены эти данные. В дополнение к этому с версии 1.4 можно вызвать метод .data() без аргументов, и в этом случае данные будут возвращены в виде объекта.
    Точно также теперь можно поступить и в том случае, если данные, связанные с элементом были сохранены в свойстве data объекта jQuery.

    Начиная с версии 1.4 добавлены вспомогательные функции jQuery.isEmptyObject(object) – проверяет, является ли объект пустым (не содержащим свойств)

    jQuery.isEmptyObject({}) // вернет true
    jQuery.isEmptyObject({ foo: "bar" }) // вернет false

    и jQuery.isObjectLiteral(object) – проверяет является ли он простым объектом (создан с помощью {} или new Object)

    jQuery.isPlainObject({}) // true
    jQuery.isObjectLiteral("test") // false

    Добавлены методы .prevUntil([selector]), .nextUntil([selector]) и .parentsUntil([selector]). Первые два новых метода помогут выбрать все элементы соответственно перед и после, но при этом ДО элемента [selector] указанного в качестве аргумента метода. А метод .parentsUntil([selector]) поможет выбрать всех родителей, но также ДО элемента [selector] указанного в качестве аргумента.

    Дополнены методы .wrap(wrappingElement), .wrapAll(wrappingElement) и .wrapInner(wrappingElement). Теперь в качестве аргумента этих методов можно использовать функцию, которая должна возвращать структуру в которую будет обернут каждый выбранный элемент (для wrap), все выбранные элементы (для wrapAll) или внутреннее содержимое выбранного элемента (для wrapInner). Также добавлен новый метод .unwrap(), название которого говорит само за себя – удаляет непосредственных родителей выбранных элементов, оставляя сами элементы без изменений.

    Добавлен весьма полезный метод .delay(duration, [queueName]), которые позволяет установить таймер задержки выполнения следующего пункта очереди. На примере:

    $('#foo').slideUp(300).delay(800).fadeIn(400);

    Здесь метод fadeIn начнет выполняться только через 800 миллисекунд после того, как отработает метод slideUp.

    Добавлен метод .detach([selector]), который похож на метод .remove() тем, что также удаляет выбранные элементы из DOM, но, в отличие от .remove() новый метод сохраняет данные, связанные с удаленными элементами, что можно использовать при возврате удаленных элементы обратно в DOM.

    Добавлен метод .toArray(), который возвращает в виде массива все DOM-элементы, включенные в набор jQuery. Выполнив

    alert($('li').toArray());

    увидим что-то вроде

    [<li id="foo">, <li id="bar">]

    Дополнен метод .replaceWith(newContent) и теперь в качестве аргумента может использоваться функция, которая должна возвращать строку html-кода, которым должен быть заменен выбранный элемент.

    Дополнен метод .add(), с помощью которого можно добавлять в существующий набор дополнительные элементы. Если до версии 1.4 в качестве аргумента можно было указать jQuery-селектор, элемент(или элементы) и фрагмент html-кода, то теперь появилась возможность после селектора указать второй аргумент – контекст, в котором будет производится поиск нужного элемента(ов).

    Добавлены новые методы .focusin(handler(eventObject)) и .focusout(handler(eventObject)). Методы вызывают обработчики соответственно при получении и потере фокуса выбранным элементом. В качестве аргумента обработчик принимает объект события.

    Добавлен метод .has(selector), с помощью которого можно проверить наличие элемента внутри другого элемента. Для разметки

    <ul><li>Does the UL contain an LI?</li></ul>

    выполним код

    $("ul").append('<li>' +
    ($("ul").has("li").length ? "Yes" : "No") +
    '</li>');

    Такой код добавит в список элемент li с текстом Yes.

    Дополнен метод .index(element) с помощью которого можно было узнать индекс DOM-элемента в наборе. Теперь может принимать в качестве аргумента селектор jQuery, а также может быть вызван без передачи аргумента. Довольно интересно, чтобы смотреть на примерах.

    <ul>
      <li id="foo">foo</li>
      <li id="bar">bar</li>
      <li id="baz">baz</li>
    </ul>

    В качестве аргумента DOM-элемент:

    var listItem = document.getElementById('bar');
    alert('Index: ' + $('li').index(listItem));  // 1

    В качестве аргумента объект jQuery:

    var listItem = $('#bar');
    alert('Index: ' + $('li').index(listItem)); // 1

    И без передачи аргумента:

    alert('Index: ' + $('#bar').index(); // 1

    т.е. возвращается индекс (считаем от 0) элемента в наборе, в котором присутствуют все сестринские элементы этого уровня.

    Дополнен метод .closest(selector), теперь вторым параметром можно передать контекст.

    Добавлен новый метод .clearQueue([queueName]), который удаляет из очереди все функции, которые еще не были выполнены. Похож на .stop(true), однако есть отличия.

    Дополнен метод .offset(), который позволяет получить координаты выбранного элемента относительно документа. Теперь координаты можно будет устанавливать с помощью передачи этому методу аргумента – .offset(coordinates). Здесь coordinates – объект, содержащий свойства top и left, значениями которых являются числовые значения новых координат. Также в качестве аргумента может выступать функция .offset(coordinates(index,coords)), которая в свою очередь принимает в качестве первого аргумента индекс элемента в наборе, а качестве второго – его новые координаты.

    Изменения коснулись и функция jQuery(). Теперь при ее вызове без аргументов будет возвращен пустой набор.

    Изменения во вспомогательной функции jQuery.param(obj), которая упорядочивает предоставленный объект или массив, представляя его в форме, пригодной для передачи в URL или Ajax-запросе. Начиная с версии 1.4 можно передавать второй параметр jQuery.param(obj, traditional), где traditional – логическое значение, которое устанавливается в true, если необходимо эмулировать поведение этой функции как в версиях ниже 1.4.

    Новая вспомогательная функция jQuery.contains(container, contained), позволяющая проверить существование элемента DOM внутри другого элемента DOM. Здесь container – элемент DOM, который может содержать другой элемент DOM, а contained – элемент DOM, который может находится внутри. На примере:

    // true
    jQuery.contains(document.documentElement, document.body);
    // false
    jQuery.contains(document.body, document.documentElement);

    Добавлена jQuery.noop() – функция, которая ничего не делает.

    Новый метод jQuery.proxy(). Принимает пару аргументов, например так jQuery.proxy(function, scope), где function – функция, область видимости которой будет изменена, а scope – объект в который должна быть установлена область видимости функции. Грандиозно! Еще вариант – jQuery.proxy(scope, name), где scope – то же, а name – имя функции, область видимости которой будет изменена (должно быть свойством объекта ’scope’). На примере:

    var obj = {
      name: "John",
      test: function() {
        alert( this.name );
        $("#test").unbind("click", obj.test);
      }
    };
    // 2-й вариант
    $("#test").click( jQuery.proxy( obj, "test" ) );
    // И так тоже работает:
    // 1-й вариант
    // $("#test").click( jQuery.proxy( obj.test, obj ) );

    Обзор конечно получился краткий, несколько поспешный и насколько я уже понимаю с некоторыми неточностями (не по моей вине :) ), но для тех, кто хочет сам покопаться и разобраться повнимательнее – новый сайт API jQuery.

    P.S. Поздравляю всех с наконец-то окончательно наступившим Новым Годом, jQuery – с четвертым Днем Рождения и выходом очередной версии, а себя – с Днем Рождения своего блога, которому исполнилось два года.

    Источник: http://www.linkexchanger.su/2010/114.html

    Нет комментариев

    25

    May

    jQuery UI – плагин Sortable

    Опубликовал admin  Рубрика JavaScript, Программирование, Языки

    Плагин Sortable – один из нескольких плагинов, входящих в состав jQuery UI, с помощью которых можно организовать взаимодействие с элементами веб-станиц. Плагин Sortable предоставляет возможность организовать сортировку элементов, перемещая их с помощью указателя мыши.

    Читаем, и пробуем проделать все это самостоятельно.

    Для начала посетим страницу настраиваемой закачки на сайте jQuery UI, чтобы получить необходимые нам файлы. Щелкаем на ссылке Deselect all component, чтобы не закачивать лишнее, а затем выбираем только то, что нам потребуется – отмечаем чекбокс Sortable и видим, что вместе с ним отметились чекбоксы UI Core и Draggable. Работа плагина Sortable зависит от них, поэтому они необходимы.
    Кроме этого, справа есть выпадающий список, где можно выбрать понравившуюся тему оформления. Если все готово, кликаем кнопку Download и получаем архив.

    Сначала в разделе HEAD подключаем несколько файлов, которые есть в архиве:

    <link type="text/css" href="css/sunny/jquery-ui-1.7.2.custom.css" rel="stylesheet" />
    <script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
    <script src="js/jquery-ui-1.7.2.custom.min.js" type="text/javascript"></script>

    Здесь мы подключили файл стилей css/sunny/jquery-ui-1.7.2.custom.css одной из многочисленных тем оформления. Хотите использовать Ваше собственное оформление – пожалуйста, но в примере мы используем готовое. Кроме этого мы подключили файл библиотеки – js/jquery-1.3.2.min.js и файл js/jquery-ui-1.7.2.custom.min.js, в котором объединена функциональность ядра UI и плагинов Sortable и Draggable.

    Смотрим HTML-разметку. Пусть у нас она будет выглядеть так:

    <ul id="sortable">
      <li class="ui-state-default">Item 1</li>
      <li class="ui-state-default">Item 2</li>
      <li class="ui-state-default">Item 3</li>
      <li class="ui-state-default">Item 4</li>
      <li class="ui-state-default">Item 5</li>
      <li class="ui-state-default">Item 6</li>
      <li class="ui-state-default">Item 7</li>
    </ul>

    и следующий javascript-код, который применит к выбранному элементу функциональность плагина Sortable.

    $(function(){
      $("#sortable").sortable();
    });

    Открыть пример в новом окне

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

    $(function(){
      $("#sortable").sortable({
      	placeholder: "ui-state-highlight",
      	opacity: 0.6
      });
    });

    Открыть пример в новом окне

    Опция placeholder передает плагину имя css-класса, который будет применен к той позиции, откуда элемент начал перемещение (или куда он может быть помещен), а опция opacity устанавливает прозрачность элемента во время перемещения. Значения остальных опций передаются плагину подобным образом.

    appendTo – по умолчанию эта опция имеет значение ‘parent’. В ней можно передать селектор jQuery или элемент, который будет использован в качестве контейнера для объекта, представляющего сортируемый элемент во время его перемещения.
    axis – в качестве значения используется строка. Доступные значения ‘x’ или ‘y’. По умолчанию установлено false. Если определить эту опцию, сортируемые элементы смогут перемещаться только по вертикали или горизонтали.
    cancel – в качестве значения используется селектор jQuery. Предотвращает сортировку, если она начинается на элементе, указанном в это опции. По умолчанию используется значение ‘:input,button’.
    connectWith – в качестве значения принимает селектор jQuery, где можно указать другой сортируемый список, в который можно будет перемещать сортируемые элементы, таким образом, что они станут частью другого сортируемого списка.
    containment – ограничивает перемещение внутри определенного элемента или области. В качестве значения может принимать селектор jQuery, элемент или строку. Примеры возможных значений: ‘parent’, ‘document’, ‘window’. По умолчанию – false.
    cursor – строка, определяющая вид курсора в процессе перемещения элемента. По умолчанию установлено значение ‘auto’.
    cursorAt – объект, который определяет положение указателя мыши во время перемещения элемента. Для задания координат используется комбинация одного или двух свойств из четырех возможных – ‘top’, ‘right’, ‘bottom’ и ‘left’. Например: {top: 10, left: 20} или {bottom: 5}. По умолчанию – false.
    delay – число, указанное в этой опции, определяет отсрочку начала перемещения элемента. Указывается в миллисекундах. Опция помогает предотвратить нежелательное перемещение элемента во время случайного щелчка мышью. По умолчанию используется значение 0.
    distance – число в пикселах, определяющее расстояние, которое должен пройти указатель мыши (с одновременно нажатой левой клавишей), чтобы начался процесс перемещения элемента. Опция помогает предотвратить нежелательное перемещение элемента во время случайного щелчка мышью. По умолчанию используется значение 1.
    dropOnEmpty – по умолчанию используется значение true. В этом случае, если один из связанных списков пустой, в него можно перемещать элементы из другого списка. Если установить значение false, эта возможность будет запрещена.
    grid – по умолчанию – false. Значением может быть массив из двух чисел, определяющий шаг сетки, по которой будет перемещаться сортируемый элемент. Например: grid: [20,20]
    handle – по умолчанию установлено значение false. В качестве значения можно указать селектор jQuery или элемент. В этом случае процесс сортировки можно будет начать только в том случае, если левая клавиша мыши нажата в момент нахождения указателя мыши над элементом, определенным в этой опции.
    helper – по умолчанию используется значение ‘original’. В этом случае, при сортировке, перемещаемый элемент представлен самим элементом. Другое возможное значение ‘clone’. В этом случае элемент при перемещении представлен своей копией.
    items – в качестве значения используется селектор jQuery. По умолчанию установлено значение ‘> *’. Опция определяет, какие элементы, являющиеся элементами-потомками того элемента, с которым связана функциональность плагина, могут быть сортируемыми.
    opacity – значение опции может изменяться от 0.01 до 1 и определяет прозрачность перемещаемого элемента. По умолчанию – false.
    placeholder – имя css-класса, который будет применен к той позиции, откуда элемент начал перемещение. Если значение опции не определено «пустая» позиция никак не оформляется.
    revert – по умолчанию используется значение false. Если использовать значение true, то при перемещении элемента, после того, как будет отпущена клавиша мыши, элемент переместится на свою новую позицию с использованием плавного анимационного эффекта.
    scroll – по умолчанию установлено значение true – при перемещении элемента к краю области просмотра, она автоматически прокручивается бесконечно. Если установить значение false, эта возможность будет запрещена.
    scrollSensitivity – число, определяющее расстояние в пикселах от края области просмотра, после которого она начинает прокручиваться. Расстояние определяется относительно указателя мыши, а не перемещаемого элемента. По умолчанию установлено значение 20.
    scrollSpeed – число, определяющее скорость, с которой прокручивается область просмотра при приближении указателя мыши к ее краю на расстояние определенное в опции scrollSensitivity. По умолчанию установлено значение 20.
    tolerance – по умолчанию эта опция имеет значение ‘intersect’. При этом элемент, перемещаемый во время сортировки должен перекрыть любой другой сортируемый элемент как минимум на 50%, чтобы тот «освободил» занимаемое место. Другое возможное значение – ‘pointer’. При этом над сортируемым элементом должен оказаться только указатель мыши.
    zIndex – число, которое определяет значение css-свойства z-index для элемента в момент его сортировки.

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

    $(function(){
      $("#sortable").sortable({
      	placeholder: "ui-state-highlight",
      	opacity: 0.6,
      	stop: function(event, ui) {
      	  alert(event.type);
      	}
      });
    });

    Открыть пример в новом окне

    Здесь мы использовали только опцию stop, в которой определили функцию, которая будет вызвана в момент окончания сортировки. Функция может принимать два аргумента. Первый аргумент – объект события, второй – специальный объект ui, в свойствах которого можно обнаружить разнообразную полезную информацию. Но в приведенном примере мы используем только свойство type объекта события, чтобы вывести в окне предупреждения название события, вызвавшего нашу функцию.

    А вот пример того, как можно использовать специальный объект ui:

    $(function(){
      $("#sortable").sortable({
        placeholder: "ui-state-highlight",
        opacity: 0.6,
        helper: "clone",
        change: function(event, ui) {
          ui.helper.css("color","#f00");
        }
      });
    });

    Открыть пример в новом окне

    Мы использовали опцию change, чтобы вызвать функцию в момент изменения положения сортируемого элемента. Внутри функции мы обращаемся к одному из свойств объекта ui – к свойству helper. Это свойство является объектом, который представляет перемещаемый элемент во время сортировки. Используя метод css(name,value) мы устанавливаем красный цвет шрифта на перемещаемом элементе. Но, как только этот элемент займет свое новое место в списке, цвет шрифта вернется к исходному значению. Догадались почему? Если нет, то обратите внимание на опцию helper. Установив значение clone в этой опции, мы использовали во время перемещения не сам исходный объект, а его копию.
    Кстати, helper – это не единственное полезное свойство объекта ui, есть и другие:

    ui.helper – объект, характеризующий элемент, находящийся в процессе перемещения;
    ui.position – объект, в свойствах top и left которого содержится информация о положении перемещаемого элемента относительно родительского элемента;
    ui.offset – объект, в свойствах top и left которого содержится информация об абсолютном положении перемещаемого элемента;
    ui.item – объект, представляющий сортируемый элемент;
    ui.placeholder – объект, представляющий место, откуда был перемещен сортируемый элемент (или куда он будет перемещен);
    ui.sender – объект, который представляет элемент-контейнер для сортируемых элементов, откуда сортируемый элемент был перемещен (при использовании связанных списков);

    Ниже перечислены опции, связанные с событиями плагина Sortable, их довольно много:
    Опция start – событие sortstart наступает в момент начала сортировки.
    Опция sort – событие sort наступает постоянно в течение сортировки.
    Опция change – событие sortchange наступает во время сортировки, но только в том случае, если изменилось положение сортируемого элемента в объектной модели документа.
    Опция beforeStop – событие sortbeforeStop наступает в момент сортировки, перед ее окончанием (когда отпущена левая клавиша мыши).
    Опция stop – событие sortstop наступает в момент окончания сортировки.
    Опция update – событие sortupdate наступает в момент окончания сортировки, но только в том случае, если порядок сортируемых элементов был изменен.
    Опция receive – событие sortreceive наступает, когда связанный сортируемый список принимает элемент из другого списка.
    Опция remove – событие sortremove наступает, когда элемент покидает один связанный список, и перемещается в другой.
    Опция over – событие sortover наступает, когда сортируемый элемент перемещен в связанный список.
    Опция out – событие sortout наступает, когда сортируемый элемент перемещен из связанного списка.
    Опция activate – событие sortactivate наступает при использовании связанных списков, для каждого связанного списка при начале процесса сортировки.
    Опция deactivate – событие sortdeactivate наступает при использовании связанных списков, для каждого связанного списка при окончании процесса сортировки.

    А теперь – методы плагина. С помощью методов можно управлять плагином после инициализации. Сначала добавим кнопочку в HTML-разметку:

    <button id="cancelSort">Cancel Sort</button>

    и небольшой пример:

    $(function(){
      $("#sortable").sortable({
      	placeholder: "ui-state-highlight",
      	opacity: 0.6
      });
      $("#cancelSort").click(function(){
      	$("#sortable").sortable("cancel");
      });
    });

    Открыть пример в новом окне

    Метод .sortable(«cancel») использованный в примере, один из самых полезных методов плагина. Он позволяет отменить результат последней операции сортировки и вернуть элементы к предшествующему состоянию.
    Обратите внимание на элемент button с идентификатором #cancelSort. С кнопкой связан обработчик события click, по которому и вызывается метод соответствующий метод.
    Если Вы попробуете переместить один из элементов с писка на новое место, а затем нажать на кнопку cancelSort, список вернется в предыдущее состояние.

    Но конечно, этот метод не единственный. Вот другие:
    destroy – .sortable(‘destroy’) полностью удаляет всю функциональность плагина Sortable. Возвращает элементы в состояние, предшествующее инициализации.
    disable – .sortable(‘disable’) временно запрещает использование всей функциональности плагина. Вновь разрешить ее использование можно с помощью метода enable.
    enable – .sortable(‘enable’) разрешает использование всей функциональности плагина, если ранее она была запрещена с использованием метода disable.
    option – .sortable(‘option’, optionName, [value]) с помощью этого метода можно получить или установить значение любой опции плагина после инициализации.
    serialize – .sortable(’serialize’, [option]) упорядочивает значение атрибутов id элементов сортируемого списка в строку, которую можно передать на сервер с помощью ajax-запроса. Предъявляет требования к формату записи значения атрибута id. Допустимые форматы: id=’name_number’ или id=’name-number’. В этом случае вид строки получается ‘name[]=number& name[]=number’. Вторым, необязательным параметром, можно передать объект. Возможные значения: ‘key’ – заменит часть ‘name[]‘ на необходимую Вам, ‘attribute’ – попробует получить значения из атрибута, отличного от id, ‘expression’ – можно использовать свое регулярное выражение.
    toArray – .sortable(‘toArray’) упорядочивает значение атрибутов id элементов сортируемого списка в массив.
    cancel – .sortable(‘cancel’) отменяет результат последней операции сортировки и возвращает элемент в состояние, предшествующее этой операции. Метод полезен при использовании в callback-функциях, связанных с событиями stop или receive.

    Ну, и «на сладкое» – конечно обязательно надо дать пример использования связанных списков.

    $(function(){
      $("#sortable1, #sortable2").sortable({
      	connectWith: ".connectedSortable",
      	tolerance: "pointer"
      });
    });

    Открыть пример в новом окне

    Я привел пример только javascript-кода, поскольку в HTML-коде страницы ничего особенного нет – просто два ненумерованных списка #sortable1 и #sortable2. С помощью javascript-кода мы сделаем их сортируемыми, указав их идентификаторы в селекторе jQuery и связав с ними функциональность Sortable. Самое главное заключается в использовании опции connectWith. Здесь мы указываем имя класса для того списка, который хотим сделать связанным с другим списком.
    Обратите внимание, что атрибут class со значением connectedSortable мы присвоили обоим спискам и добились того, что элементы могут перемещаться не только из первого списка во второй, но и наоборот. Если бы мы захотели организовать только «одностороннее движение», скажем из первого списка во второй, мы бы присвоили класс connectedSortable только второму списку.

    Теперь сортируемые элементы можно переносить из одного списка в другой и элемент, перемещенный из одного списка в другой, становится частью другого списка.

    Все примеры, использованные в статье, можно совершенно запросто получить в этом архиве.

    Источник: http://www.linkexchanger.su/2009/111.html

    Нет комментариев

    25

    May

    jqGrid Часть I: Знакомство

    Опубликовал admin  Рубрика JavaScript, Общее, Программирование, Языки

    - Не робейте -, сказала Черная Королева, – это всего-навсего баранья нога, ни больше ни меньше.
    Она вам понравится, уверяю вас.
    Познакомьтесь. Алиса, это Баранья Нога.
    Баранья Нога, это Алиса.

    Предисловие

    Весь цикл статей направлен в первую очередь на начинающих разработчиков, которые постигают все прелести jQuery. Которые имеют базовые знания и понимания работы с этой библиотекой. Для разработчиков, которые впервые слышат слово jQuery я бы посоветовал цикл видео уроков Евгений Попова (Уроки 1-4 и Уроки 5-6) или книгу Геннадия Самкова jQuery. Сборник рецептов.

    Во всех статьях, я постараюсь максимально подробно охватить материал, чтобы исключить появление примитивных вопросов. Также хочется сразу предупредить, я не буду учить вас программированию на PHP, этот материал как и весь ресурс посвящен в первую очередь jQuery и технологиям AJAX. Поэтому пожалйста не задавайте вопросы «как мне защититься от хакеров?», «как мне сделать авторизацию?» и т.п., на эту тему вы всегда сможете найти массу материала на дружественных сайтах.

    Введение

    Любой набор данных можно представить в виде двумерного массива – таблицы. Я считаю таблицу одним из фундаментальных элементов представления информации. Благодаря такой структуре организации человек может увидеть, оценить и легко манипулировать данными в такой форме.

    В данном цикле статей я постараюсь познакомить вас и вместе с вами сам постигнуть все прелести замечательнейшего плагина для jQuery – jqGrid. Чтобы дать вам почувствовать этого «монстра», да-да именно «монстра», я приведу ссылку на демо-галерею сайта разработчика. Рекомендую посмотреть все примеры работы с таблицей.

    Лично я, когда увидел «это» был шокирован и решил разобрать этот плагин. Но сразу же был разочарован, он не заработал! А перепроверив все еще раз я понял, что проблема не в плагине, а во мне. Вот еще одна причина, по которой я сел за этот цикл. Далее меня настигло еще одно разочарование, скрипт вызывал ошибку в IE и отказывался работать. Это было связанно с багом в коде плагина, которую устранили к версии 3.6.1 (На момент написания статьи, последняя версия была 3.6.2). Таким образом я «вляпался» в этот плагин. Уверен вы устали от моей пустой болтовни и следует перейти к делу.

    I. Подготовка к установке

    Перед началом любых работ нам необходимо заготовить «инструменты» и «материалы».
    Инструменты (которые использую я)

    • Apache/2.2.9
    • PHP/5.2.6
    • MySQL-server/5.0.51a-24

    Вобщем все стандартные пакеты в репозитории Debian. Если вы предпочитаете Windows, то я могу посоветовать вам Denwer
    Материалы

    • jQuery – скачать с официального сайта или подключить по ссылке Google http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js
    • jQueryUI CSS Framework (проще говоря тема для jQueryUI) – выбирайте и скачивате на официальном сайте
    • jqGrid Plugin – скачивайте с официального сайта. ВАЖНО! Выберите все модули, т.к. мы пока разбираемся и будем тестировать все возможности jqGrid! В дальнейшей работе, вы можете выбирать только те модули которые вам необходимы.

    II. Документ, в котором будет использоваться jqGrid
    Аннотация:

    • Весь материал, который начинается с этого момента я буду осваивать заново, поэтому все ответы на вопросы я буду искать вмести с вами.
    • Мы будем работать с кириллицей в кодировке UTF-8. Но я дам некоторые рекомендации при использовании плагина с кодировкой Windows-1251(CP1251) .

    1) Html – разметка
    Итак создадим документ с разметкой следующего вида:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Осваиваем jqGrid с Linkexchanger</title></head>
    <body>
    <table id="le_table"></table>
    <div id="le_tablePager"></div>
    </body>
    </html>

    Как видите самый незаурядный код чистой страницы, где <table id=»le_table»></table> это и есть таблица которую вы видели на демо, а <div id=»le_tablePager»></div> – это элемент таблицы, «статус бар» (status bar), о нем поговорим позже. Здесь следует сказать, что в качестве селектора таблицы лучше использовать именно атрибут ID, почему? Ответ на этот вопрос будет дан по мере изучения плагина.

    2) Html + CSS + JS
    Далее переходим к подключаем необходимые стили и скрипты. Для начала создадим на сервере, в рабочем каталоге следующую структуру.

    • css/ – в этом каталоге будут все *.css файлы и прочие файлы относящиеся к визуальному оформлению страницы.
    • js/ – в этом каталоге будут все *.js файлы

    Теперь по каждому каталогу подробнее:

    • css – в него следует положить
        «jqueryUI Theme» – каталог с темой оформления jQueryUI (например flick)
        ui.jqgrid.css – дополнительные стили jqGrid (находятся в скачанном в п.I архиве css/ui.jqgrid.css)
    • js – в него следует положить
        jQuery - библиотеку
        Каталог i18n – это каталог с локализациями плагина, проще говоря с «языками» (находятся в скачанном в п.I архиве js/i18n) . На этом этапе я остановлюсь подробнее, потому что тут дам обещанный совет по использованию плагина с кирилице кодировки CP1251. Если вы планируете использовать плагин в таких условиях, то вам необходимо в каталоге i18n найти и переконвертировать кодировку файла grid.locale-ru.js из UTF-8 в CP1251. Рассказ о том как это сделать выходит за рамки данной статьи. Также вы можете не загружать все языки, а выбрать только тот, который вам необходим.
        jquery.jqGrid.min.js – собственно сам плагин.

    Теперь следует перепроверить всю структуру каталога еще раз. Именно на этом этапе я допустил первую ошибку, упоминавшуюся во введении.

    • /css/
      • flick/
        • images/
        • …
        • jquery-ui-1.7.2.custom.css
      • ui.jqgrid.css
    • /js/
      • i18n/
        • grid.locale-ru.js
        • …
      • jquery-1.4.min.js
      • jquery.jqGrid.min.js

    Далее необходимо подключить всю эту кухню

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
    <meta http-equiv="Content-Type" content="text/html;
    charset=utf-8" />
    <title>Осваиваем jqGrid с Linkexchanger</title>
    <link rel="stylesheet" type="text/css" media="screen" href="css/flick/jquery-ui-1.7.2.custom.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" mce_href="css/ui.jqgrid.css" />
    <style>html, body {
        margin: 0;
        padding: 0;
        font-size: 80%;
    }
    </style>
    <script type="text/javascript" src="js/jquery-1.4.min.js"></script>
    <script type="text/javascript" src="js/i18n/grid.locale-ru.js"></script>
    <script type="text/javascript" src="js/jquery.jqgrid.min.js"></script>
    </head>
    <body>
    <table id="le_table"></table>
    <div id="le_tablePager"></div>
    </body>
    </html>

    Как видите в разметке есть еще дополнительный стиль. Этот стиль задает базовые параметры для отступов и самое главное размер шрифта! Если этого не сделать, то при использовании jQueryUI CSS Framework размер шрифта будет «не маленьким» и при этом различным в различных браузерах.

    3) MySQL
    Как бы мы не хотели, но в данной статье мы никак не сможем обойтись без базы данных. Поэтому я подготовил для вас дамп. Вы можете скачать его по этой ссылке или с моего домашнего сервера и экспортировать в любую БД (MySQL) например используя phpMyAdmin, у данного дампа есть один ньюанс. Аименно у некоторых названий городов «искаверкана» кодировка, т.е. проблема в дампе, но никак не в плагине!
    В дампе сохранены 10тыс городов с кодами страны, региона, названием на англ., долготой, широтой, и nbit. Фактически это кусок одной таблицы БД распределения IP адресов в интернете. В принципе нам абсолютно не важно, что это будет за БД и для опытов подойдет и такая.

    4) PHP
    На данном этапе следует создать PHP скрипт, который будет возвращать таблице, запрашиваемую ею информацию. Вот пример такого скрипта для наших нужд

    <?php
    // Подключение и выбор БД
    $db = mysql_connect('database_host', 'database_user',
    'database_password');
    mysql_select_db('database_name');
    # ВНИМАНИЕ!!!
    # Данный код не имеет проверок запрашиваемых данных
    # что может стать причиной взлома!
    # Обязательно проверяйте все данные
    # поступающие от клиента
    
    // Номер запришиваемой страницы
    $page = $_GET['page'];
    
    // Количество запрашиваемых записей
    $limit = $_GET['rows'];
    
    // Номер элемента массива по которому
    // следует производить сортировку
    // Проще говоря поле, по которому
    // следует производить сортировку 
    $sidx = $_GET['sidx'];                 
    
    // Направление сортировки
    $sord = $_GET['sord'];                         
    
    // Если не указано поле сортировки,
    // то производить сортировку по первому полю
    if(!$sidx) $sidx =1;                 
    
    // Выполним запрос, который
    // вернет суммарное кол-во записей в таблице
    $result = mysql_query("SELECT COUNT(*) AS count FROM cities");
    $row = mysql_fetch_array($result,MYSQL_ASSOC);
     // Теперь эта переменная хранит кол-во записей в таблице
    $count = $row['count'];                   
    
    // Рассчитаем сколько всего страниц займут данные в БД
    if( $count > 0 && $limit > 0) {
        $total_pages = ceil($count/$limit);
    } else {
        $total_pages = 0;
    }                   
    
    // Если по каким-то причинам клиент запросил
    if ($page > $total_pages) $page=$total_pages;                   
    
    // Рассчитываем стартовое значение для LIMIT запроса
    $start = $limit*$page - $limit;                   
    
    // Зашита от отрицательного значения
    if($start < 0) $start = 0;                   
    
    // Запрос выборки данных
    $query = "SELECT id, country_code, region_code, city, latitude,
    longitude, nbip FROM cities
    ORDER BY ".$sidx." ".$sord." LIMIT ".$start.", ".$limit;
    $result = mysql_query($query);                   
    
    // Начало xml разметки
    $s = "<?xml version='1.0' encoding='utf-8'?>";
    $s .=  "<rows>";
    $s .= "<page>".$page."</page>";
    $s .= "<total>".$total_pages."</total>";
    $s .= "<records>".$count."</records>";                   
    
    // Строки данных для таблицы
    // Не забудьте обернуть
    //текстовые данные в <![CDATA[]]>                   
    
    while($row = mysql_fetch_assoc($result)) {
      $s .= "<row id='". $row[id]."'>";
      $s .= "<cell><![CDATA[". $row[country_code]."]]></cell>";
      $s .= "<cell>". $row[region_code]."</cell>";
      $s .= "<cell><![CDATA[". $row[city]."]]></cell>";
      $s .= "<cell>". $row[latitude]."</cell>";
      $s .= "<cell>". $row[longitude]."</cell>";
      $s .= "<cell>". $row[nbip]."</cell>";
      $s .= "</row>";
    }
    $s .= "</rows>";                   
    
    // Перед выводом не забывайте выставить header
    // с типом контента и кодировкой
    header("Content-type: text/xml;charset=utf-8");                 
    
    echo $s;
    ?>

    5) Инициализация плагина
    Последний этап подготовительных работ. Здесь мы должны инициализировать плагин JqGrid. Делается это вызовом метода jqGrid(), который в качестве параметра, принимает объект со свойствами таблицы.
    Теперь давайте посмотрим на примере разметки, приведенной выше.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Осваиваем jqGrid с Linkexchanger</title>
    <link rel="stylesheet" type="text/css" media="screen" href="css/flick/jquery-ui-1.7.2.custom.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" mce_href="css/ui.jqgrid.css" />
    <style>html, body {
        margin: 0;
        padding: 0;
        font-size: 80%;
    }
    </style>
    <script type="text/javascript" src="js/jquery-1.4.min.js"></script>
    <script type="text/javascript" src="js/i18n/grid.locale-ru.js"></script>
    <script type="text/javascript" src="js/jquery.jqgrid.min.js"></script>
    <script type="text/javascript">
    $(function(){           
    
    $('#le_table').jqGrid({
       url:'p1e1.php',
       datatype: 'xml',
       mtype: 'GET',
       colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
       colModel :[
         {name:'country_code', index:'country_code', width:80},
         {name:'region_code', index:'region_code', width:80},
         {name:'city', index:'city', width:90},
         {name:'latitude', index:'latitude', width:60},
         {name:'longitude', index:'longitude', width:60},
         {name:'nbip', index:'nbip', width:30}],
      pager: $('#le_tablePager'),
      rowNum:10,
      rowList:[10,20,30,100],
      sortname: 'city',
      sortorder: 'asc'
    });           
    
    });
    </script>
    </head>
    <body>
    <table id="le_table></table>
    <div id="le_tablePager"></div>
    </body>
    </html>

    Cейчас можно взглянуть результаты наших трудов. Вот ссылка на просмотр ДЕМО1 и на архив с ДЕМО1 (тот же архив на зеркале)

    III. Разбор параметров
    Остался последний пункт сегодняшней статьи в котором я дам пояснения по каждому из используемых в данном примере свойств плагина.

    • url – этот параметр указывает URL на скрипт
    • datatype – тип возвращаемых сервером данных. В данном примере, плагин ожидает данные с сервера в виде XML. Забегая наперед скажу что в следующей статье мы рассмотрим ответ сервера в виде JSON и Offline варианты использования плагина.
    • mtype – определяет каким методом будут переданы данные серверу
    • colNames – массив с заголовками столбцов таблицы
    • colModel – параметр-массив, каждый элемент которого является объектом свойств столбца с данными
      • name – «имя колонки», используется внутренними механизмами jqGrid
      • index – «имя колонки», передается серверу при запросах данных
      • width – ширина столбца в пикселах
    • pager – определяет элемент, который будет преобразован в «панель-листалку». Может быть как строкой (‘#le_tablePager’) так и объектом jQuery ($(‘#le_tablePager’)). При этом сами разработчики рекомендуют присваивать этому параметру как раз объект jQuery.
    • rowNum – определяет количество записей запрашиваемых у сервера и отображаемых за «один раз» (я написал именно так, потому что jqGrid может динамически подгружать строки с данными, что будет рассмотрено в последующих статьях) по умолчанию.
    • rowList - параметр-массив. На основе этого параметра строится выпадающий список, позволяющий изменять кол-во записей выводимых за «один раз»
    • sortname – определяет index(столбец) по которому будут отсортированы записи
    • sortorder – определяет направление сортировки. asc – по возрастанию, desc – по убыванию.

    Говоря о параметрах (options) следует сказать, что это лишь крохотная их часть. Эти параметры обеспечивают только базовую функциональность таблице. Множество других параметров мы с вами рассмотрим в последующих статьях, а пока поэкспериментируйте с теми что использованы в этом примере.

    IV. Содержание следующей статьи

    • Другие способы загрузки данных
      • В виде JSON объекта
      • В виде массива
      • Конвертирование простой таблицы в jqGrid
    • Форматирование данных
      • Встроенные функции форматирования
      • Пользовательские функции форматирования
    • Дополнительные панели и панели инструментов
      • Панель-листалка
      • Панели инструментов
      • Пользовательская панель
      • Управление столбцами данных

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

    В ходе работы мы поняли принцип работы плагина. Фактически сам плагин это интерфейс пользователя, который отправляет AJAX запросы серверу и получает от него ответ. Таблица отправляет все необходимые параметры, для выборки данных на стороне сервера, в виде GET запроса, а сервер возвращает в виде набора строк в XML-разметке.

    Пожалуйста оставляйте только конструктивные комментария и пожелания, а все вопросы задавайте на форуме!

    Источник: http://www.linkexchanger.su/2010/118.html

    Нет комментариев

    February 2012
    M T W T F S S
    « Jan    
     12345
    6789101112
    13141516171819
    20212223242526
    272829  

    Ссылки

    Рубрики

    • Hardware (2)
      • Видеокарты (1)
    • Общее (12)
    • Программирование (9786)
      • Утилиты (5)
      • Языки (963)
        • JavaScript (9)
        • php (127)
          • cakePHP (2)
        • Ruby (821)

    Архивы

    • February 2012 (227)
    • January 2012 (830)
    • December 2011 (933)
    • November 2011 (779)
    • October 2011 (1169)
    • September 2011 (20)
    • August 2011 (22)
    • July 2011 (43)
    • June 2011 (30)
    • May 2011 (42)
    • April 2011 (46)
    • March 2011 (25)
    • February 2011 (53)
    • January 2011 (48)
    • December 2010 (39)
    • November 2010 (20)
    • October 2010 (718)
    • September 2010 (196)
    • August 2010 (655)
    • July 2010 (533)
    • June 2010 (607)
    • May 2010 (656)
    • April 2010 (696)
    • March 2010 (868)
    • February 2010 (542)

    Последние записи

    • Gigabyte отрицает слухи о предстоящем повышении цен на материнские платы
    • Gigabyte отрицает слухи о предстоящем повышении цен на материнские платы
    • Intel начала поставки процессоров Atom для серверного сегмента
    • Gigabyte отрицает слухи о предстоящем повышении цен на материнские платы
    • Intel начала поставки процессоров Atom для серверного сегмента
    • Gigabyte отрицает слухи о предстоящем повышении цен на материнские платы
    • Gigabyte отрицает слухи о предстоящем повышении цен на материнские платы
    • Elpida отчитывается об убытках и молчит о плане спасения
    • Gigabyte отрицает слухи о предстоящем повышении цен на материнские платы
    • Gigabyte отрицает слухи о предстоящем повышении цен на материнские платы

    Свежие комментарии

    • Комментариев нет
    • Случайные записи

      • Arctic выпускает кулер для Radeon HD 6990
      • Elpida отчитывается об убытках и молчит о плане спасения
      • Обзор и тестирование Sapphire Radeon HD 6950 Flex Edition
      • OpenNebula 3.2
      • Intel начинает поставки 25 нм твёрдотельной памяти
      • Учёные создали транзистор размером 9 нанометров
      • Информация о ценах процессоров Zambezi
    © 2008 Особое программирование
    Дизайн : Roam2Rome | Локализация шаблоны для wordpress и goodwin.wpbot.ru