dareficlma
Вторник, 17 Сентября 2013 г. 08:39 (
ссылка)
Сегодня, в день релиза нового jQuery плагина для сервиса КЛАДР в облаке, я хочу показать как можно быстро сделать форму для ввода адреса с автодополнением и валидацией.
Для нетерпеливых: исходный код формы можно посмотреть на гитхабе. Для запуска примера вам достаточно скачать его в zip и открыть страницу с примером в браузере.
Несколько слов о плагине и реализованных фичах:
Мы избавились от использования jquery.ui.autocomplete. Теперь плагин суммарно весит 13 Кбайт и не требует никаких дополнительных библиотек, кроме непосредственно jQuery.Плагин теперь состоит из 2 отдельных частей: библиотеки для выполнения запросов к сервису (гитхаб) и собственно самого плагина для автодополнения (гитхаб). Это даёт возможность в случае необходимости использовать их отдельно.В плагине для автодополнения мы постарались реализовать весь необходимый функционал: проверку корректности введенного адреса, ajax-крутилку.
Теперь после небольшого резюме нововведений предлагаю вернуться к форме. Начнём с подключения необходимых библиотек.
<link href="e;../jquery.kladr.min.css"e; rel="e;stylesheet"e;><link href="e;css/example5.css"e; rel="e;stylesheet"e;><script src="e;js/lib/jquery-1.10.2.min.js"e; type="e;text/javascript"e;></script><script src="e;../jquery.kladr.min.js"e; type="e;text/javascript"e;></script><script src="e;js/example5.js"e; type="e;text/javascript"e;></script>
Так как целью данного поста является не стилевое оформление форм сразу приведу код html и css
HTML<!DOCTYPE html><html> <head> <meta http-equiv="e;content-type"e; content="e;text/html; charset2=utf-8"e;> <title>Форма для ввода адреса</title> <link href="e;../jquery.kladr.min.css"e; rel="e;stylesheet"e;> <link href="e;css/example5.css"e; rel="e;stylesheet"e;> <script src="e;js/lib/jquery-1.10.2.min.js"e; type="e;text/javascript"e;></script> <script src="e;../jquery.kladr.min.js"e; type="e;text/javascript"e;></script> <script src="e;js/example5.js"e; type="e;text/javascript"e;></script> </head> <body> <form> <div class="e;field"e;> <label>Регион</label> <input type="e;text"e; name="e;region"e;> </div> <div class="e;field"e;> <label>Район</label> <input type="e;text"e; name="e;district"e;> </div> <div class="e;field"e;> <label>Город</label> <input type="e;text"e; name="e;city"e;> </div> <div class="e;field"e;> <label>Улица</label> <input type="e;text"e; name="e;street"e;> </div> <div class="e;field"e;> <label>Дом</label> <input type="e;text"e; name="e;building"e;> </div> <div class="e;tooltip"e; style="e;display: none;"e;><b></b><span></span></div> </form> </body></html>
CSSbody, input { color: #555; font-size: 13px; font-family: Helvetica, Arial, sans-serif;}form { width: 300px; margin: 40px auto 0; padding: 20px 20px 10px; border-radius: 5px; border: 1px solid #e1e1e8; background-color: #f7f7f9; box-shadow: rgba(0,0,0,0.075) 2px 3px 7px;}input, button { outline: none;}.field label { display: inline-block; width: 80px; vertical-align: middle;}.field { margin-bottom: 10px; padding: 0;}.field input { height: 2em; min-width: 196px; border-radius: 3px; border: 1px solid #d3d3d3; box-shadow: inset 0 1px 1px rgba(0,0,0,0.1); padding: 0 7px; color: #666;}.tooltip { position: absolute; top: 16px; left: 360px; width: 220px; color: #b94a48; padding: 8px 10px; border-radius: 5px; border: 1px solid #eed3d7; background-color: #f2dede; opacity: 0.8;}.tooltip b { position: absolute; display: block; left: -14px; width: 0; height: 0; color: transparent; border: 7px solid; border-right-color: #f2dede;}#kladr_autocomplete ul { border-radius: 4px; border-color: #d3d3d3; padding: 0; background-color: #fff;}#kladr_autocomplete li { padding: 6px 8px; border: none; border-bottom: 1px solid #ededed; background-color: transparent;}#kladr_autocomplete ul .active { border: none; border-bottom: 1px solid #f0f0f0; background-color: #f0f0f0; margin-top: -1px; padding-top: 7px;}#kladr_autocomplete ul li:first-child.active { padding-top: 6px; margin-top: 0;}#kladr_autocomplete li strong { color: #5499BB;}#kladr_autocomplete .spinner { background-image: url("e;../img/spinner.png"e;); width: 16px; height: 16px;}
В итоге у нас получается вот такая вот форма.
Осталось сделать автодополнение с валидацией.
Открываем example5.js.
Сохраняем токен, ключ и объекты, которыми будем манипулировать в виде переменных.
$(function() { var token = '51dfe5d42fb2b43e3300006e'; var key = '86a2c2a06f1b2451a87d05512cc2c3edfdf41969'; var region = $('[name="e;region"e;]'); var district = $('[name="e;district"e;]'); var city = $('[name="e;city"e;]'); var street = $('[name="e;street"e;]'); var building = $('[name="e;building"e;]');});
Теперь чтобы подключить автодополнение из сервиса, нам в простейшем варианте нужно написать следующее.
region.kladr({ token: token, key: key, type: $.kladr.type.region});district.kladr({ token: token, key: key, type: $.kladr.type.district});city.kladr({ token: token, key: key, type: $.kladr.type.city});street.kladr({ token: token, key: key, type: $.kladr.type.street});building.kladr({ token: token, key: key, type: $.kladr.type.building});
Для того чтобы автодополнение районов выполнялось из выбранного региона и т.д. задаём родительский объект для нижестоящих полей при выборе элемента в списке.
region.kladr({ select: function(obj) { region.parent().find('label').text(obj.type); district.kladr('parentType', $.kladr.type.region); district.kladr('parentId', obj.id); city.kladr('parentType', $.kladr.type.region); city.kladr('parentId', obj.id); }});district.kladr({ select: function(obj) { district.parent().find('label').text(obj.type); city.kladr('parentType', $.kladr.type.district); city.kladr('parentId', obj.id); }});city.kladr({ select: function(obj) { city.parent().find('label').text(obj.type); street.kladr('parentType', $.kladr.type.city); street.kladr('parentId', obj.id); building.kladr('parentType', $.kladr.type.city); building.kladr('parentId', obj.id); }});street.kladr({ select: function(obj) { street.parent().find('label').text(obj.type); building.kladr('parentType', $.kladr.type.street); building.kladr('parentId', obj.id); }});building.kladr({ select: function(obj) { building.parent().find('label').text(obj.type); }});
Сделаем проверку введенных данных (на случай если пользователь не будет выбирать название в списке, а введёт его вручную).
var tooltip = $('.tooltip');var ShowError = function(input, message){ tooltip.find('span').text(message); var inputOffset = input.offset(); var inputWidth = input.outerWidth(); var inputHeight = input.outerHeight(); var tooltipHeight = tooltip.outerHeight(); tooltip.css({ left: (inputOffset.left + inputWidth + 10) + 'px', top: (inputOffset.top + (inputHeight - tooltipHeight)/2 - 1) + 'px' }); tooltip.show();};region.kladr({ verify: true, check: function(obj) { if(obj){ region.parent().find('label').text(obj.type); district.kladr('parentType', $.kladr.type.region); district.kladr('parentId', obj.id); city.kladr('parentType', $.kladr.type.region); city.kladr('parentId', obj.id); } else { ShowError(region, 'Неверно введено название региона'); } }});district.kladr({ verify: true, check: function(obj) { if(obj){ district.parent().find('label').text(obj.type); city.kladr('parentType', $.kladr.type.district); city.kladr('parentId', obj.id); } else { ShowError(district, 'Неверно введено название района'); } }});city.kladr({ verify: true, check: function(obj) { if(obj){ city.parent().find('label').text(obj.type); street.kladr('parentType', $.kladr.type.city); street.kladr('parentId', obj.id); building.kladr('parentType', $.kladr.type.city); building.kladr('parentId', obj.id); } else { ShowError(city, 'Неверно введено название населённого пункта'); } }});street.kladr({ verify: true, check: function(obj) { if(obj){ street.parent().find('label').text(obj.type); building.kladr('parentType', $.kladr.type.street); building.kladr('parentId', obj.id); } else { ShowError(street, 'Неверно введено название улицы'); } }});
Ну и последний штрих: сделаем чтобы пункты в списке автодополнения регионов и районов форматировались в стиле «Московская обл.»
var LabelFormat = function( obj, query ){ var label = ''; var name = obj.name.toLowerCase(); query = query.toLowerCase(); var start = name.indexOf(query); start = start > 0 ? start : 0; if(query.length < obj.name.length){ label += obj.name.substr(0, start); label += '<strong>' + obj.name.substr(start, query.length) + '</strong>'; label += obj.name.substr(start+query.length, obj.name.length-query.length-start); } else { label += '<strong>' + obj.name + '</strong>'; } if(obj.typeShort){ label += ' ' + obj.typeShort + '.'; } return label;};region.kladr({ labelFormat: LabelFormat,});district.kladr({ labelFormat: LabelFormat,});
Вот и всё =)
Буду рад вашим вопросам и комментариям
Весь JS код$(function() { var token = '51dfe5d42fb2b43e3300006e'; var key = '86a2c2a06f1b2451a87d05512cc2c3edfdf41969'; var region = $('[name="e;region"e;]'); var district = $('[name="e;district"e;]'); var city = $('[name="e;city"e;]'); var street = $('[name="e;street"e;]'); var building = $('[name="e;building"e;]'); var tooltip = $('.tooltip'); var LabelFormat = function( obj, query ){ var label = ''; var name = obj.name.toLowerCase(); query = query.toLowerCase(); var start = name.indexOf(query); start = start > 0 ? start : 0; if(query.length < obj.name.length){ label += obj.name.substr(0, start); label += '<strong>' + obj.name.substr(start, query.length) + '</strong>'; label += obj.name.substr(start+query.length, obj.name.length-query.length-start); } else { label += '<strong>' + obj.name + '</strong>'; } if(obj.typeShort){ label += ' ' + obj.typeShort + '.'; } return label; }; var ShowError = function(input, message){ tooltip.find('span').text(message); var inputOffset = input.offset(); var inputWidth = input.outerWidth(); var inputHeight = input.outerHeight(); var tooltipHeight = tooltip.outerHeight(); tooltip.css({ left: (inputOffset.left + inputWidth + 10) + 'px', top: (inputOffset.top + (inputHeight - tooltipHeight)/2 - 1) + 'px' }); tooltip.show(); }; region.kladr({ token: token, key: key, type: $.kladr.type.region, labelFormat: LabelFormat, verify: true, select: function(obj) { region.parent().find('label').text(obj.type); district.kladr('parentType', $.kladr.type.region); district.kladr('parentId', obj.id); city.kladr('parentType', $.kladr.type.region); city.kladr('parentId', obj.id); }, check: function(obj) { if(obj){ region.parent().find('label').text(obj.type); district.kladr('parentType', $.kladr.type.region); district.kladr('parentId', obj.id); city.kladr('parentType', $.kladr.type.region); city.kladr('parentId', obj.id); } else { ShowError(region, 'Неверно введено название региона'); } } }); district.kladr({ token: token, key: key, type: $.kladr.type.district, labelFormat: LabelFormat, verify: true, select: function(obj) { district.parent().find('label').text(obj.type); city.kladr('parentType', $.kladr.type.district); city.kladr('parentId', obj.id); }, check: function(obj) { if(obj){ district.parent().find('label').text(obj.type); city.kladr('parentType', $.kladr.type.district); city.kladr('parentId', obj.id); } else { ShowError(district, 'Неверно введено название района'); } } }); city.kladr({ token: token, key: key, type: $.kladr.type.city, verify: true, select: function(obj) { city.parent().find('label').text(obj.type); street.kladr('parentType', $.kladr.type.city); street.kladr('parentId', obj.id); building.kladr('parentType', $.kladr.type.city); building.kladr('parentId', obj.id); }, check: function(obj) { if(obj){ city.parent().find('label').text(obj.type); street.kladr('parentType', $.kladr.type.city); street.kladr('parentId', obj.id); building.kladr('parentType', $.kladr.type.city); building.kladr('parentId', obj.id); } else { ShowError(city, 'Неверно введено название населённого пункта'); } } }); street.kladr({ token: token, key: key, type: $.kladr.type.street, select: function(obj) { street.parent().find('label').text(obj.type); building.kladr('parentType', $.kladr.type.street); building.kladr('parentId', obj.id); }, check: function(obj) { if(obj){ street.parent().find('label').text(obj.type); building.kladr('parentType', $.kladr.type.street); building.kladr('parentId', obj.id); } else { ShowError(street, 'Неверно введено название улицы'); } } }); building.kladr({ token: token, key: key, type: $.kladr.type.building, select: function(obj) { building.parent().find('label').text(obj.type); } });});
Источник: , получено с помощью rss-farm.ru
Читать далее...