Pull to refresh

ExtJS: контрол выбора локации

Reading time4 min
Views1.7K
Многие проекты на данный момент используют информацию о местонахождении своих клиентов. К таким относятся интернет-магазины, сайты знакомств, банковские операционные ресурсы и прочее. Именно об элементе указания такого рода информации и будет данная статья: Ext.ux.locationSelect реализованный в поле фреймворка ExtJS 2.
Маленькая демка поможет ответить на вопрос о необходимости вчитываться в дальнейшее.

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, необходимо «договориться» о протоколе общения его с сервером. Здесь имеется развилка:
  1. При выборе какой-либо одной части локации посредством комбобокса контрол «расчитывает» на один массив со значениями для следующего комбобокса в json-формате {rows: [{id: numeric, name: string}, ...]};
  2. При полной загрузке локации контролу необходимы массивы для двух последних комбобоксов единовременно в json-формате {rows: {region: [{id: numeric, name: string}, ...], city: [{id: numeric, name: string}, ...]}}.

Т. о. можно реализовать серверную часть каким угодно образом с одним лишь требованием — соответствие формату, указанному выше.

Ресурсы


Tags:
Hubs:
+17
Comments35

Articles

Change theme settings