Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 02.11.2016, 21:42
veg veg вне форума
Аспирант
Отправить личное сообщение для veg Посмотреть профиль Найти все сообщения от veg
 
Регистрация: 05.04.2012
Сообщений: 43

Живой поиск. Как реализовать фичу
На страничке стоит живой поиск, который начинает делать выборку по городам при вводе двух символов.

Все работает, все отправляется. Но есть одно НО, нужно чтоб люди могли ТОЛЬКО выбирать из предлагаемого списка вариантов.

Если совпадений не найдено,то в выводимых результатах появлялась надпись - СОВПАДЕНИЯ НЕ НАЙДЕНЫ, а при смене фокуса с поля input вводимые данные уничтожаются.

<form method="POST" action=""> 
    <input type="text" name="referal" placeholder="Живой поиск" value="" class="who"  autocomplete="off"><input type="submit" name="subscribe" value="Отправить!"> 
    <ul class="search_result" id='popup'></ul>
</form>

<script>
jQuery(function($){
	$(document).mouseup(function (e){ // событие клика по веб-документу
		var div = $("#popup"); // тут указываем ID элемента
		if (!div.is(e.target) // если клик был не по нашему блоку
		    && div.has(e.target).length === 0) { // и не по его дочерним элементам
			div.hide(); // скрываем его
		}
	});
}); </script>


if(!empty($_POST["referal"])){ //Принимаем данные

    $referal = trim(strip_tags(stripcslashes(htmlspecialchars($_POST["referal"]))));

    $db_referal = $mysqli -> query("SELECT * from ".PREFIX."city WHERE city LIKE '%$referal%'")
    or die('Ошибка №'.__LINE__.'<br>Обратитесь к администратору сайта пожалуйста, сообщив номер ошибки.');

    while ($row = $db_referal -> fetch_array()) {
        echo "\n<li>".$row["city"]."</li>"; //$row["name"] - имя таблицы
    }

}

$(function(){
    
    //Живой поиск
    $('.who').bind("change keyup input click", function() {
        if(this.value.length >= 2){
            $.ajax({
                type: 'post',
                url: "search.php", //Путь к обработчику
                data: {'referal':this.value},
                response: 'text',
                success: function(data){
                    $(".search_result").html(data).fadeIn(); //Выводим полученые данные в списке
                }
            })
        }
    })
    
    $(".search_result").hover(function(){
        $(".who").blur(); //Убираем фокус с input
    })
    
    //При выборе результата поиска, прячем список и заносим выбранный результат в input
    $(".search_result").on("click", "li", function(){
        s_user = $(this).text();
		$(".search_result").fadeOut();
        $(".who").val(s_user); //деактивируем input, если нужно
        
    })

})
Изображения:
Тип файла: jpg Без имени-2.jpg (25.2 Кб, 6 просмотров)
Ответить с цитированием
  #2 (permalink)  
Старый 03.11.2016, 01:31
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

$referal = trim(strip_tags(stripcslashes(htmlspecialchars($_P OST["referal"]))));

Кашу маслом не испортишь? htmlspecialchars применяется при выдаче данных клиенту чтобы избежать на клиенте XSS атак или банально не добавить ошибок в html. strip_tags, к сведению, может работать некорректно, и запрос типа "<div>1</div>" никакой опасности не представляет.

Функция stripslashes удаляет экранирование и применяется, чтобы исключить действие магических кавычек, которые надо раз и навсегда отключить в конфигурации, а stripcslashes удаляет экранирование стиля С. В тоже время, хотя в запросах городов такового не может быть, но уж коли со страха режутся теги и замена на html-сущности, то надо учитывать то, что LIKE использует символы _ и % как спецсимволы, которые нужно экранировать в данных посредством addcslashes().

То есть все что понаписано в запросе никоим образом не спасет от sql-инъекции. Для этого в оригинальном расширении MySQL применяется mysql_real_escape_string, а mysqli mysqli_real_escape_string, но в mysqli лучше использовать подготовленные запросы (prepare) и метку параметров ?, а экранированием займется драйвер.

По ответу клиента строится список. А что будет у клиента при получении 'Ошибка №'.__LINE__.'<br>Обратитесь к администратору сайта пожалуйста, сообщив номер ошибки.'? И вообще, если таким образом администратор будет разбираться с ошибками, то он поседеет, ибо скриптов много и одноименных линий в них куча. А пользователи не обязательно программисты, и не обязательно точно смогут описать где и при каких обстоятельствах произошло нечто.

Может сперва исправите код на человеческий, измените логику общения клиент-сервер, а потом уже пояснить, что означает "люди могли ТОЛЬКО выбирать из предлагаемого списка вариантов", ибо что кроме выбора они в нем могут сделать? Иначе, если понимать это буквально, то ни LIKE, ни ввода на клиенте не нужно, и все должно быть иное.

К сведению - echo "\n<li>".$row["city"]."</li>" - для html это просто мусор.

Последний раз редактировалось laimas, 03.11.2016 в 01:40.
Ответить с цитированием
  #3 (permalink)  
Старый 03.11.2016, 03:20
veg veg вне форума
Аспирант
Отправить личное сообщение для veg Посмотреть профиль Найти все сообщения от veg
 
Регистрация: 05.04.2012
Сообщений: 43

Вот это письмецо.
Это же скрипт на столько упрощенный, чтобы вопросов не возникало. Конечно же ошибка тоже приведена для примера.

По поводу самого вопроса - "люди могли ТОЛЬКО выбирать из предлагаемого списка вариантов"
Означает, что люди могут выбирать город, только из предлагаемого списка вариантов. Если вариант не находится, то как во вложении выше выдается надпись - совпадений не найдено, а поле input очищается.
А кроме выбора они могут сделать следующее:
Вбить несуществующий город и нажать кнопку отправить. Собственно вот что и вышло, во вложении ниже.
Снимок.JPG
Ответить с цитированием
  #4 (permalink)  
Старый 03.11.2016, 04:03
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от veg
Это же скрипт на столько упрощенный, чтобы вопросов не возникало.
trim(strip_tags(stripcslashes(htmlspecialchars($_P OST["referal"])))) - это не упрощение, а бесполезное усложнение, как следствие непонимания назначения указанных функций.

Насчет ошибки - ul кроме li ничего не должен содержать, а вы строя список на нем конечно его стилизуете. Как можно при этом вместо списка в ul втыкать сообщение об ошибке? Ведь проблема не в том, что вы номера строк в файлах сообщаете, а в том как сообщаете об ошибках, код то клиентский просто принимает и помещает. Ну разве же так делается, а если так не делается, то где реальный код?

А чтобы выбирать из списка имеющегося, то код то ведь совсем иной будет при этом. Тут только возникает вопрос - а сколько позиций предлагает список, будет ли удобен при этом выбор в нем? Это ведь тоже надо обдумать, а если обдумать, то это несомненно скажется на коде как клиента, так и сервера. Или не так?

То есть ваш вопрос, это нечто общее, желание, а детализация этого желания отсутствует. Значит и ответ может быть в общих чертах. )
Ответить с цитированием
  #5 (permalink)  
Старый 03.11.2016, 11:38
veg veg вне форума
Аспирант
Отправить личное сообщение для veg Посмотреть профиль Найти все сообщения от veg
 
Регистрация: 05.04.2012
Сообщений: 43

http://02r.ru/news/ вот как это выглядит, чтоб было совсем понятно.
Вариантов около 1000, но пользователю предоставляется выбор. Можно ввести несколько букв города и выбрать из списка нужны, а можно просто ввести несуществующий и отправить форму.

Нужно, чтобы при отсутствии вариантов выводилась строка - совпадений нет https://vk.com/edit?act=contacts как здесь. Попробуйте вбить несуществующий город.
Ответить с цитированием
  #6 (permalink)  
Старый 03.11.2016, 13:10
Профессор
Отправить личное сообщение для Гробовщик Посмотреть профиль Найти все сообщения от Гробовщик
 
Регистрация: 10.03.2013
Сообщений: 169

veg,
Ну считай сколько у тебя записей из базы возвращается... Если 0 то выводи сообщение.
Что бы отчистить город как вариант можно сделать поле input type="hidden" в котором будет меняться значение в зависимости от выбора города (ну как пример).
А вообще самый оптимальный вариант проводить проверку города после отправки на сервер (так то она должна быть при лбом раскладе) и если пользователь проигнорировал сообщение "нет такого города", то он сам виноват, пускай перезаполняет форму заново

Последний раз редактировалось Гробовщик, 03.11.2016 в 13:19.
Ответить с цитированием
  #7 (permalink)  
Старый 03.11.2016, 13:28
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от veg
Вариантов около 1000, но пользователю предоставляется выбор. Можно ввести несколько букв города и выбрать из списка нужны, а можно просто ввести несуществующий и отправить форму.
Живой поиск (или плагины AutoComplete) потому и называется живым, что находит совпадения по мере ввода.

Вы же в вопросе написали буквально следующее "люди могли ТОЛЬКО выбирать из предлагаемого списка вариантов", а это уже не поиск, а предложения, то есть есть готовый список, выбирайте, а нет вводите свое. Но если нет в предложении, то ввод "другого", это тоже не поиск, а добавление нового субъекта в базу, который впоследствии может предлагаться.

Как еще иначе понимать ваше требование? А если понимание правильное, то список предложений из 1000 городов, это уже много, думаю не стоит объяснять, что выбор в таком будет очень неудобным. В тоже время существует множество готовых плагинов AutoComplete, включая и с постраничной навигацией в списке, и прочими плюшками.

Так что решайте, любо ищите готовое подходящее, либо отказываетесь от "только выбор из списка" и все-таки живой поиск, либо хорошо обдумайте "все подводные камни всех И", и тогда формулируйте вопрос.

Сообщение от veg
Попробуйте вбить несуществующий город.
Не буду пробовать: а) я и так прекрасно знаю как работает AutoComplete; б) конкретно на ВК посмотреть не могу - не был и не буду участником соцболот, а регистрироваться у них ради пощелкать тем более. )
Ответить с цитированием
  #8 (permalink)  
Старый 03.11.2016, 15:54
veg veg вне форума
Аспирант
Отправить личное сообщение для veg Посмотреть профиль Найти все сообщения от veg
 
Регистрация: 05.04.2012
Сообщений: 43

Сообщение от Гробовщик Посмотреть сообщение
veg,
Ну считай сколько у тебя записей из базы возвращается... Если 0 то выводи сообщение.
Что бы отчистить город как вариант можно сделать поле input type="hidden" в котором будет меняться значение в зависимости от выбора города (ну как пример).
А вообще самый оптимальный вариант проводить проверку города после отправки на сервер (так то она должна быть при лбом раскладе) и если пользователь проигнорировал сообщение "нет такого города", то он сам виноват, пускай перезаполняет форму заново
Спасибо. Позже отпишу что получилось.
Ответить с цитированием
  #9 (permalink)  
Старый 03.11.2016, 22:56
veg veg вне форума
Аспирант
Отправить личное сообщение для veg Посмотреть профиль Найти все сообщения от veg
 
Регистрация: 05.04.2012
Сообщений: 43

Сообщение от laimas Посмотреть сообщение
Живой поиск (или плагины AutoComplete) потому и называется живым, что находит совпадения по мере ввода.
Так он совпадения и находит, пользователь должен выбрать из совпавшего, как в яндексе, зайдите поглядите, там регистрироваться не нужно. Если я ввожу например слово javascript в яндексе, то он предлагает мне несколько вариантов совпадений, при клике на который уже заполняется поле input. Далее нажимаю кнопку поиск и он выдает результаты по моему запросу.

Если же я например введу слово jjjjaavvaascripttt, то в выпадающем поле ничего не будет, а при дальнейшем нажатии кнопки ИСКАТЬ тоже вряд ли что-то найдет.


Сообщение от laimas Посмотреть сообщение
Вы же в вопросе написали буквально следующее "люди могли ТОЛЬКО выбирать из предлагаемого списка вариантов", а это уже не поиск, а предложения, то есть есть готовый список, выбирайте, а нет вводите свое. Но если нет в предложении, то ввод "другого", это тоже не поиск, а добавление нового субъекта в базу, который впоследствии может предлагаться.
А яндекс что не предлагает? Когда в поисковике вводите фразу, он и выдает Вам совпадения из списка часто используемых поисковых фраз. Добавлять в базу новый город через форму мне не нужно.
Сообщение от laimas Посмотреть сообщение
Как еще иначе понимать ваше требование? А если понимание правильное, то список предложений из 1000 городов, это уже много, думаю не стоит объяснять, что выбор в таком будет очень неудобным. В тоже время существует множество готовых плагинов AutoComplete, включая и с постраничной навигацией в списке, и прочими плюшками.
Чем глаголить в пустую не разобравшись, открыли бы пример, а если нечего по делу сказать, лучше даже не пишите.

Еще раз, откройте яндекс, вбейте слово javascript, он вам выдаст с десяток часто используемых поисковых фраз(при клики на любое заполнится поле input), а их явно не 1000, скажу больше, даже не 1000 000, а вы говорите что 1000 городов - это уже много.
Сообщение от laimas Посмотреть сообщение
Так что решайте, любо ищите готовое подходящее, либо отказываетесь от "только выбор из списка" и все-таки живой поиск, либо хорошо обдумайте "все подводные камни всех И", и тогда формулируйте вопрос.
Какие камни? Я ж не собираюсь корпорацию открывать. Взламывать мой доходяшный сайтик вряд кто будет, его еще сперва найти надо.
Сообщение от laimas Посмотреть сообщение
Не буду пробовать: а) я и так прекрасно знаю как работает AutoComplete; б) конкретно на ВК посмотреть не могу - не был и не буду участником соцболот, а регистрироваться у них ради пощелкать тем более. )
a) autocomplete у меня вообще OFF стоит.
B) Я не ясновидец, не знаю есть страничка у Вас или нет.
Ответить с цитированием
  #10 (permalink)  
Старый 04.11.2016, 00:26
veg veg вне форума
Аспирант
Отправить личное сообщение для veg Посмотреть профиль Найти все сообщения от veg
 
Регистрация: 05.04.2012
Сообщений: 43

$i=0;
	
    while ($row = $db_referal -> fetch_array()) { $i++;
		
        echo "\n<li><span>".$row["city"]."</span></li>"; //$row["name"] - имя таблицы
    } 
	if($i == 0){echo "\n<li>Нет такого города</li>";}


Сделал так. Теперь выводит что город не найден и это поля неактивно для выбора.
$(".search_result").on("click", "li span", function(){
        s_user = $(this).text();
		$(".search_result").fadeOut();
        $(".who").val(s_user); 
        
    })

Теперь осталось сделать, чтобы поле input очищалось при условии, что город не найден и что был клик вне этого input.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как реализовать динамичное добавление тегов modelfak23 jQuery 1 19.06.2015 14:27
Как правильно реализовать такой функционал? Julian Общие вопросы Javascript 3 16.01.2015 12:34
Как правильно реализовать наследование? Universe Общие вопросы Javascript 9 10.04.2014 16:05
Как вы относитесь к наркоманам? Maxmaxmaximus7 Оффтопик 7 05.02.2014 13:29
Как реализовать? Fliand Элементы интерфейса 4 22.08.2009 19:47