PHP

Последовательный выбор с использованием AJAX, jQuery и PHP

В данном уроке мы построим набор элементов для последовательного выбора. Выбор опции будет приводить к обновлению страницы, показывая пользователю дополнительные опции для уточнения выбора. Опции выбора описаны на серверной стороне с помощью PHP, поэтому будет просто переделать пример на использование базы данных.

Разметка HTML

Элемент выбора имеет заголовок, который описывает выбираемый параметр. Заголовок и элемент выбора заключены в элемент LI.

Элемент выбора

При добавлении вопросов дополнительные элементы LI создается кодом jQuery. Все они располагаются в неупорядоченном списке #questions. Заголовок и опции данных пунктов обрабатываются как JSON, что будет видно в части PHP. вот какая разметка генерируется для пункта li:
index.html – генерируемый код
 	<ul id="questions">
 	    <!-- Генерируется кодом jQuery -->
 	    <li>
 	        <p>Что желаете купить?</p>
	        <select data-placeholder="Выберите категорию продукта">
 	            <option data-connection="phoneSelect" value="Phones">Телефоны</option>
 	            <option data-connection="notebookSelect" value="Notebooks">Ноутбуки</option>
 	            <option data-connection="tabletSelect" value="Tablets">Планшеты</option>
 	        </select>
 	    </li>
 	    <!-- Следующая секция вставляется в зависимости от выбора -->
 	</ul>

Демонстрационная страница не использует элемент браузера. Потому что мы подключаем плагин jQuery Chosen для преобразования нашего элемента в стильный виджет, который вы видите на экране. Нужно просто вызвать метод chosen() для элемента select, а все остальное сделает плагин.

Код jQuery

Вот что делает наш код jQuery - он получает информацию для элемента выбора в виде JSON с сервера, генерирует разметку HTML и устанавливает обработчики событий для отслеживания изменений. Если элемент выбора меняется, то процесс повторяется с новыми пунктами.

В коде используется две функции JavaScript:

refreshSelects запускает плагин Chosen и привязывает обработчики событий каждый раз, когда новый пункт добавляется на страницу;
fetchSelect запрашивает фид JSON с сервера и генерирует разметку для ответа.

assets/js/script.js
 	$(function(){
 	     
	    var questions = $('#questions');
 	     
 	    function refreshSelects(){
 	        var selects = questions.find('select');
 	         
 	        // Улучшаем элемент selects с помощью плагина Chose
 	        selects.chosen();
 	         
 	        // Ждем изменений
 	        selects.unbind('change').bind('change',function(){
 	             
 	            // Выбранная опция
 	            var selected = $(this).find('option').eq(this.selectedIndex);
 	            // Ищем атрибут data-connection
 	            var connection = selected.data('connection');
	             
 	             
 	            // Удаляем следующий контейнер li (к=если есть)
 	            selected.closest('#questions li').nextAll().remove();
 	             
 	            if(connection){
 	                fetchSelect(connection);
 	            }
 	 
 	        });
 	    }
 	     
 	    var working = false;
 	      
 	    function fetchSelect(val){
 	         
 	        if(working){
 	            return false;
 	        }
 	        working = true;
 	         
 	        $.getJSON('ajax.php',{key:val},function(r){
 	             
 	            var connection, options = '';
 	             
 	            $.each(r.items,function(k,v){
 	                connection = '';
 	                if(v){
 	                    connection = 'data-connection="'+v+'"';
 	                }
 	                 
 	                options+= '<option value="'+k+'" '+connection+'>'+k+'</option>';
 	            });
 	             
 	            if(r.defaultText){
 	                 
 	                // Плагин Chose требует, чтобы был добавлен пустой элемент опции
 	                // если нужно выводить текст "Пожалуйста, выберите"
 	                 
 	                options = '<option></option>'+options;
 	            }
 	             
 	            // Строим разметку для раздела select
 	             
 	            $('<li>\
 	                <p>'+r.title+'</p>\
 	                <select data-placeholder="'+r.defaultText+'">\
 	                    '+ options +'\
 	                </select>\
 	                <span class="divider"></span>\
 	            </li>').appendTo(questions);
 	             
 	            refreshSelects();
 	             
	            working = false;
 	        });
 	         
 	    }
 	     
 	    $('#preloader').ajaxStart(function(){
 	        $(this).show();
 	    }).ajaxStop(function(){
 	        $(this).hide();
 	    });
 	     
 	    // В начале загружаем выбор продукта
 	    fetchSelect('productSelect');
 	});

Отлично! Теперь осталось сделать генерацию фида JSON. Обратите внимание, что функция fetchSelect получает в качестве аргумента строку. Это ключ, который передается в код PHP, обозначающий, какой набор пунктов нам требуется.

Вот как выглядит простой ответ из нашего скрипта PHP:
 	{
 	    "items": {
	        "Телефоны": "phoneSelect",
 	        "Ноутбуки": "notebookSelect",
 	        "Планшеты": ""
 	    },
 	    "title": "Что желаете купить?",
 	    "defaultText": "Выберите категорию продукта"
 	}

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

Вид элемента выбора

PHP

Нам нужно где-то хранить информацию о элементах выбора, опциях, которые в них содержатся, и взаимосвязях между ними. В базе данных для решения задачи может использоваться набор строк. Но в нашем примере мы храним данные в статических объектах. Для решения мы определяем простой класс, который будет содержать информацию об элементе выбора.
ajax.php / 1
 	// Будем использовать данный класс для определения каждого элемента select
 	 
 	class SelectBox{
 	    public $items = array();
 	    public $defaultText = '';
 	    public $title = '';
 	     
 	    public function __construct($title, $default){
 	        $this->defaultText = $default;
 	        $this->title = $title;
 	    }
 	     
 	    public function addItem($name, $connection = NULL){
 	        $this->items[$name] = $connection;
 	        return $this;
 	    }
 	     
 	    public function toJSON(){
 	        return json_encode($this);
 	    }
 	}

Теперь нам нужно только создать экземпляр данного класса для каждого элемента выбора и вызвать метод addItem() для добавления опций. Данный метод имеет опциональный параметр $connection, который содержит имя зависимого элемента выбора.
ajax.php / 2
 	/* конфигурация элементов select */
 	 
 	// Продукт
 	 
 	$productSelect = new SelectBox('Что желаете купить?','Выберите категорию продукта');
 	$productSelect->addItem('Телефоны','phoneSelect')
 	              ->addItem('Ноутбуки','notebookSelect')
 	              ->addItem('Планшеты','tabletSelect');
 	 
 	// Типы телефонов
 	 
 	$phoneSelect = new SelectBox('Какой тип телефона вы хотите?', 'Выберите тип телефона');
 	$phoneSelect->addItem('Смартфон','smartphoneSelect')
 	            ->addItem('Обычный телефон','featurephoneSelect');
 	 
 	// Смартфоны
 	 
 	$smartphoneSelect = new SelectBox('Какой смартфон вам нужен?','Выберите модель смартфона');
 	$smartphoneSelect->addItem('Samsung Galaxy Nexus')
 	                 ->addItem('iPhone 4S','iphoneSelect')
 	                 ->addItem('Samsung Galaxy S2')
 	                 ->addItem('HTC Sensation');
 	 
 	// Обычные телефоны
 	 
 	$featurephoneSelect = new SelectBox('Какой телефон вам нужен?','Выберите модель телефона');
 	$featurephoneSelect->addItem('Nokia N34')
 	                   ->addItem('Sony Ericsson 334')
 	                   ->addItem('Motorola');
 	 
 	// Цвет iPhone
 	 
 	$iphoneSelect = new SelectBox('Какой цвет аппарата вам нравится?','Выберите цвет');
 	$iphoneSelect->addItem('Белый')->addItem('Черный');
 	 
 	// Выбор ноутбука
 	 
 	$notebookSelect = new SelectBox('Какой ноутбук вы хотите купить?', 'Выберите модель ноутбука');
 	$notebookSelect->addItem('Asus Zenbook','caseSelect')
 	               ->addItem('Macbook Air','caseSelect')
 	               ->addItem('Acer Aspire','caseSelect')
 	               ->addItem('Lenovo Thinkpad','caseSelect')
 	               ->addItem('Dell Inspiron','caseSelect');
 	 
 	// Планшет
 	 
 	$tabletSelect = new SelectBox('Какой планшет является предметом вашей мечты?', 'Выберите модель планшета');
 	$tabletSelect->addItem('Asus Transformer','caseSelect')
 	             ->addItem('Samsung Galaxy Tab','caseSelect')
 	             ->addItem('iPad 16GB','caseSelect')
 	             ->addItem('iPad 32GB','caseSelect')
 	             ->addItem('Acer Iconia Tab','caseSelect');
 	 
 	// Сумка
 	 
 	$caseSelect = new SelectBox('Возьмёте защитный чехол к вашему аппарату?','');
 	$caseSelect->addItem('Да')->addItem('Нет');
 	 
 	 
 	// Регистрируем все пункты выбора в массиве
 	 
 	$selects = array(
 	    'productSelect'         => $productSelect,
 	    'phoneSelect'           => $phoneSelect,
	    'smartphoneSelect'      => $smartphoneSelect,
	    'featurephoneSelect'    => $featurephoneSelect,
 	    'iphoneSelect'          => $iphoneSelect,
 	    'notebookSelect'        => $notebookSelect,
 	    'tabletSelect'          => $tabletSelect,
 	    'caseSelect'            => $caseSelect
 	);

Выше приведенный код определяет несколько элементов выбора и размещает их в массиве $selects. Когда скрипт получает запрос AJAX, он просматривает данный массив и возвращает ответ:
ajax.php / 3
 	// Будем просматривать данный массив и возвращать выбранный объект в зависимости
 	// от парметра $_GET['key'] передаваемого jQuery
	 
 	// Вы можете модифицировать код для выбора результата из таблицы
 	 
 	if(array_key_exists($_GET['key'],$selects)){
 	    header('Content-type: application/json');
 	    echo $selects[$_GET['key']]->toJSON();
 	}
 	else{
 	    header("HTTP/1.0 404 Not Found");
 	    header('Status: 404 Not Found');
 	}

Вызывая метод toJSON() мы выводим все данные для элементов выбора в формате JSON, который используется клиентской частью jQuery.

Готово!

Скрипт можно модифицировать для работы с базой данных. Описанный метод поможет сформировать опросы посетителей, представление различных продуктов, выбор правильных опций для товаров и так далее.
Добавлено: 19 Августа 2013 05:47:44 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...