Главная страница   /   16.4. Источники информации о продукции (Pro jQuery

Pro jQuery

Pro jQuery

Адам Фриман

16.4. Источники информации о продукции

Следующее изменение, которое я собираюсь сделать, – это удалить существующие элементы продукции и цикл, который добавляет в список три дополнительных цветка, заменяя их парой вызовов Ajax и шаблоном данных. Тем не менее, во-первых, я создал новый файл с именем additionalflowers.json, который показан в листинге 16-4.

Листинг 16-4: Содержание файла additionalflowers.json
[{"name":"Carnation","product":"carnation"},
{"name":"Lily","product":"lily"},
{"name":"Orchid","product":"orchid"}]

Этот файл содержит базовое JSON описание дополнительной продукции, которую я хочу отобразить. Я собираюсь получить основной набор продукции в качестве HTML фрагмента, а затем добавить к этому набору обработанные JSON данные. В листинге 16-5 показаны изменения.

Листинг 16-5: Определение продукции через HTML и JSON, полученных от Ajax
<!DOCTYPE html>
<html>
<head>
	<title>Example</title>
	<script src="jquery-1.7.js" type="text/javascript"></script>
	<script src="jquery.tmpl.js" type="text/javascript"></script>
	<link rel="stylesheet" type="text/css" href="styles.css" />
	<style type="text/css">
		a.arrowButton {
			background-image: url(leftarrows.png);
			float: left;
			margin-top: 15px;
			display: block;
			width: 50px;
			height: 50px;
		}

		#right {
			background-image: url(rightarrows.png);
		}

		h1 {
			min-width: 0px;
			width: 95%;
		}

		#oblock {
			float: left;
			display: inline;
			border: thin black solid;
		}

		form {
			margin-left: auto;
			margin-right: auto;
			width: 885px;
		}

		#bbox {
			clear: left;
		}

		#error {
			color: red;
			border: medium solid red;
			padding: 4px;
			margin: auto;
			width: 300px;
			text-align: center;
			margin-bottom: 5px;
		}
	</style>
	<script type="text/javascript">
		$(document).ready(function () {

			$.ajaxSetup({
				timeout: 5000,
				converters: {
					"text html": function (data) { return $(data); }
				}
			})

			$(document).ajaxError(function (e, jqxhr, settings, errorMsg) {
				$('#error').remove();
				var msg = "An error occurred. Please try again"
				if (errorMsg == "timeout") {
					msg = "The request timed out. Please try again"
				} else if (jqxhr.status == 404) {
					msg = "The file could not be found";
				}
				$('<div id=error/>').text(msg).insertAfter('h1');
			}).ajaxSuccess(function () {
				$('#error').remove();
			})

			$('#row2, #row3').hide();

			$.get("flowers.html", function (data) {
				var elems = data.filter('div').addClass("dcell");
				elems.slice(0, 3).appendTo('#row1');
				elems.slice(3).appendTo("#row2");
			})

			$.getJSON("additionalflowers.json", function (data) {
				$('#flowerTmpl').tmpl(data).appendTo("#row3");
			})

			$('<a id=left></a><a id=right></a>').prependTo('form')
				.addClass("arrowButton").click(handleArrowPress).hover(handleArrowMouse);
			$('#right').appendTo('form');

			var total = $('#buttonDiv')
				.prepend("<div>Total Items: <span id=total>0</span></div>")
				.css({ clear: "both", padding: "5px" });

			$('<div id=bbox />').appendTo("body").append(total);

			$('input').change(function (e) {
				var total = 0;
				$('input').each(function (index, elem) {
					total += Number($(elem).val());
				});
				$('#total').text(total);
			});

			function handleArrowMouse(e) {
				var propValue = e.type == "mouseenter" ? "-50px 0px" : "0px 0px";
				$(this).css("background-position", propValue);
			}
			function handleArrowPress(e) {
				var elemSequence = ["row1", "row2", "row3"];

				var visibleRow = $('div.drow:visible');
				var visibleRowIndex = jQuery.inArray(visibleRow.attr("id"), elemSequence);

				var targetRowIndex;

				if (e.target.id == "left") {
					targetRowIndex = visibleRowIndex - 1;
					if (targetRowIndex < 0) { targetRowIndex = elemSequence.length - 1 };
				} else {
					targetRowIndex = (visibleRowIndex + 1) % elemSequence.length;
				}
				visibleRow.fadeOut("fast", function () {
					$('#' + elemSequence[targetRowIndex]).fadeIn("fast")
				});
			}
		});
	</script>
	<script id="flowerTmpl" type="text/x-jquery-tmpl">
		<div class="dcell">
			<img src="${product}.png" />
			<label for="${product}">${name}:</label>
			<input name="${product}" value="0" />
		</div>
	</script>
</head>
<body>
	<h1>Jacqui's Flower Shop</h1>
	<form method="post" action="http://node.jacquisflowershop.com/order">
		<div id="oblock">
			<div class="dtable">
				<div id="row1" class="drow"></div>
				<div id="row2" class="drow"></div>
				<div id="row3" class="drow"></div>
			</div>
		</div>
		<div id="buttonDiv">
			<button type="submit">Place Order</button></div>
	</form>
</body>
</html>

Я использовал сокращенные методы Ajax, чтобы получить HTML фрагмент и данные JSON, которые мне нужны для создания рядов. Это может быть не совсем очевидно из скрипта, но одна из приятных вещей, которая связана с сокращенными методами. Это то, что они просто оборачивают вызовы низкоуровневого API, что обозначает, что настройки, которые вы применяете через метод ajaxSetup, применяются так же, как при использовании метода ajax напрямую.

В дополнение к вызовам методов get и getJSON я добавил простой шаблон данных, таким образом я могу обрабатывать JSON легко и просто. В представлении документа нет никаких изменений, но изменился источник контента.