Многие проекты на данный момент используют информацию о местонахождении своих клиентов. К таким относятся интернет-магазины, сайты знакомств, банковские операционные ресурсы и прочее. Именно об элементе указания такого рода информации и будет данная статья: Ext.ux.locationSelect реализованный в поле фреймворка ExtJS 2.
Маленькая демка поможет ответить на вопрос о необходимости вчитываться в дальнейшее.
Так сложилось исторически, что управляющим элементом по выбору локации (будем пользоваться этим словом для определения месторасположения, местонахождения и иного) является popup окно с некоторым количеством взаимосвязанных списков , позволяющих последовательно уточнять локацию часть за частью. Контрол в сумме удобен, малопротиворечив, но несколько устарел. Вот первые, бросающиеся в глаза, минусы решения:
В одном из проектов мне понадобилось обойти всё вышеперечисленное и ко всему прочему соблюсти следующее:
Использование, благодаря мастерству и прозорливости разработчиков ExtJS, практически ничем не отличается от использования стандартных компонент этого пакета — создать и применить Ext.ux.locationSelect также легко как и создать обычную панель.
Подключение реализуется в обычном порядке. Если ExtJS уже используется, то необходимо подключить только само расширение:
Ввиду того, что контрол расширяет Ext.form.FieldSet, то видеть себя он предполагает в поле Ext.FormPanel, однако это необязательное требование.
Таким образом включить контрол в форму можно простым добавлением его конфигурационного объекта в items формы:
Нестандартными конфигурационными полями являются:
Все остальные поля — наследие конфигурации суперкласса.
Существуют задачи когда необходимо позволить выбирать локацию и при этом начать выбор с той, что уже установлена — редактирование анкетных данных, оформление переезда и прочее.
Для этой цели контрол имеет метод loadLocation(), который принимает конфигурационный объект формата {country: integer, region: integer, city: integer}. При его вызове будет произведено обращение по url, указанном при создании, с передачей параметров локации. Если вернувшиеся данные соответствуют допустимому формату, то в соответствующие комбобоксы будут загружены списки с данными, а те части локации, которые были заданы в конфигурационном объекте будут выбраны.
Так как контрол подкачивает данные с помощью AJAX, необходимо «договориться» о протоколе общения его с сервером. Здесь имеется развилка:
Т. о. можно реализовать серверную часть каким угодно образом с одним лишь требованием — соответствие формату, указанному выше.
Маленькая демка поможет ответить на вопрос о необходимости вчитываться в дальнейшее.
Synopsis
Так сложилось исторически, что управляющим элементом по выбору локации (будем пользоваться этим словом для определения месторасположения, местонахождения и иного) является popup окно с некоторым количеством взаимосвязанных списков , позволяющих последовательно уточнять локацию часть за частью. Контрол в сумме удобен, малопротиворечив, но несколько устарел. Вот первые, бросающиеся в глаза, минусы решения:
- popup окно для донесения до посетителя всего контрола;
- отсутствие кеширования данных селектов;
- слабая расширяемость — любой функционал необходимо реализовывать самостоятельно.
Что необходимо получить
В одном из проектов мне понадобилось обойти всё вышеперечисленное и ко всему прочему соблюсти следующее:
- window based дизайн — ресурс интенсивно редактируется и интерфейс решено было сделать оконным;
- т. к. страница могла не перезагружаться при работе на ней часами, то вопрос кеширования данных стоит очень остро;
- необходимо не только позволять выбирать локации, но и верно отображать их, в такой, например, ситуации как редактирование, когда все селекты уже означены, а соответствующие списки в них уже загружены.
Контрол в действии
Использование, благодаря мастерству и прозорливости разработчиков ExtJS, практически ничем не отличается от использования стандартных компонент этого пакета — создать и применить Ext.ux.locationSelect также легко как и создать обычную панель.
Подключение
Подключение реализуется в обычном порядке. Если ExtJS уже используется, то необходимо подключить только само расширение:
<head> <script type="text/javascript" src="/lib/ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="/lib/ext/ext-all.js"></script> <script type="text/javascript" src="/lib/ext/ux/locationSelect.js"></script> <link href="/lib/ext/resources/css/ext-all.css" rel="stylesheet" type="text/css" /> </head>
для галочки:
используйте правильный DOCTYPE документа, часто многие нетривиальности можно решить раз и навсегда только начав работать в правильном режиме.
Конфигурирование и создание
Ввиду того, что контрол расширяет Ext.form.FieldSet, то видеть себя он предполагает в поле Ext.FormPanel, однако это необязательное требование.
важно:
подробнейшее описание API, конфигураций и немного примеров по каждому из контролов можно обнаружить в ExtJS API Documentation в соответствующей части дерева компонент, пакетов и классов.
Таким образом включить контрол в форму можно простым добавлением его конфигурационного объекта в items формы:
var myForm = new Ext.form.FormPanel({ items: [{ xtype: 'locationselect', url: '/someURL', prefix: 'some_location_', title: 'someFieldSetTitle', valueNotFoundText: 'Не важно', validator: function(){/*some js-code*/} autoHeight: true, cache: someCacheVar }] });
Нестандартными конфигурационными полями являются:
- url — адрес куда хранилища контрола будут обращаться за списками частей локаций (страны, регионы и города), по этому же адресу будет отправляться запрос на полную единовременную загрузку локации целиком. Например, Россия | Рязанская обл. | Рязань;
- prefix — префикс имен переменных в которых будут сохранены ID частей локации. Для случая выше при сабмите контрол «сгенерирует» и отправит на сервер переменные _some_location_country, _some_location_region, _some_location_city;
- valueNotFoundText — значение этого поля будет присвоено одноименному конфигурационному полю всех Ext.form.ComboBox контрола;
- validator — функция будет вызываться при событии выбора любой части локации и позволит обязать, например, к указанию локации полностью;
- cache — передаваемая по ссылке глобальная переменная, которая будет являться кешем-хранилищем всех подгружаемых контролом данных. Если создать несколько контролов, передав в их конструкторы одну и ту же кеш-переменную, то контролы будут использовать единый на всех кеш, тем самым экономя ресурсы. В случае, если параметр опущен, кеш для контрола будет локальным, определенным внутри.
о незаметном:
обратите внимание на символ подчеркивания в именах генерируемых по префиксу переменных. Дело в том, что комбобокс в ExtJS реализации состоит из двух полей ввода — одно из которых и отправляет значение при сабмите формы т.е. приходится генерировать два похожих имени для каждого комбобокса.
Все остальные поля — наследие конфигурации суперкласса.
Загрузка локации целиком
Существуют задачи когда необходимо позволить выбирать локацию и при этом начать выбор с той, что уже установлена — редактирование анкетных данных, оформление переезда и прочее.
Для этой цели контрол имеет метод loadLocation(), который принимает конфигурационный объект формата {country: integer, region: integer, city: integer}. При его вызове будет произведено обращение по url, указанном при создании, с передачей параметров локации. Если вернувшиеся данные соответствуют допустимому формату, то в соответствующие комбобоксы будут загружены списки с данными, а те части локации, которые были заданы в конфигурационном объекте будут выбраны.
Формат данных
Так как контрол подкачивает данные с помощью AJAX, необходимо «договориться» о протоколе общения его с сервером. Здесь имеется развилка:
- При выборе какой-либо одной части локации посредством комбобокса контрол «расчитывает» на один массив со значениями для следующего комбобокса в json-формате {rows: [{id: numeric, name: string}, ...]};
- При полной загрузке локации контролу необходимы массивы для двух последних комбобоксов единовременно в json-формате {rows: {region: [{id: numeric, name: string}, ...], city: [{id: numeric, name: string}, ...]}}.
Т. о. можно реализовать серверную часть каким угодно образом с одним лишь требованием — соответствие формату, указанному выше.