Аякс подбор города профиля

+63
5.15K
Сделаем аякс подбор города при регистрации и при редактировании профиля из геобазы. Также страна, регион и город всегда будут возвращаться методом getUser в массиве geo, поскольку всё хранится в профиле пользователя БД.
Демо тут.

Установка

1. Заливаем содержимое папки upload архива в корень и импортируем в БД geo.sql из него же.

2. Выполним запросы к БД:
  1. ALTER TABLE `cms_user_profiles` ADD INDEX ( `city` );
  2. ALTER TABLE `cms_user_profiles` ADD `geo` TEXT NOT NULL AFTER `city`;

Если вам это поле необходимо при регистрации

3. В файле com_registration.tpl вашего шаблона найти:
  1. 112 {if $cfg.ask_icq}
  2. <tr>
  3. <td valign="top" class=""><strong>ICQ:</strong></td>
  4. <td valign="top" class="">
  5. <input name="icq" type="text" class="text-input" id="icq" value="{$item.icq}" style="width:300px"/>
  6. </td>
  7. </tr>
  8. {/if}
После вставить:
  1. <tr>
  2. <td valign="top" class="">
  3. <div><strong>Город:</strong></div>
  4. <div><small>Выберите город из списка</small></div>
  5. </td>
  6. <td valign="top" class="">
  7. <input name="city" type="text" class="text-input" id="city" value="Введите первые символы" style="width:300px"/> <span class="regstar">*</span>
  8. <input name="city_int" type="hidden" class="text-input" id="city_int" value=""/>
  9. {literal}<script type="text/javascript">
  10. $(function () {
  11. $('#city').autocomplete({
  12. serviceUrl: '/cities.php',
  13. minChars: 1,
  14. deferRequestBy: 300,
  15. onSelect: function (value, data) {
  16. $('#city_int').val(data.id_city);
  17. $("#city").removeClass("bad_value");
  18. }
  19. });
  20. $("#city").focus(function(){
  21. if($(this).val()=='Введите первые символы')$(this).val('');
  22. });
  23. $("#city").blur(function(){
  24. if(!$('#city_int').val()){
  25. $(this).addClass("bad_value");
  26. $(this).val('Введите первые символы');
  27. }else $(this).removeClass("bad_value");
  28. });
  29. });
  30. </script>{/literal}
  31. {add_js file='includes/jquery/autocomplete/jquery.autocomplete.js'}
  32. {add_css file='includes/jquery/autocomplete/styles.css'}
  33. </td>
  34. </tr>
4. В файле /components/registration/frontend.php

Найти:
  1. 177 // День рождения
Перед вставить:
  1. $item['city_int'] = cmsCore::request('city_int', 'int', 0);
  2. $item['city'] = cmsCore::request('city', 'str', '');
  3. if(!$item['city_int']){cmsCore::addSessionMessage('Город необходимо выбрать из вариантов!', 'error');$errors = true;}
  4. else{
  5. $sql = "SELECT s.id_city, s.id_region, s.id_country, s.city_name_ru, r.region_name_ru, c.country_name_ru
  6. FROM cms_geo_cities s
  7. LEFT JOIN cms_geo_countries c ON s.id_country = c.id_country
  8. LEFT JOIN cms_geo_regions r ON s.id_region = r.id_region
  9. WHERE s.id_city={$item['city_int']}";
  10. $city = $inDB->query($sql);
  11. if($inDB->num_rows($city)){
  12. $city = $inDB->fetch_assoc($city);
  13. $item['city'] = $city['city_name_ru'];
  14. $item['geo'] = cmsCore::arrayToYaml($city);
  15. }else{cmsCore::addSessionMessage('Город необходимо выбрать из вариантов!', 'error');$errors = true;}
  16. }

В профиле

5. В файле com_users_edit_profile.tpl вашего шаблона

Найти:
  1. 53 <td valign="top">
  2. <input name="city" type="text" id="city" class="text-input" style="width:300px" value="{$usr.city|escape:'html'}"/>
  3. <script type="text/javascript">
  4. {$autocomplete_js}
  5. </script>
  6. </td>
Заменить:
  1. <td valign="top" class="">
  2. <input name="city" type="text" class="text-input" id="city" value="{$usr.city|escape:'html'}" style="width:300px"/>
  3. <input name="city_int" type="hidden" class="text-input" id="city_int" value="{$usr.geo.id_city}"/>
  4. {literal}<script type="text/javascript">
  5. $(function () {
  6. $('#city').autocomplete({
  7. serviceUrl: '/cities.php',
  8. minChars: 1,
  9. deferRequestBy: 300,
  10. onSelect: function (value, data) {
  11. $('#city_int').val(data.id_city);
  12. $("#city").removeClass("bad_value");
  13. }
  14. });
  15. $("#city").focus(function(){
  16. if($(this).val()=='Введите первые символы')$(this).val('');
  17. });
  18. $("#city").blur(function(){
  19. if(!$('#city_int').val()){
  20. $(this).addClass("bad_value");
  21. $(this).val('Введите первые символы');
  22. }else $(this).removeClass("bad_value");
  23. });
  24. });
  25. </script>{/literal}
  26. {add_js file='includes/jquery/autocomplete/jquery.autocomplete.js'}
  27. {add_css file='includes/jquery/autocomplete/styles.css'}
  28. </td>
6. В файле /components/users/model.php

Найти:
  1. 341 p.city, p.description, p.showmail, p.showbirth, p.showicq,
Заменить:
  1. p.city, p.geo, p.description, p.showmail, p.showbirth, p.showicq,
Найти:
  1. 368 $user['status_date'] = cmsCore::dateDiffNow($user['status_date']);
После вставить:
  1. $user['geo'] = cmsCore::yamlToArray($user['geo']);
7. В файле /components/users/frontend.php

Удалить:
  1. 219 $smarty->assign('autocomplete_js', $inPage->getAutocompleteJS('citysearch', 'city', false));
Удалить:
  1. 210 $inPage->initAutocomplete();
Найти:
  1. 238 if (mb_strlen($city)>25) { cmsCore::addSessionMessage($_LANG['LONG_CITY_NAME'], 'error'); $errors = true; }
Заменить:
  1. $city_int = cmsCore::request('city_int', 'int', 0);
  2. if(!$city_int){cmsCore::addSessionMessage('Город необходимо выбрать из вариантов!', 'error');$errors = true;}
  3. else{
  4. $sql = "SELECT s.id_city, s.id_region, s.id_country, s.city_name_ru, r.region_name_ru, c.country_name_ru
  5. FROM cms_geo_cities s
  6. LEFT JOIN cms_geo_countries c ON s.id_country = c.id_country
  7. LEFT JOIN cms_geo_regions r ON s.id_region = r.id_region
  8. WHERE s.id_city={$city_int}";
  9. $geo = $inDB->query($sql);
  10. if($inDB->num_rows($geo)){
  11. $geo = $inDB->fetch_assoc($geo);
  12. $city= $geo['city_name_ru'];
  13. $geo = cmsCore::arrayToYaml($geo);
  14. }else{cmsCore::addSessionMessage('Город необходимо выбрать из вариантов!', 'error');$errors = true;}
  15. }
Вот и всё!

Топ 3 ответов на популярные вопросы

Q: Плагином можно?
A: Нет

Q: Для 1.9 подойдёт?
A: Вряд ли

Q: Сделаете для 1.9?
A: Нет
Q: Ню пожалуйстя...
A: Нет
+2
lokanaft lokanaft 11 лет назад #
P.S.: Наверное это моя последняя публичная доработка этой версии, поскольку, к моему сожалению, для большей части комментирующих мои доработки, видимо вся мебель в доме тоже родственники. Если вы не согласны с моими доводами, идите сюда и кликните красную стрелочку, я хоть буду знать "who is what"...
+1
SJen SJen 11 лет назад #
это намек на то, что пора бы и карму немного поднять? - там как раз ничего не будет понятно. Просто молчаливые плюсы/минусы. А в комментах реально можно понять "who is who".
0
lokanaft lokanaft 11 лет назад #
Согласен, а то деревянные родственники печатать не умеют =D
0
Игорь Игорь 11 лет назад #
Установил Вашу доработку комменты в карму... доволен.. сейчас буду эту верстать.
0
Anton Anton 11 лет назад #
у меня почему-то не получилось ;( Введите первые символы НЕ ПРОПАДАЕТ при вводе своего города. может кто нибудь выложит видоизмененные файлы? спасибки!
0
Игорь Игорь 11 лет назад #
Супер... +++++
+4
Madmax Madmax 11 лет назад #
lokanaft , карма и рейтинг - зло, мы тебя и просто так ценим и уважаем!

Топ 3 ответов на популярные вопросы
Улыбнули )
0
lokanaft lokanaft 11 лет назад #
Погодите, ща люди начнут пытаться установить и снова понесётся в мозгу война вежливости и желания высказаться...
0
AndroS AndroS 11 лет назад #
Правильно ли я понял, что это для 1.10? Такие фишки нужно в коробку загонять
+1
st.Puh st.Puh 11 лет назад #
Мне ваши все доработки нравятся, главное нужное все.
0
AndroS AndroS 11 лет назад #
Тоже заметил данное явление :)
0
Крот Крот 11 лет назад #
лучше сделать плагином на USER_LOGIN и добавить в поле city базы (новое например)
0
Крот Крот 11 лет назад #
сам себе такую штуку планировал, а тут уже) молодца + в карму
0
Крот Крот 11 лет назад #
вопрос не в тему разработчикам - "тыкнул" плюс на пост, значение не поменялось, разве сложно сделать? всем будет удобнее)
0
lokanaft lokanaft 11 лет назад #
Даже если мы повесим на USER_BEFORE_REGISTER при регистрации, GET_USER при запросе данных, мы не сможем сохранить это при редактировании и убрать вызов другого комплитера.
0
st.Puh st.Puh 11 лет назад #
Что то сял не могу выполнить ругает красным вот
"Ошибка SQL-запрос:
ALTER TABLE `cms_geo_cities` ADD INDEX ( `city_name_ru` ) ;
Ответ MySQL:
#1072 - Key column 'city_name_ru' doesn't exist in table"
0
lokanaft lokanaft 11 лет назад #
Удалите таблицы geo, скачайте архив снова, импортируйте файл и проблем возникнуть не должно - я обновил дамп гео в архиве.
0
st.Puh st.Puh 11 лет назад #
Ну и я так пологаю раз нет етих таблиц потому и неработает все то где есть вывод юзера с горогом,например Люди Профиля и тд.
0
st.Puh st.Puh 11 лет назад #
удалил cms_geo_cities cms_geo_countries cms_geo_regions импортировал из обновленного архива,делаю запрос уже из двух строк и опять тоже ругает
"Ошибка SQL-запрос:
ALTER TABLE `cms_user_profiles` ADD `geo` TEXT NOT NULL AFTER `city` ;
Ответ MySQL:
#1060 - Duplicate column name 'geo'"
0
st.Puh st.Puh 11 лет назад #
Да забыл в реге уже выбор города есть чтото там подгружает и даже не кричит что поле не заполнено.а вот с етим запросом беда так как неработает все где есть вывод города
0
lokanaft lokanaft 11 лет назад #
#1060 - Duplicate column name 'geo' - это значит, что этот столбец уже есть - с прошлого раза остался.
Удалите из таблицы cms_user_profiles лишние дубли индексов city, раз вы несколько раз запросы выполняли. А так всё должно работать.
+2
alexbabo alexbabo 11 лет назад #
Супер.На коменты и минусы старайтесь не обрщать внимание.
0
lesterkey lesterkey 11 лет назад #
Отлично...
0
KS KS 11 лет назад #
+ !
+3
Soul Soul 11 лет назад #
плюсанул и здесь и в карму (пока не ставил, но все-таки плюсую по 3 причинам: 1. из 7 Ваших наработок ни одной комерческой; 2. понятный мануал по установкам; 3. быстрая реакция и исправления замечаний)
0
st.Puh st.Puh 11 лет назад #
Подскажите пожалуста что здесб лишнее где эти "дубли индексов city"
""
0
st.Puh st.Puh 11 лет назад #
Типа очистить таблицу city ?
0
lokanaft lokanaft 11 лет назад #
Это список столбцов, каждому из них можно назначить индекс. Индексы перечислены ниже и возможно у вас несколько с именем "city", надо оставить только один.
0
st.Puh st.Puh 11 лет назад #
Типа эти лишние
""
-1
lokanaft lokanaft 11 лет назад #
Да, оставьте только city
0
lezginka.ru lezginka.ru 11 лет назад #
+
0
Anonim Anonim 11 лет назад #
А почему вы бесплатно выкладываете такие мощные доработки? Тут, уже повелось так: изменяешь одну-две строчки системы - выкладываешь ПЛАТНЫЙ ХАК!
+1
Soul Soul 11 лет назад #
"Провокация?" :)
0
st.Puh st.Puh 11 лет назад #
Вот смотрите удалил индексы
""

вот даже пользователь зарегался где выбрал город и это есть в базе

Код вставленый в файл /components/users/frontend.php перепроверил пару раз зделал все верно да и в остальных файлах,а где есть вывод города те страницы не работают
""

Что уже делать незнаю
0
lokanaft lokanaft 11 лет назад #
У вас 404 ко всему, что связано с users. У вас случаем не ограничен доступ к этому пункту меню?
0
st.Puh st.Puh 11 лет назад #
У меня профили могут просматривать только зарегистрированные, а оддельно поле я даже не видел где скрыть.Но вот прикол взялса все повторит с самого начал и вроде все работает без внесения изменений в файл /components/users/frontend.php и города выбираются и редактируются и сохраняются
0
lokanaft lokanaft 11 лет назад #
Я зареган у вас как tester
0
st.Puh st.Puh 11 лет назад #
Да tester Тестер Иванович вы мне с форумом помогали
0
st.Puh st.Puh 11 лет назад #
С разрешенным просмотром профилей гостям тоже самое нет страниц с упоминания города.Может нормально без последнего пункта вашей инструкции,без него работает.
0
Игорь Игорь 11 лет назад #
У меня тоже самое работает без измнений фронтенда. при внесении изменений в последний - компонент юзеры умирает - чистый лист.
0
lokanaft lokanaft 11 лет назад #
Я поправил самый последний пункт, теперь должно быть нормально.
0
Игорь Игорь 11 лет назад #
Тоже все ОК.
0
st.Puh st.Puh 11 лет назад #
Спасибо огромное, теперь все работает нормально.
0
Def Def 11 лет назад #
сегодн еще не проверял. но вчера на андроиде не работала подгрузка городов
+3
picaboo picaboo 11 лет назад #
Спасибо за нужные доработки. Все ваши последние доработки, а особенно форум, тянут на отдельный релиз инстанта 1.10.1, может администрация рассмотрит их включение в дистрибутив, вроде бы после аудита безопасности будет еще релиз вскоре?
0
Anonim Anonim 11 лет назад #
Это было бы просто здорово!
+1
lokanaft lokanaft 11 лет назад #
Надеюсь администрация так не считает.
0
Fuze Fuze 11 лет назад #
Надеюсь администрация так не считает.
не нужно подобного в дистрибутиве?
0
lokanaft lokanaft 11 лет назад #
Лишь функционально, моё исполнение мягко говоря не очень ))
+1
Dost Dost 11 лет назад #
Достаточно посмотреть плюсики к каждой записи в Вашем блоге. Это тоже о многом говорит даже без слов. Спасибо.
+1
Марат Марат 11 лет назад #
+
хорошие наработки и адекватный человек с чувством юмора
Топ 3 ответов на популярные вопросы
Да и не обращайте вы внимания на эти минусы. Главное, делаете то, что вам нравится. И многим это нужно. А всем не угодить.
0
st.Puh st.Puh 11 лет назад #
Обнаружилась проблемка,теперь когда вошол в профил, что то изменил и хочеш сохранить, не дает пишет "Город необходимо выбрать из вариантов!" Получается чтоб что то изменить надо править то что хочеш и выбрать город,ну а так как страница перегрузила пока появилось сообщения то и презрении изменения исчезли и не каждый это заметит,вот и получиться что заходил чтоб ещо раз город ввести
+1
lokanaft lokanaft 11 лет назад #
Это сделано, чтобы у всех был выбран правильный город, а не: "г. Москва", "Мухогород замкадья", "Киев - Украина"
0
Петр Петр 11 лет назад #
Думал что у меня одного такая проблема.
Как это убрать? Если например уже выбран город, но хочешь отредактировать другие поля профиля, то приходится вводить город заново, хотя поле заполнено.
Если не заполняешь заново поле - город слетает все что ты отредактировал в профиле, что не есть хорошо. Как быть?
0
lokanaft lokanaft 11 лет назад #
Чёт там было. У себя поправил, тут забыл.
0
Петр Петр 11 лет назад #
глянь пожалуйста
0
Петр Петр 11 лет назад #
Глянь пожалуйстааа
+1
lokanaft lokanaft 11 лет назад #
Плагином скоро сделаю.
0
Miron Miron 11 лет назад #
Безумно полезная работа. Плюсую везде. Спасибо!
0
Андрей Андрей 11 лет назад #
а если хочется ввести свой город, такую возможность совсем нет возможности реализовать?
ведь геобаза не знает все деревень :)

и еще момент, есть возможность разработать трехуровневую систему (страна, область, город)
даже за какую нибудь приятную оплату?
Олег Васильевич я Олег Васильевич я 11 лет назад #
Комментарий удален
0
AndroS AndroS 11 лет назад #
Думаю, это можно сделать так:
Выбор города одним полем для ввода. При вводе также подсвечиваются города и области, если вашего города нет, то справа должен быть плюсик, щелкая по котором появляется форма для добавления населенного пункта (область, район, статус нас.пункта и т.д.). Далее этот населенный пункт отправляется на модерацию. Если он не проходит модерацию, то есть, не существует, то юзера в зависимости от настроек системы, нужно обязать ввести другой нас.пункт, ограничив его в использовании сайта.
+1
lokanaft lokanaft 11 лет назад #
Я сделал из трёхуровневой одноуровневую и в подсказках соответственно высвечивается область и страна, Россия по-умолчанию не высвечивается, но вы можете в файле, который лежит в корне поменять идентификатор главной страны вашего сайта, а также кол-во юзеров, проживающих в данном городе, чтобы он стал выделяться жирным.
Код PHP:
  1. //Идентификатор главной страны
  2. $id_main_country = 1;
  3. //Популярность в двух местах:
  4. $ress['popule'] > 10
0
lokanaft lokanaft 11 лет назад #
Вообще это сделано, дабы проще было найти своих соседей так сказать, а то если все начнут свои деревни вводить, будет каша. Для регионального сайта нет ничего сложного переделать базу, а можно и код для: Район->Улица->Дом например. Вплоть до квартиры =D
0
Артем Артем 11 лет назад #
Добавил на страницу регистрации поле город по этому примеру. Как реализовать такой же функционал у поля профессия? Создал в базе данных таблицу cms_users_professia с полями id и professia. Как изменить файл cities.php для выборки по базе и возврата результата?
0
Артем Артем 11 лет назад #
Всех приветствую! Люди, может кто сделать тоже самое для поля профессия? Готов отблагодарить на R... или Z...
0
mogulkhan mogulkhan 11 лет назад #
Здраствуйте отличная дороботка давно ждал, поставил но оказалось что не совсем то чего хотелось. Может кто подскажет как зделать из сея дороботки чтобы было в первом поле выбираешь страну, затем аяксом появляется второе поле где нужно выбрать область, регион. ну и затем появляется третье поле с выбором города, населенного пункта. без перезагрузки страницы. просто я поудалял всю базу оставил только нужное, ну ведь не все знают что надо писать к примеру "п. Зазеркаловка" а так с выбором легче было бы.
+1
EVV EVV 11 лет назад #
в базе выдает ошибку:

Код PHP:
  1. Ошибка
  2. SQL-запрос:
  3. /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
  4. Ответ MySQL: Документация
  5. #1231 - Variable 'character_set_client' can't be set to the value of 'NULL'
0
БИБАБО БИБАБО 11 лет назад #
У меня тоже самое....
Импорт через Sypex Dumper и через phpmyadmin пробывал ни в какую не хочет ...
У кого получилось, чем импорт делали?)
0
Петр Петр 11 лет назад #
три последние строчки удалите из запроса
0
AlLar AlLar 11 лет назад #
Интересует данная доработка для 1.10.2
trOid поясните на счёт трёх строчек

2. Выполним запросы к БД:
Код SQL: ALTER TABLE `cms_user_profiles` ADD INDEX ( `city` );
ALTER TABLE `cms_user_profiles` ADD `geo` TEXT NOT NULL AFTER `city`;
..............
три последние строчки удалите из запроса
0
Петр Петр 11 лет назад #
ошибку то читать умеете? в бд geo.sql удалить последние строки
0
Петр Петр 11 лет назад #
Спасибо! все отлично работает, установил на 1.10.2 :)
+1
Петр Петр 11 лет назад #
добавил такой же автоподбор города в доску объявлений smile проще некуда! :)
0
lesterkey lesterkey 11 лет назад #
добавил такой же автоподбор города в доску объявлений smile проще некуда! :)
может поделитесь???
0
Петр Петр 11 лет назад #
уже точно не помню как делал, сейчас постараюсь вспомнить.
делайте шаг 1, 2, и вместо третьего вот это
в файле /templates/_default_/components/com_board_edit.tpl
вместо
Код PHP:
  1. <tr class="proptable">
  2. <td>
  3. <span>{$LANG.CITY}:</span>
  4. </td>
  5. <td height="35" valign="top">
  6. <input name="city_ed" type="text" id="city_ed" style="width:184px" value="{$item.city|escape:'html'}"/> {$LANG.OR_SELECTING} {$cities}
  7. </td>
  8. </tr>
вставить
Код PHP:
  1. <tr>
  2. <td valign="top" class="">
  3. <div><strong>Город:</strong></div>
  4. </td>
  5. <td valign="top" class="">
  6. <input name="city" type="text" id="city" value="{$item.city|escape:'html'}" style="width:300px"/> <span class="regstar">*</span>
  7. <input name="city_int" type="hidden" class="text-input" id="city_int" value=""/>
  8. {literal}<script type="text/javascript">
  9. $(function () {
  10. $('#city').autocomplete({
  11. serviceUrl: '/cities.php',
  12. minChars: 1,
  13. deferRequestBy: 300,
  14. onSelect: function (value, data) {
  15. $('#city_int').val(data.id_city);
  16. $("#city").removeClass("bad_value");
  17. }
  18. });
  19. $("#city").focus(function(){
  20. if($(this).val()=='Введите первые символы')$(this).val('');
  21. });
  22. $("#city").blur(function(){
  23. if(!$('#city_int').val()){
  24. $(this).addClass("bad_value");
  25. $(this).val('Введите первые символы');
  26. }else $(this).removeClass("bad_value");
  27. });
  28. });
  29. </script>{/literal}
  30. {add_js file='includes/jquery/autocomplete/jquery.autocomplete.js'}
  31. {add_css file='includes/jquery/autocomplete/styles.css'}
  32. </td>
  33. </tr>
вроде все.
0
lesterkey lesterkey 11 лет назад #
Группе, к которой вы принадлежите, запрещено просматривать этот скрытый текст
0
udaff udaff 9 лет назад #
Да я археолог! :)
Все круто, но при регистрации в город пользователю попадает значение "Array"
А если отредкатировать профиль - тогда все как надо.. Почему так, не понятно..

Еще от автора

Ajax подгрузка контента для двойки
Ну что, товарищи, сегодня вы своими руками сможете сделать ajax подгрузку записей контента.
AJAX подгрузка комментов для двойки
Как следует из названия, дополнение ограничивает полный вывод всех комментов записи и позволяет пользователю при необходимости посмотреть следующие.
ContentWatch - проверка уникальности добавляемого контента для icms2
Компонент позволяет проверять уникальность текста с помощью сервиса Content-Watch.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.