Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
API Выбор города из выпадающего списка по начальным буквам (API+Ajax)
Работу примера можно увидеть здесьБольшинство API функций сервиса htmlweb.ru совершенно бесплатны. Идентификация нужна для исключения злоупотреблений и позволяет разделить количество запросов от разных пользователей. Ограничения на бесплатные запросы и тарификация описана здесь.
Для идентификации используется API_KEY из_профиля. API_KEY может быть передан как GET так и POST запросом.
Не размещайте ключ API_KEY в открытом доступе и в javascript.
Он фактически заменяет ваши логин пароль и дает возможность использовать весь функционал нашего сайта от вашего аккаунта, включая платные функции.
Ключи выбора формата:
- html - HTML-формат.
- json - JSON-формат
- xml - XML-формат
Для указания кодирования ответа в нужном вам формате добавьте в запрос параметр html или json или xml, например:
http://htmlweb.ru/geo/api.php?city=1711&html&charset=utf-8&api_key=xxxx
При возврате в формате JSON возврашается заголовок header('Access-Control-Allow-Origin: *') - разрешающий кроссдоменные запросы.
Ключ выбора кодировки charset=:
- windows-1251 по умолчанию всё отдается в кодировке utf-8
- utf-8 unicode - кодировка UTF-8. Пример: charset=utf-8
- а также другие: koi-8, ISO-8859-1, ISO-8859-15, cp866, cp1252, KOI8-R
fields
- какие поля включать в ответ, например:
http://htmlweb.ru/geo/api.php?city=1711&sql=pb_city&fields=id,name,english,area,rajon,country
Если Вам нужен другой формат или другая кодировка, а также обо всех найденных проблемах и пожеланиях сообщайте нам.
Структура API запроса для получения списка городов соответствующих шаблону:
http://htmlweb.ru/geo/api.php?html&city_name=НАЧАЛО_НАЗВАНИЯ_ГОРОДА&api_key=API_KEY_из_профиля
Структура API запроса для получения списка городов в json-формате, соответствующих шаблону:
http://htmlweb.ru/geo/api.php?json&city_name=НАЧАЛО_НАЗВАНИЯ_ГОРОДА&api_key=API_KEY_из_профиля
Структура API запроса для получения списка городов в option/select-формате для отображения выпадающего списка:
http://htmlweb.ru/geo/api.php?city_name=НАЧАЛО_НАЗВАНИЯ_ГОРОДА&api_key=API_KEY_из_профиля
Пример для города Москва с Вашим API_KEY:
Ответ для html:
<a href="/geo/country/RU/city/1"><b>Москва (Московская область,Домодедовский район)</b></a><br>
Ответ для option/select:
<option value='1'>Москва (Московская область,Домодедовский район)</option>
Ответ для json:
{"0": { "id": 1, "name": "Москва", "area": 1, "telcod": 495.499, "latitude": 55.7558, "longitude": 37.6176, "time_zone": 3, "tz": "", "english": "Moscow", "rajon": 3597, "sub_rajon": 0, "country": "RU", "sound": "M210", "level": 1, "iso": "MOW", "vid": 1, "post": 101000, "geonameid": null, "wiki": "ru.wikipedia.org/wiki/%D0%92%D0%BD%D1%83%D0%BA%D0%BE%D0%B2%D0%BE_(%D1%80%D0%B0%D0%B9%D0%BE%D0%BD_%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D1%8B)", "full_english": "Moscow (Moscow oblast, Domodedovskij rajon)", "full_name": "Москва (Московская область, Домодедовский район)" } }
Параметр limit
в ответе показывает количество оставшихся запросов до конца суток для бесплатных запросов или количество запросов до окончания тарифа при платных.
Ограничения на бесплатные запросы и тарификация описана здесь.
Как интегрировать готовый скрипт выбора города по начальным буквам себе на сайт?
Добавьте сайт, на котором Вы собираетесь разместить скрипт в Профиль->ограничить домены. В код страницы вставьте следующий HTML-код:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="Author" content="Kolesnikov D.G." />
<title>Выбор города из выпадающего списка по начальным буквам</title>
<script type="text/javascript" src="/geo/api.js" async></script>
<script type="text/javascript" src="/js.js" async></script>
</head>
<body style="max-width: 600px">
<h1>Выбор города из выпадающего списка по начальным буквам</h1>
<form method="get" action="/geo/city.php"
onsubmit="return CityChoice();">
<p style='font-size:15px;text-align: left'><b>Введите город:</b>
<input style='font-size:15px;width:450px' id="city" size="60"
placeholder="Начните вводить название"
onfocus="_geo.o_info=getObj('info');_geo.f_Choice=CityChoice;_geo.init(this);" />
</p>
</form>
<br>
<div id="info"></div>
<script type="text/javascript"><!--
function CityChoice(e){
//ajaxLoad(_geo.o_info, '/geo/api.php?city='+_geo.city_id);
updateObj(_geo.o_info, 'Выбран <b>'+_geo.city_name+'</b>, код: <b>'+_geo.city_id+'</b>');
return false;
}
//--></script>
</body>
</html>
Код скрипта api.js:
//"use strict"
var _geo={/* скрипт скачан с htmlweb.ru/geo/ */
city_name:"",
city_id:0,
timer:0,
x:-1,
y:0,
o_city:null, /* input, по умолчанию id='city' */
o_select:null,
o_info:null, /* div для вывода результата информации о городе, по умолчанию id='info'*/
f_Choice:null, /* функция, которая вызывается после выбора, по умолчанию 'CityChoce'*/
json:false,
//g=getObj('city').onkeyup=PressKey; // альтернативный вариант назначения обработчика
init:function(t){ /* t='id input-а' */
if(!_geo.o_info)_geo.o_info=getObj('info');
var e;
if(typeof(t)=='object')e=_geo.o_city=t;
else e=_geo.o_city=getObj((typeof(t)=='string'?t:'city'));
//console.log(e.id);
addEvent(e, 'keyup',_geo.PressKey);
e.setAttribute('autocomplete','off');
//t=t+'_select';
if(!_geo.o_select){
/* создаем селект
<select id="info_sel" size=5 style='visibility:hidden;position:absolute;z-index:999;'
onChange="getObj('city').value=city_name=this.options[this.selectedIndex].text;city_id=this.options[this.selectedIndex].value;"
onkeyup='PressKey2(event)' ondblclick='return CityChoce()'>
</select>*/
_geo.o_select=e=document.createElement('select');
//e.setAttribute('id',t);
e.setAttribute('size',5);
e.setAttribute('style','visibility:hidden;position:absolute;z-index:999;max-width:400px');
addEvent(e, 'change',function(){_geo.o_city.value=_geo.city_name=this.options[this.selectedIndex].text;_geo.city_id=this.options[this.selectedIndex].value;});
addEvent(e, 'keyup',_geo.PressKey2);
addEvent(_geo.o_select, 'dblclick', _geo.Choice);
document.body.appendChild(e);
}
//console.log(_geo.f_Choce);
_geo.x=-1; _geo.y=0; _geo.city_name="";
},
Choice:function(e){
if(!_geo.f_Choice)_geo.f_Choice=CityChoice;
_geo.f_Choice(e);
_geo.o_city.focus();
_geo.o_city.select();
_geo.o_select.style.visibility = 'hidden'; // спрячем select
},
PressKey2:function(e){ // вызывается при нажатии клавиши в select
e=e||window.event;
t=(window.event) ? window.event.srcElement : e.currentTarget; // объект для которого вызвано
if(e.keyCode==13){ // Enter
//_geo.o_city.form.onsubmit();
_geo.o_city.value=_geo.city_name=t.options[t.selectedIndex].text;_geo.city_id=t.options[t.selectedIndex].value;
_geo.Choice();
return;}
if(e.keyCode==38&&t.selectedIndex==0){ // Up
_geo.o_city.focus();
_geo.o_select.style.visibility = 'hidden'; // спрячем select
}
},
// Определение координаты элемента
pageX:function(elem) {
return elem.offsetParent ?
elem.offsetLeft + _geo.pageX( elem.offsetParent ) :
elem.offsetLeft;
},
pageY:function(elem) {
return elem.offsetParent ?
elem.offsetTop + _geo.pageY( elem.offsetParent ) :
elem.offsetTop;
},
PressKey:function(e){ /* вызывается при отпускании кнопки в input */
e=e||window.event;
t=(window.event) ? window.event.srcElement : e.currentTarget; // объект для которого вызвано
g=_geo.o_select;
if(_geo.x==-1&&_geo.y==0){// при первом обращении просчитываю координаты
_geo.x=_geo.pageX(t); _geo.y=_geo.pageY(t);
g.style.top = _geo.y + t.clientHeight+1 + "px";
g.style.left = _geo.x + "px";
}
if(e.keyCode==40){g.focus();g.selectedIndex=0;return;}
if(_geo.city_name==t.value)return; // если ничего не изменилось не "замучить" сервер
_geo.city_name=t.value;
if(_geo.timer){clearTimeout(_geo.timer);_geo.timer=0;}
if(_geo.city_name&&_geo.city_name.length<3){
g.style.visibility = 'hidden'; // спрячем select
return;
}
_geo.timer=window.setTimeout('_geo.Load()',1000); // загружаю через 1 секунду после последнего нажатия клавиши
},
Load:function(){
_geo.timer=0;
_geo.o_select.options.length=0;
ajaxLoad(_geo.o_select, '/geo/api.php?city_name='+_geo.city_name);
_geo.o_select.style.visibility='visible';
},
getGeo:function(p,f){ /* p=0 - по IP, p=1 по данным браузера с запросом пользователя, p=2 - точно по данным браузера с запросом пользователя и использованием GPS
f=html или f=json */
if(!p || !navigator.geolocation){
ajaxLoad(_geo.o_info, '/geo/api.php?ip'+(f?'&'+f:''),'Загрузка...','',
function (obj, ajaxObj, callback){
if(ajaxObj.readyState==4) updateObj(obj, ajaxObj.responseText);
hide('wait');
return false;
});
}else
if(navigator.geolocation) {
_geo.timer = setTimeout("_geo.geolocFail()", 10000);
navigator.geolocation.getCurrentPosition(function(position) {
clearTimeout(_geo.timer); _geo.timer=0;
//updateObj(_geo.o_info, "latitude (широта): <b>" + position.coords.latitude + "</b> , longitude (долгота): <b>" + position.coords.longitude + "</b>");
ajaxLoad(_geo.o_info, '/api/geo/city_coming?latitude='+position.coords.latitude+'&longitude='+position.coords.longitude+'&perpage=1'+(f?'&'+f:''),'Загрузка...','',
function (obj, ajaxObj, callback){
if(ajaxObj.readyState==4) updateObj(obj, ajaxObj.responseText);
hide('wait');
return false;
}
);
}, function(error) {
clearTimeout(_geo.timer); _geo.timer=0;
_geo.geolocFail(error);
},
{
maximumAge:100000,
timeout:10000,
enableHighAccuracy:!!(p==2)
});
} else {
_geo.geolocFail();
}
},
geolocFail:function(e){
if(typeof(e)=='object'){
switch (e.code) {
case e.PERMISSION_DENIED:
updateObj(_geo.o_info, "Посетитель не дал доступ к сведениям о местоположении", true);
break;
case e.POSITION_UNAVAILABLE:
updateObj(_geo.o_info, "Невозможно получить сведения о местоположении", true);
break;
case e.TIMEOUT:
updateObj(_geo.o_info, "Истёк таймаут, в течение которого должны быть получены данные о местоположении", true);
break;
default:
updateObj(_geo.o_info, "Возникла ошибка '" + e.message + "' с кодом " + e.code, true);
}
}else{
updateObj(_geo.o_info, "Ваш браузер не поддерживает гео-локацию", true);
}
}
};
/* дальше идут общие функции */
if(0){
function getObj(objID){
if (document.getElementById) {return document.getElementById(objID);}
else if (document.all) {return document.all[objID];}
else if (document.layers) {return document.layers[objID];}
return'';
}
function ajaxLoad(obj,url,defMessage,post,callback){
var ajaxObj;
if(typeof(obj)!="object")obj=document.getElementById(obj);
if(defMessage&&obj)obj.innerHTML=defMessage;
if(window.XMLHttpRequest){
ajaxObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
ajaxObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
return false;
}
ajaxObj.open ((post?'POST':'GET'), url);
if(post&&ajaxObj.setRequestHeader){
if(post=='chat'){ajaxObj.chat=true;post='';}
else ajaxObj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8;");
}
ajaxObj.setRequestHeader("Referer", window.location.href);
ajaxObj.onreadystatechange = ajaxCallBack(obj,ajaxObj,(callback?callback:null));
ajaxObj.send(post);
return false;
}
if (!window.getComputedStyle) { // борьба с IE
window.getComputedStyle = function(el, pseudo) {
this.el = el;
this.getPropertyValue = function (prop) {
var re = /(\-([a-z]){1})/g;
if (prop == "float") prop = "styleFloat";
if (re.test(prop)) {
prop = prop.replace(re, function () {
return arguments[2].toUpperCase();
});
}
return el.currentStyle[prop] ? el.currentStyle[prop] : null;
};
return this;
}
}
function updateObj(obj, data, bold, blink){
if(bold)data=data.bold();
if(blink)data=data.blink();
if(typeof(obj)!="object")obj=document.getElementById(obj);
o=obj;
do{ if(o.style){c=window.getComputedStyle(o, null);
if(c.display!="block"&&c.display!="inline"&&c.display.substr(0,5)!="table"){o.style.display=(o.tagName=="DIV"?"block":"inline");}
}
o=o.parentNode;
}while(o);
ajaxEval(obj, data);
}
function ajaxEval(obj, data){
if(obj.tagName=='INPUT'||obj.tagName=='TEXTAREA'){
if(obj.value!=data){
obj.value=data;
if(obj.onchange!=null)obj.onchange(obj);
}
}else if(obj.tagName=='SELECT'){
if(typeof(data)=='number' || data.indexOf('<')<0){ // это value
for(i=0;i<obj.options.length;i++)
if(obj.options[i].value==data){obj.options[i].selected=true;break;}
}else{
obj.options.length = 0;
var re=new RegExp ("<option[^<]+</option>","img");
data=data.match(re);
if(data){
for(i=0;i<data.length;i++){
var re0 = new RegExp ("value=[\'\"]([^\'\"]+)[\'\"]?","i"); value=re0.exec(data[i]); value= value==null? '' : value[1];
if(!value){var re0 = new RegExp ("value=([^<>]+)","i"); value=re0.exec(data[i]); value= value==null? '' : value[1];}
var re1=new RegExp ("<option[^>]+>([^<]+)</option>","i"); text=re1.exec(data[i]); text= text==null? null : text[1];
var re4 = new RegExp ("class=[\'\"]([^\'\"]+)[\'\"]","i"); defclass=re4.exec(data[i]);
j=obj.options.length;
if (text !=null){
var re2 = /selected/i; defSelected=re2.test(data[i]);
obj.options[j] = new Option(text, value,defSelected,defSelected);
var re3 = /disabled/i; if(re3.test(data[i]))obj.options[j].disabled=true;
if(defclass!=null) obj.options[j].className=defclass[1];
}else obj.options[j] = new Option('ОШИБКА!', '' );
}
}}
}else if(typeof(data)=='object' && obj.tagName=='A'){
//console.log('data=',data, ', obj=',obj);
for(k in data){
//console.log(obj,'[',k, '] =',data[k]);
if(k=='innerHTML')obj.innerHTML=data[k];
else obj.setAttribute(k, data[k]);
}
}else obj.innerHTML = data;
}
function ajaxJson(obj, data){
if(!data)return;
ajaxObj=eval("(" + data + ")");
if(obj.tagName!="FORM"&&obj.form)obj=obj.form;
if(obj.tagName!="FORM"){
ajaxEval(obj, ajaxObj);
return;
}
for(key in ajaxObj){
o=obj[key];
if(typeof(ajaxObj[key])=='object'){
if(typeof(o)=='object' && o.tagName=='SELECT'){
o.options.length = 0; j=0;
s=ajaxObj[key];
for(k in s){
m=s[k];
if(typeof(m)=='object'){
if(typeof(m['selected'])=='undefined')m['selected']=false;
if(typeof(m['value'])=='undefined')m['value']=k;
o.options[j++] = new Option(m['text'], m['value'] ,m['selected'],m['selected']);
for(var k1 in m)if(k1!='text'&&k1!='value'&&k1!='selected')o.options[j-1].setAttribute(k1,m[k1]);
}else{
o.options[j++] = new Option(m, k,false,false);
}
}
}else{
s=(typeof(o)=='undefined'?document.createElement("input"):o);
s.setAttribute('name', key);
s.setAttribute('type', 'hidden');/*по умолчанию скрытый*/
if(typeof(o)=='undefined')obj.appendChild(s);
o=ajaxObj[key];
for(k in o)s.setAttribute(k, o[k]);
}
}else if(typeof(o)!='undefined'&&typeof(o)!='null'){
ajaxEval(o, ajaxObj[key]);
}else if((pos=key.indexOf('.'))>0){ // имя.атрибут=значение
o=key.substr(0,pos);
o=obj[o];
if(typeof(o)!='undefined'&&typeof(o)!='null'){
s=key.substr(pos+1);
if(s=='disabled')o.disabled=ajaxObj[key];
else if(s=='value'&&o.tagName=='SELECT'){
o.options.length = 0;
t=ajaxObj[key]; s='';
if(o.name.substr(o.name.length-3,3)=='_cs'){
s=eval('o.form.'+o.name.substr(0,o.name.length-3));
if(s)t=s.value;
}
o.options[0] = new Option(t, ajaxObj[key],true,true);
if(s)if(o1=s.getAttribute('after'))eval(o1);
}else o.setAttribute(s, ajaxObj[key]);
}
}else if(o=getObj(key))ajaxEval(o,ajaxObj[key]);
}
if(obj.style)obj.style.display='block';
}
function ajaxCallBack(obj, ajaxObj, callback){
return function(){
if(ajaxObj.readyState==4){
if(callback) if(!callback(obj,ajaxObj))return;
if (ajaxObj.status==200){
//console.log(ajaxObj.responseText);
if(ajaxObj.getResponseHeader("Content-Type").indexOf("application/x-javascript")>=0){
eval(ajaxObj.responseText.replace(/\n/g,";").replace(/\r/g,""));
}else if(ajaxObj.getResponseHeader("Content-Type").indexOf('json')>=0){
ajaxJson(obj,ajaxObj.responseText);
}else updateObj(obj, ajaxObj.responseText);
}
else updateObj(obj, ajaxObj.status+' '+ajaxObj.statusText,1,1);
}
else if(ajaxObj.readyState==3&&ajaxObj.chat)obj.innerHTML=ajaxObj.responseText;
}
}
var addEvent = (function(){
if (document.addEventListener){
return function(obj, type, fn, useCapture){
if(!obj)console.error(obj, type, fn, useCapture);
if(typeof(obj)!="object")obj=document.getElementById(obj);
//console.log("addEvent:",obj,fn);
if(obj)obj.addEventListener(type, fn, useCapture);
}
} else if (document.attachEvent){ // для Internet Explorer
return function(obj, type, fn, useCapture){
if(typeof(obj)!="object")obj=document.getElementById(obj);
obj.attachEvent("on"+type, fn);
}
} else {
return function(obj, type, fn, useCapture){
if(typeof(obj)!="object")obj=document.getElementById(obj);
obj["on"+type] = fn;
}
}
})();
function removeEvent(obj, eventType, handler)
{ if(obj&&typeof(obj)!="object")obj=document.getElementById(obj);
return (obj.detachEvent ? obj.detachEvent("on" + eventType, handler) : ((obj.removeEventListener) ? obj.removeEventListener(eventType, handler, false) : null));
}
function getEventTarget(e) {
e = e || window.event;
var target=e.target || e.srcElement;
if(typeof target == "undefined")return e; // передали this, а не event
if (target.nodeType==3) target=target.parentNode;// боремся с Safari
return target;
}
}
Пример выбора города с использованием универсального скрипта выпадающих подсказок
В данном примере используется скрипт выпадающих подсказок autoComplete. Если Вы используете этот или аналогичный скрипт в других полях, то вам удобнее использовать его и для данного выбора. Так же в нем используется API htmlweb.ru
Код скрипта:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="Author" content="Kolesnikov D.G.">
<title>Выбор города из выпадающего списка по начальным буквам</title>
<link rel="stylesheet" href="/load/auto-complete.css" type="text/css">
<script type="text/javascript" src="/load/auto-complete.min.js"></script>
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, shrink-to-fit=no, target-densitydpi=medium-dpi" name="viewport">
</head>
<body style="box-sizing: border-box; width: 100vw; max-width: 600px; margin: 0; padding: 8px; font-family: 'Arial', sans-serif; font-size: 15px;">
<h1>Выбор города из выпадающего списка по начальным буквам</h1>
<form method="get" action="#" onsubmit="return false;">
<label style="line-height: 2;">
<b>Введите город:</b>
<input name="city2" style="font-size: 15px; width: 360px; max-width: 100%; box-sizing: border-box;" placeholder="Начните вводить название" value="" autocomplete="off">
</label>
</form>
<br>
<div id="err"></div>
<div id="info"></div>
<script type="text/javascript">
new autoComplete({
selector: 'input[name="city2"]',
minChars: 2,
delay: 500,
source: function(term, response){
console.log('Ищем ',term);
fetch('https://htmlweb.ru/json/geo/city_list?format=list&q='+encodeURIComponent(term)
/* +'&api_key= взять здесь: https://htmlweb.ru/user/#allowDomain' */)
.then(
function(data){ // обрабатываем ответ от сервера
if (data.status !== 200) {
return Promise.reject(new Error(data.statusText));
}
return data.json(); // раскодируем json в объект
})
.then(
function(data){
console.log('data:',data);
if(data.limit)document.getElementById('err').innerHTML='Осталось '+data.limit+' запросов';
if(data.error)document.getElementById('err').innerHTML=data.error;
else if(data.message)document.getElementById('err').innerHTML=data.message;
if(data.items) response(data.items);
})
.catch(
function(error) {
console.error(error)
});
},
onSelect: function(event, term, item){
document.getElementById('info').innerHTML='Выбран: '+term;
}
}
);
</script>
<br><br><p>Скрипт скачан здесь: <a href="https://htmlweb.ru/geo/city_api_example.php#autoComplete">https://htmlweb.ru/geo/city_api_example.php</a>
</body>
</html>
Открыть пример, Открыть пример с регионом, пример выбор города с выбором района в городе скачать архив, скачать базу городов.
Параметры API метода получения списка городов по шаблону
Все актуальные параметры доступны по ссылке: https://htmlweb.ru/json/geo/city_list?help
Входные параметры:Необязательные:
https://htmlweb.ru/json/geo/city_list?format=list&fields=id%2Cfullname&q=Моск
.
Прокомментировать/Отблагодарить