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

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

demosourse

Разметка 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.

 

Готово!

Скрипт можно модифицировать для работы с базой данных. Описанный метод поможет сформировать опросы посетителей, представление различных продуктов, выбор правильных опций для товаров и так далее.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: tutorialzine.com/2011/11/chained-ajax-selects-jquery/
Перевел: Сергей Фастунов
Урок создан: 14 Декабря 2011
Просмотров: 46732
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

    Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

^ Наверх ^