<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CTAPbIu_MABP&#039;s BLOG &#187; date</title>
	<atom:link href="http://mabp.kiev.ua/tag/date/feed/" rel="self" type="application/rss+xml" />
	<link>http://mabp.kiev.ua</link>
	<description>энтузиазм = 1/опыт © Старый Мавр</description>
	<lastBuildDate>Sat, 12 May 2012 07:40:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>jQuery UI: Customized datepicker</title>
		<link>http://mabp.kiev.ua/2009/08/11/jquery-ui-customized-datepicker/</link>
		<comments>http://mabp.kiev.ua/2009/08/11/jquery-ui-customized-datepicker/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 19:49:35 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[jqueryUI]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1104</guid>
		<description><![CDATA[Написать этот код меня подтолкнул комментарий, но идея сделать такую плюшку была давно. Смысл простой до нельзя - надо на стандартном календаре выделять определенные дни. Стандартными средствами этого естественно сделать нельзя. Хачить ui.datepicker.js тоже нельзя, при этом желательно еще передавать список дней прямо в конструктор календаря. Нужно выкрутится, ну в общем как всегда. Начинаем кое-как [...]]]></description>
			<content:encoded><![CDATA[<p>Написать этот код меня подтолкнул <a href="http://mabp.kiev.ua/2008/12/29/jquery-ui-datepicker/#comment-990">комментарий</a>, но идея сделать такую плюшку была давно.</p>

<p>Смысл простой до нельзя - надо на стандартном календаре выделять определенные дни. Стандартными средствами этого естественно сделать нельзя. Хачить ui.datepicker.js тоже нельзя, при этом желательно еще передавать список дней прямо в конструктор календаря. Нужно выкрутится, ну в общем как всегда.</p> 
<span id="more-1104"></span>

<p>Начинаем кое-как обживаемся в тех узких рамках в которые себя загнали - используем замыкания и делегацию и прочие малоиспользуемых плюшки типа функции apply и регулярных выражений.</p>

<pre><code class="javascript">
(function($) {

	/**
	 * autor: CTAPbIu_MABP
	 * email: ctapbiumabp@gmail.com
	 * site: http://mabp.kiev.ua/2009/08/11/customized-datepicker/
	 * license: MIT &#038; GPL
	 * last update: 11.08.2009
	 * version: 1.0
	 */
     
	// сохраняем старые функции
	var old_datepicker =  $.fn.datepicker;
	var old_generateHTML = $.datepicker._generateHTML;

	// и делигируем их новым
	$.datepicker._generateHTML = function(inst) {
		// получаем календарь ввиде raw-html
		var _generateHTML = old_generateHTML.apply(this, arguments),
		// выгребаем даты для этого календаря
		dates = inst.settings.hightlight.values;
		titles = inst.settings.hightlight.titles;
		
		// и начинаем расскрашивать
		for (var i in dates){
			if (dates[i].getFullYear() == inst.drawYear &#038;& dates[i].getMonth() == inst.drawMonth){
				_generateHTML = _generateHTML.replace(
				// магия регулярок
				new RegExp('&lt;a class="([^"]+)" href="#"&gt;' + dates[i].getDate() + '&lt;/a&gt;','i'),
				function(link, classes){
					// еще больше магии
					return link.replace(classes, classes + ' ui-state-custom' + 
						(titles[i] ? '" title="'+ titles[i] : ''));
				});
			}
		}
		return _generateHTML;
	};
	
	// делегируем конструктор
	$.fn.datepicker = function(options){
		// новые опции преобразовываем к объекту
		options.hightlight = $.extend(
			{format:$.datepicker._defaults.dateFormat, values:[], titles:[], settings:{}},
			options.hightlight
		);
		
		// сразу превращаем даты в объекты типа Date для того чтобы сохранить 
		options.hightlight.values = $.map(options.hightlight.values, function(value){
			return $.datepicker.parseDate(options.hightlight.format, value, options.hightlight.settings);
		});
		
		return old_datepicker.apply(this, [options]);
	};
})(jQuery);
</code></pre>

<p>Сначала очень долго думал как же для каждого инстанса календаря сделать свою функцию generateHTML с замкнутыми датами, но потом обнаружил что разработчики тоже сильно не парились и все совали в $.data и я тоже решил этим воспользоваться. Как никак уже готовое решение и переиспользование кода.</p>

<p>Пока писал, обнаружил еще одно забавное недокументированую (кажется) функцию, оказывается есть отдельный CSS класс для выходных, к которому нет реализации. Вот я ее в пример и добавил.</p> 

<script src="/content/source/jquery.calendar.js"></script>
<style>
.ui-datepicker-week-end .ui-state-default{
       border: 1px solid #ffa1a1;
}
.ui-state-custom {
       border: 1px solid #f0f !important;
}
</style>
<script>
jQuery().ready(function($){
$("#datepicker").datepicker({
	firstDay: 1 , 
	hightlight : {
		format:"dd/mm/yy",
		values:["1/08/2009","5/08/2009","15/08/2009"],
		titles:["Рас","Два","Три"],
		settings:{}
	}
});
})
</script>
<div id="datepicker"></div>

<p>Используется это все вот так.</p>
<pre><code class="css">
.ui-datepicker-week-end .ui-state-default{
       border: 1px solid #ffa1a1;
}
.ui-state-custom {
       border: 1px solid #f0f !important;
}
</code></pre> 
<pre><code class="javascript">
$("#datepicker").datepicker({
	firstDay: 1 , 
	hightlight : {
		format:"dd/mm/yy",
		values:["1/08/2009","5/08/2009","15/08/2009"],
		titles:["Рас","Два","Три"],
		settings:{}
	}
});
</code></pre>

<p>Проще не бывает, а скачать можно <a href="http://mabp.kiev.ua/content/source/jquery.calendar.js">тут</a></p> 

]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/08/11/jquery-ui-customized-datepicker/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Непересекающиеся выпадающие списки</title>
		<link>http://mabp.kiev.ua/2009/01/22/xless-selectbox/</link>
		<comments>http://mabp.kiev.ua/2009/01/22/xless-selectbox/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 19:55:55 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=473</guid>
		<description><![CDATA[Что-то я все больше рассказываю о какой-то чепухе, навроде динамического создания полей в форме и совсем отошел от высокого - шаблонов проектирования. И эта статья к сожалению тоже не про них :( На этот раз я собираюсь рассказывать про selectbox'ы. Для примера возьмем два selectbox'а и попробуем выбрах в них интервал времени. Допустим нам надо [...]]]></description>
			<content:encoded><![CDATA[<p>Что-то я все больше рассказываю о какой-то чепухе, навроде <a href="http://mabp.kiev.ua/2009/01/20/dynamic-fieldsdynamic-fields/">динамического создания полей</a> в форме и совсем отошел от высокого - шаблонов проектирования. И эта статья к сожалению тоже не про них :( На этот раз я собираюсь рассказывать про selectbox'ы.</p>
<span id="more-473"></span>
<p>Для примера возьмем два selectbox'а и попробуем выбрах в них интервал времени. Допустим нам надо выбрать два месяца, да так чтоб месяц выбранный в первом шел раньше чем месяц выбранный во втором. Один и тот же месяц тоже желательно не выбирать, поэтому в первом нельзя выбрать декарь, а во втором - январь. И последние условие: если в первом selectbox'е выбрали месяц который идет после месяца, выбранного во втором, то во втором надо отметить месяц идущий за тем который выбрали в первом. В общем масло сливочное с растительным жареное на сале и маргарине, но я надеюсь вы поняли.</p>
<p>Итак нам как всегда понадобиться jQuery и немного уличной магии.</p>

<script>
jQuery().ready(function($){
	$("select[name=first]").change(function(){
		var val = $(":selected",this).val(),
			col = $("select[name=second] option");
		col.removeAttr("disabled").each(function(){
			if ($(this).val() <= val)
				$(this).attr({disabled:'disabled'});
		})
		if(col.filter(":selected").is(":disabled"))
			col.filter(":enabled:first").attr({selected:"selected"});
	}).change().find(":last").attr({disabled:'disabled'});
});
</script>
</head>
<body>
<div style="text-align:center;"><form action="">

<select name="first">
<option value="101">Январь</option>
<option value="102">Февраль</option>
<option value="103">Март</option>
<option value="104">Апрель</option>
<option value="105">Май</option>
<option value="106">Июнь</option>
<option value="107">Июль</option>
<option value="108">Август</option>
<option value="109">Сентябрь</option>
<option value="110">Октябрь</option>
<option value="111">Ноябрь</option>
<option value="112">Декабрь</option>
</select>

<select name="second">
<option value="101">Январь</option>
<option value="102">Февраль</option>
<option value="103">Март</option>
<option value="104">Апрель</option>
<option value="105">Май</option>
<option value="106">Июнь</option>
<option value="107">Июль</option>
<option value="108">Август</option>
<option value="109">Сентябрь</option>
<option value="110">Октябрь</option>
<option value="111">Ноябрь</option>
<option value="112">Декабрь</option>
</select>

</form></div>
<br />
<pre><code class="javascript">
jQuery().ready(function($){
	$("select[name=first]").change(function(){
		var val = $(":selected",this).val(),
			col = $("select[name=second] option");
		col.show().each(function(){
			if ($(this).val() &lt;= val)
				$(this).hide();
		})
		if(!col.filter(":selected").is(":visible"))
			col.filter(":visible:first").attr({selected:"selected"});
	}).change().find(":last").hide();
});
</code></pre>
<br />
<p><b>UPD</b> Вообще у меня в хорошей традиции на следующий день после написания статьи вносить правки. Вот так и сегодня, я посмотрел свое творение под оперой и ослом и понял что надо что-то менять. Итак окончательный вариант:</p>
<br />
<pre><code class="html">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;title&gt;Непересекающиеся выпадающие списки&lt;/title&gt;
&lt;script src="jquery-1.3.2.js"&gt;&lt;/script&gt;
&lt;script&gt;
jQuery().ready(function($){
	$("select[name=first]").change(function(){
		var val = $(":selected",this).val(),
			col = $("select[name=second] option");
		col.removeAttr("disabled").each(function(){
			if ($(this).val() &lt;= val)
				$(this).attr({disabled:'disabled'});
		})
		if(col.filter(":selected").is(":disabled"))
			col.filter(":enabled:first").attr({selected:"selected"});
	}).change().find(":last").attr({disabled:'disabled'});
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form action=""&gt;

&lt;select name="first"&gt;
&lt;option value="101"&gt;Январь&lt;/option&gt;
&lt;option value="102"&gt;Февраль&lt;/option&gt;
&lt;option value="103"&gt;Март&lt;/option&gt;
&lt;option value="104"&gt;Апрель&lt;/option&gt;
&lt;option value="105"&gt;Май&lt;/option&gt;
&lt;option value="106"&gt;Июнь&lt;/option&gt;
&lt;option value="107"&gt;Июль&lt;/option&gt;
&lt;option value="108"&gt;Август&lt;/option&gt;
&lt;option value="109"&gt;Сентябрь&lt;/option&gt;
&lt;option value="110"&gt;Октябрь&lt;/option&gt;
&lt;option value="111"&gt;Ноябрь&lt;/option&gt;
&lt;option value="112"&gt;Декабрь&lt;/option&gt;
&lt;/select&gt;

&lt;select name="second"&gt;
&lt;option value="101"&gt;Январь&lt;/option&gt;
&lt;option value="102"&gt;Февраль&lt;/option&gt;
&lt;option value="103"&gt;Март&lt;/option&gt;
&lt;option value="104"&gt;Апрель&lt;/option&gt;
&lt;option value="105"&gt;Май&lt;/option&gt;
&lt;option value="106"&gt;Июнь&lt;/option&gt;
&lt;option value="107"&gt;Июль&lt;/option&gt;
&lt;option value="108"&gt;Август&lt;/option&gt;
&lt;option value="109"&gt;Сентябрь&lt;/option&gt;
&lt;option value="110"&gt;Октябрь&lt;/option&gt;
&lt;option value="111"&gt;Ноябрь&lt;/option&gt;
&lt;option value="112"&gt;Декабрь&lt;/option&gt;
&lt;/select&gt;

&lt;/form&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>PS: хотя может стоило статью позиционировать как мануал по использованию псевдоселекторов?..</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/01/22/xless-selectbox/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>jQuery UI: DatePicker</title>
		<link>http://mabp.kiev.ua/2008/12/29/jquery-ui-datepicker/</link>
		<comments>http://mabp.kiev.ua/2008/12/29/jquery-ui-datepicker/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 21:12:01 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[jqueryUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=316</guid>
		<description><![CDATA[По результатам сегодняшнего труда решил написать небольшую обучаловку, которая я надеюсь станет первой из цикла статей про jQuery UI. Начнем я думаю с того, что констатируем, что все примеры в мануале немного недостаточны для создания полнофункционального работающего приложения, поэтому нужны такие вот обучаловки. Давайте обрисуем наши потребности: нам нужен сдвоенный календарик выбора периода, чтобы дата [...]]]></description>
			<content:encoded><![CDATA[<p>По результатам сегодняшнего труда решил написать небольшую обучаловку, которая я надеюсь станет первой из цикла статей про jQuery UI. Начнем я думаю с того, что констатируем, что все примеры в <a href="http://ui.jquery.com/repository/tags/latest/demos/functional/#ui.datepicker" rel="nofollow external">мануале</a>  немного недостаточны для создания полнофункционального работающего приложения, поэтому нужны такие вот обучаловки.</p>
<span id="more-316"></span>
<p>Давайте обрисуем наши потребности: нам нужен сдвоенный календарик выбора периода, чтобы дата начала периода не была больше даты конца периода и меньше какой-то границы, соответственно дата конца периода не должна быть меньше даты начала и больше сегодняшней. Для этого я набросал вот такой лаконичный код.</p>

<script type="text/javascript" src="/content/js/jquery-ui-datepicker.js"></script>

<div style="text-align:center;">c <input type="text" name="fromDate" size="12" readonly="readonly"/> по <input type="text" name="toDate" size="12" readonly="readonly"/></div>


<pre><code class="js">
jQuery().ready(function($){
	// двум полям ввода
	$(":input[name='fromDate'], :input[name='toDate']")
		// устанавливаем начальное значение (текущую дату)
		.val($.datepicker.formatDate('dd/mm/yy', new Date()))
		// и добавляем календарик, которому в виде опций передаем 
		// русскую локализацию объединенную с массивом настроек
		.datepicker($.extend({}, {
 			// в call-back функции перед показом задаем доступный для выбора период
			beforeShow: function (input) { 
				return {
					// формируем верхнюю границу
					minDate: (input.name == "toDate" 
						// если не выбрана дата на втором календаре
						? $(":input[name='fromDate']").datepicker("getDate")
 						// берем нижнюю границу
						: $.datepicker.parseDate("dd/mm/yy", "01/01/2009") ), 
					// формируем нижнюю границу
					maxDate: (input.name == "fromDate" 
						// если не выбрана дата на первом календаре
						? $(":input[name='toDate']").datepicker("getDate") 
 						// берем сегодняшнюю дату
						: new Date())
				}; 
			}, 
			// задаем формат даты
			dateFormat: "dd/mm/yy", 
			// указываем путь к картинке
			buttonImage: "themes/smoothness/images/calendar.gif", 
			// показываем картинку возле обоих input'ов
			showOn: "both",
			// убираем кнопку из под картинки
			buttonImageOnly: true 
		})
	);
});
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2008/12/29/jquery-ui-datepicker/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Простой comet</title>
		<link>http://mabp.kiev.ua/2008/04/26/simple_comet/</link>
		<comments>http://mabp.kiev.ua/2008/04/26/simple_comet/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 15:01:38 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://mabp.localhost/?p=179</guid>
		<description><![CDATA[Всю неделю готовил эту статью, и вот наконец публикую. Что же первое приходит в голову, когда видишь слово "comet", правильно - чистящее средство, потом комета, а оно почему-то означает технологию (хотя это, наверное, громко сказано, скорее паттерн) постоянного соединения с сервером. Все же в толстых книжках читали, что после того как сервер получил запрос и [...]]]></description>
			<content:encoded><![CDATA[<p>Всю неделю готовил эту статью, и вот наконец публикую.</p>
<p>Что же первое приходит в голову, когда видишь слово "comet", правильно - чистящее средство, потом комета, а оно почему-то означает технологию (хотя это, наверное, громко сказано, скорее паттерн) постоянного соединения с сервером. Все же в толстых книжках читали, что после того как сервер получил запрос и отдал ответ браузеру, он забывает, что к нему вообще кто-то обращался. А тут поседели умные люди и стали седыми. Нет, посидели и придумали идею, как заставить передавать браузеру информацию, изменившуюся на сервере.</p>

<span id="more-179"></span>
<script type="text/javascript" src="/content/source/jquery.comet.js"></script>
<script type="text/javascript">
jQuery().ready(function($){
	$().comets({
		update:function(data){
			$("#clock").text(data);
		},
		connect:function(sid){
			$(this).attr({src:"/content/polygon/comet_clock.php?sid="+sid});
		},
		url:"/content/polygon/comet_clock.php?sid="
	});
	$().comets({
		update:function(data){
			$("#timer").text(data);
		},
		connect:function(sid){
			$(this).attr({src:"/content/polygon/comet_timer.php?sid="+sid});
		},
		url:"/content/polygon/comet_timer.php?sid="
	});
});
</script>

<style>
iframe {
	width:1px;
	height:1px;
	top:-2000px;
	position:absolute;
}
</style>

<p>Вот собственно об этом мы с вами сегодня и поговорим, а собственно я как обычно буду высказывать свои ламерские мысли, а вы, как обычно, будете комментировать...</p>
<img src="/content/img/comet.jpg" alt="comet" align="right" />
<p>И так с чего же начать, начать надо с того что выберем серверным языком php а клиентским как это не странно — javascript. Для того чтобы соединение не разрывалось, php скрипт должен все время работать, но тут мы встречаем два ограничения. Первое вполне логичное у нас нет бесконечного скрипта который бы все время что-то делал, да это и не надо, достаточно включить в код бесконечный цикл. А вот собственно второе ограничение уже куда более неприятное: по умолчанию php скрипт может выполняться только 30 секунд, после чего сервер выдает ошибку о зависании скрипта. С этим мы будем бороться, но об этом потом.</p>
<p>Теперь когда мы имеем серверную часть нужно придумать как она будет контактировать с клиентской. Для этого нужно написать еще какую-то функцию на javascript, которую бы мог вызвать сервер, причем это должно работать параллельным потоком относительно основной страницы. Для реализации параллельного запроса идеально подходит AJAX, но, к сожалению IE и Opera, не умеют корректно обрабатывать событие onreadystatechange==3 , поэтому для реализации параллельного потока в них используют iframe, а я буду использовать его и для остальных браузеров.</p>

<p>В общем пора переходить к делу. Для реализации порционного отдавания контента на php нужно использовать буферизацию, а то php будет хранить все у себя, аж пока не закончит работу скрипта, чего мы собственно пытаемся избежать. Дальше я приведу пример скрипта, который каждую секунду отдает браузеру команду обновить часы и текущее время.</p>

<pre><code class="php">
// устанавливаем неограниченное время выполнения скрипта
ini_set('max_execution_time', 0);

// начинаем буферизацию
ob_start();
// ставим флаг отдавать буфер каждый раз как он больше не нужен
ob_implicit_flush(true);

// отдаем заголовки, чтобы избежать кэширования
header('Expires: Sut, 01 Jan 2000 00:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

// выбрасываем в поток килобайт пробелов, 
// это нужно из-за того, что php первый раз меньше отдавать не хочет
echo str_repeat(chr(32), 1024);
ob_get_clean();   

// в бесконечном цикле описываем то передачу информации в браузер
while(true){
	echo ""
		."&lt;script type='text/javascript'&gt;\n"
		."parent.$(parent.document).trigger('comet".$_GET['sid']."',['".date("D, d M Y H:i:s O")."']);\n"
		."&lt;/script&gt;\n";
	ob_get_clean();
	// ждем 1 секунду до следующего обновления
	sleep(1);
}
</code></pre>

<p>А вот и пример работы этого скрипта находиться сразу под кодом.</p>

<div id="clock" style="width:300px;border: 2px dashed red; font-weight:bold; font-size:1.2em; margin:auto;text-align:center;">Hello from comet!</div>

<p>Теперь давайте разберем, клиентскую часть, она тоже весьма не большая. Как я уже говорил, ее задача в основном создать iframe и приаттачить нужные события. Событий может быть всего два: обновление с новыми данными и разрыв соединения с сервером. Оба события необязательные, потому что сервер и сам вполне может отдавать готовый javascript код, а разорванное соединение можно восстанавливать, а можно предположить, что все обновления с сервера уже пришли и новых больше не будет.</p>

<pre><code class="javascript">
(function($) {

	// конструктор объекта
	var comets = function(options){
		this.init(options);
	}
	
	// собственно сам объект
	comets.prototype = {
		comets : [], // итератор соединений
		options : { // массив функций по умолчанию
			connect:function(sid){
				// функция, выполняющаяся при разрыве соединения с сервером
			},
			update:function(data){
				// функция, вызываемая сервером с новыми данными
			},
			url:"", // адрес бэкэнда
		},
		init : function(options){
			var self = this, 
				comet = {},
				sid = self.comets.push([]); // i++

			// создаем реальный массив параметров
			$.extend(comet,self.options,options)
			
			// создаем iframe и соединение
			$("&lt;iframe/&gt;")
				.appendTo("body")
				.attr({src:comet.url+sid})
				.bind("load", function(){comet.connect.apply(this,[sid]);})
				
			// аттачим события, к ифрейму аттачить нельзя, так как он еще не загрузился
			$(document).bind("comet"+sid, function(event,data){comet.update.apply(this,[data])})
		}
	}

	$.fn.comets = function(options){
		// создаем новый comet
		new comets(options);
		
		// не нарушаем цепочку
		return this;
	}
})(jQuery);
</code></pre>

<p>Теперь надо передать в этот плагин (да я как всегда все делаю плагином под jQuery) наши функции.</p>

<pre><code class="javascript">
$().comets({
	// функция которая обновит такст часов
	update:function(data){
		$("#clock").text(data);
	},
	// функция которая востановит соединение с сервером
	connect:function(sid){
		$(this).attr({src:"clock.php?sid="+sid});
	},
	// адресс бэкэнда
	url:"clock.php?sid="
});
</code></pre>

<p>Как я говорил в начале я расскажу как бороться с временем выполнения скрипта если вам недоступна функция ini_set(); Для этого надо узнать сколько времени может выполняться скрипт и прерывать его работу незадолго до этого времени. Если передать браузеру команду восстановить соединение, то этого можно не указывать в параметрах  в javascript. Вносим правки в алгоритм работы скрипта:</p>


<pre><code class="php">
// узнаем время рабы и отнимаем 5 секунд запаса
$metime = ini_get('max_execution_time') - 5;

// узнаем время начала и конца работы скрипта
$start = $stop = array_sum(explode(" ",microtime()));

ob_start();
ob_implicit_flush(true);
header('Expires: Sut, 01 Jan 2000 00:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

echo str_repeat(chr(32), 1024);
ob_get_clean();   

// по условию, что время начала больше чем время конца минус время исполнения прерываем процедуру
while($start > $stop-$metime){
	echo ""
		."&lt;script type='text/javascript'&gt;\n"
		."parent.$(parent.document).trigger('comet".$_GET['sid']."',['".date("D, d M Y H:i:s O")."']);\n"
		."&lt;/script&gt;\n";
	ob_get_clean();
	$stop = array_sum(explode(" ",microtime()));
	sleep(1);
}

// echo "&lt;script type='text/javascript'&gt;window.location='".$_SERVER['PHP_SELF']."?sid=".$_GET['sid']."';&lt;/script&gt;n";
</code></pre>

<p>Вот пример работы этого кода, только для наглядности я поставил обрыв соединения каждые 10 секунд.</p>

<div id="timer" style="width:300px;border: 2px dashed red; font-weight:bold; font-size:1.2em; margin:auto; text-align:center;">Hello from comet!</div>

<p>Вот такие вот у меня получились простые комёты ;) , возможно, я их немного доделаю и опубликую, свежую версию, но это не сейчас.</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2008/04/26/simple_comet/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Вычисление знака зодиака</title>
		<link>http://mabp.kiev.ua/2007/08/09/calculation_of_zodiacal_sign/</link>
		<comments>http://mabp.kiev.ua/2007/08/09/calculation_of_zodiacal_sign/#comments</comments>
		<pubDate>Thu, 09 Aug 2007 14:10:49 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[date]]></category>

		<guid isPermaLink="false">http://mabp.localhost/?p=117</guid>
		<description><![CDATA[Тут только что ASMO попросил помочь ему рассчитать знак зодиака зная timestamp даты рождения. Чего он тока на свой сайт не пихает)))) Мне чета вдруг захотелось написать что-то очень простое но элегантное. Для этого мне понадобилось завести массив со значениями продолжительности влияния знака в секундах. Для подсчета высокосных годов, надо узнать остаток от деления на [...]]]></description>
			<content:encoded><![CDATA[<p>Тут только что ASMO попросил помочь ему рассчитать знак зодиака зная timestamp даты рождения. Чего он тока на свой сайт не пихает))))</p>
<p>Мне чета вдруг захотелось написать что-то очень простое но элегантное. </p>
<span id="more-117"></span>
<p>Для этого мне понадобилось завести массив со значениями продолжительности влияния знака в секундах.</p>
<p>Для подсчета высокосных годов, надо узнать остаток от деления на полный высокосный цикл (365*24*60*60)*3+(366*24*60*60), получаться 126230400. Оставшееся нужно поделить на (365*24*60*60), остаток от этого деления это последний год из которого можно найти знак</p>
<p>Пример 1975-07-23 это 175298400 секунд с начала 1970 года. Поделив на 126230400 получаем остаток 49068000 а поделив это на 31536000 получаем 17532000. Это количество дней которое прошло с начала 1975 до дня рождения ASMO.</p>
<p>Теперь обратим внимание что массив дат имеет два вхождения козерога, это потому что посередине его влияния выпадает новый год и нужно отдельно считать до него и после.</p>
<p>Еще одна поправка на высокосность года. 1970 (начало эры Unix) не был высокосным, высокосным был 72-й поэтому надо сравнивать текущий год с остатком от деления на высокосный цикл и если разница равна 2 то добавлять рыбам еще один день влияния.</p>
<p>Теперь перебирая массив дат нужно по очереди отнимать от найденного числа 17532000 периоды влияния знаков. Если остаток получается меньше величины влияния знака то данный знак и есть искомый.</p>
<p>В результате работы скрипта мы узнаем что ASMO - <span style="font-weight:bold;">лев</span></p>

<script type="text/javascript">
jQuery().ready(function($){
	$("#go").click(function(){
		var d = $("#date").val().split("-");
		var birth = new Date(d[0].substr(2,2),d[1]-1,d[2]).getTime() / 1000;

		var a = [
			['козерог',1641600],	// 22.12-01.01
			['водолей',2592000],	// 21.01-20.02
			['рыбы',2419200],		// 21.02-20.03
			['овен',2592000],		// 21.03-20.04
			['телец',2505600],	// 21.04-20.05
			['близнецы',2678400],	// 21.05-21.06
			['рак',2592000],		// 22.06-22.07
			['лев',2678400],		// 23.07-23.08
			['дева',2592000],		// 24.08-23.09
			['весы',2505600],		// 24.09-23.10
			['скорпион',2505600],	// 24.10-22.11
			['стрелец',2419200],	// 23.11-21.12
			['козерог',864000],	// 01.01-20.01
		];

		a[2][1] += Math.floor((birth % 126230400)/31536000) == 2 ? 86400 : 0;

		var ostatok = (birth % 126230400) % 31536000;

		for(var v in a)  {
			if(ostatok <= a[v][1])
				break;
			ostatok -= a[v][1];
		}
		alert(a[v][0]);
	});
});
</script>

<p><input type="text" id="date" value="1975-07-23" size="7">&nbsp;<input type="button" id="go" value="Проверь себя"></p>

<pre><code class="php">
$a= array(
	array('козерог',1641600),	// 22.12-01.01
	array('водолей',2592000),	// 21.01-20.02
	array('рыбы',2419200),		// 21.02-20.03
	array('овен',2592000),		// 21.03-20.04
	array('телец',2505600),		// 21.04-20.05
	array('близнецы',2678400),	// 21.05-21.06
	array('рак',2592000),		// 22.06-22.07
	array('лев',2678400),		// 23.07-23.08
	array('дева',2592000),		// 24.08-23.09
	array('весы',2505600),		// 24.09-23.10
	array('скорпион',2505600),	// 24.10-22.11
	array('стрелец',2419200), 	// 23.11-21.12
	array('козерог',864000),	// 01.01-20.01
);

$birth = 175298400; // 1975-07-23
$a[2]['рыбы'] += floor(($birth % 126230400)/31536000) == 2 ? 86400 : 0;

$ostatok = ($birth % 126230400) % 31536000; 

foreach($a as $v)  {
	if($ostatok <= $v[1]) 
		break;
	$ostatok -= $v[1];	
}
echo $v[0];
</code></pre>

<p>Решил добавить еще тоже самое на <a href="http://mabp.kiev.ua/category/programming/javascript/">JavaScript</a></p>

<pre><code class="javascript">
var a = [
    ['козерог',1641600],	// 22.12-01.01
    ['водолей',2592000],	// 21.01-20.02
    ['рыбы',2419200],		// 21.02-20.03
    ['овен',2592000],		// 21.03-20.04
    ['телец',2505600],		// 21.04-20.05
    ['близнецы',2678400],	// 21.05-21.06
    ['рак',2592000],		// 22.06-22.07
    ['лев',2678400],		// 23.07-23.08
    ['дева',2592000],		// 24.08-23.09
    ['весы',2505600],		// 24.09-23.10
    ['скорпион',2505600],	// 24.10-22.11
    ['стрелец',2419200], 	// 23.11-21.12
    ['козерог',864000],		// 01.01-20.01
];

var birth = 175298400; // 1975-07-23

a[2][1] += Math.floor((birth % 126230400)/31536000) == 2 ? 86400 : 0;

var ostatok = (birth % 126230400) % 31536000;

for(var v in a)  {
    if(ostatok <= a[v][1])
        break;
    ostatok -= a[v][1];
}
alert(a[v][0]);
</code></pre>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2007/08/09/calculation_of_zodiacal_sign/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>YUI: calendar</title>
		<link>http://mabp.kiev.ua/2006/11/27/yui-calendar/</link>
		<comments>http://mabp.kiev.ua/2006/11/27/yui-calendar/#comments</comments>
		<pubDate>Mon, 27 Nov 2006 13:15:14 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1202</guid>
		<description><![CDATA[Для тех, кто не знает что такое YUI ссылка на мат. часть Это библиотека классов для разработчиков. В этой статье я хочу поговорить о том, как ее использовать. А точнее как использовать ту ее часть которая выводит DHTML календарик Демо, конечно же, можно глянуть вот тут, но оно далеко не полное... приходится собирать скрипт по [...]]]></description>
			<content:encoded><![CDATA[<p>Для тех, кто не знает что такое YUI ссылка на  <a href="http://developer.yahoo.com/yui/" rel="nofollow external">мат. часть</a></p>

<p>Это библиотека классов для разработчиков. В этой статье я хочу поговорить о том, как ее использовать. А точнее как использовать ту ее часть которая выводит DHTML календарик</p>
<span id="more-1202"></span>
<p>Демо, конечно же, можно глянуть вот тут, но оно далеко не полное... приходится собирать скрипт по частям из разных примеров</p>

<p>Итак вот такой html</p>

<pre><code class="html">
&lt;input type="text" size="15" name="calDate" id="calDate" value="" maxlength="30"  /&gt;
&lt;div id="calContainer"&gt;&lt;/div&gt;
&lt;button type="button" id="calShow"&gt;...&lt;/button&gt;
</code></pre>

<p>и начинаем подключать библиотеки</p>

<pre><code class="html">
&lt;script type="text/javascript" src="yui/yahoo/yahoo.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="yui/dom/dom.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="yui/event/event.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="yui/calendar/calendar.js"&gt;&lt;/script&gt;
</code></pre>

<p>и css без него ничего не выйдет</p>

<pre><code class="html">
&lt;link type="text/css" rel="stylesheet" href="yui/calendar/assets/calendar.css"&gt;
</code></pre>

<p>Потом создаем свой скрипт &lt;_script&gt;...&lt;/_script&gt; Все что я пишу дальше идет именно внутри этого тега</p>

<pre><code class="javascript">
/* 
Задача: нарисовать календарь, который появляется в указанном месте по нажатию на кнопку 
и исчезает после выбора даты, результат выбора попадает в форму в формате YYYY-MM-DD.
Субботу и воскресенье выбирать нельзя, прошедшие дни тоже. 
Ну и я думаю, не стоит заставлять пользователей учить албанский
*/

// создаем новую зону видимости YAHOO.calendar
YAHOO.namespace("calendar");

// создаем загрузчик

function init() {
    // создаем новый объект салендаря с именем cal и загружаем его в div calContainer
    YAHOO.calendar.cal = new YAHOO.widget.Calendar("cal","calContainer", { 
        // средние имена дней (по умолчанию длинные) 
        LOCALE_WEEKDAYS:"medium",
                 // минимальная дата - сегодня
                mindate: new Date(),
                // текущая дата сегодня
                pagedate: new Date() 
        });
	/* 
	массив параметров при создании можно вынести и отдельно как показано ниже но я решил показать оба способа
	*/

	YAHOO.calendar.cal.cfg.setProperty("START_WEEKDAY ",   1); // первый день недели - понедельник а не воскресенье

	// Русифицируем календарь
	YAHOO.calendar.cal.cfg.setProperty("MONTHS_SHORT",   ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"]); 
	YAHOO.calendar.cal.cfg.setProperty("MONTHS_LONG",    ["январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"]); 
	YAHOO.calendar.cal.cfg.setProperty("WEEKDAYS_MEDIUM",["вск", "пон", "втр", "срд", "чет", "пят", "суб"]); 
	YAHOO.calendar.cal.cfg.setProperty("WEEKDAYS_LONG",  ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота", "воскресенье"]); 

	// функция которая получает координаты html элемента
	var getAbsPos = function  (p) {
		var s = { x:0, y:0 };
		while (p.offsetParent)
		{
			s.x += p.offsetLeft;
			s.y += p.offsetTop;
			p = p.offsetParent;
		}
		return s;
	}

	// получаем координаты поля куда надо ввести дату и выводим на его месте календарь, можно выводить под или над ним
	var calCon = document.getElementById("calContainer");
	var calBut = document.getElementById("calDate");
	// функцию getAbsPos я обьясню чуть ниже
	calCon.style.top = getAbsPos(calBut).y + 'px';
	calCon.style.left = getAbsPos(calBut).x + 'px';

	// пишем обработчик события выбора дяты
	var handleSelect function (type,args,obj) {
		var year = date[0][0][0], month = date[0][0][1], day = date[0][0][2];
		
		var txtDate1 = document.getElementById("calDate");
		// формат даты YYYY-MM-DD
		txtDate1.value = year + "-" + month + "-" + day;
		
		// прячем календарь
		var txtCon = document.getElementById("calContainer");
		txtCon.style.display = "none";
	}

	// устанавливаем событие при выборе даты
	YAHOO.calendar.cal.selectEvent.subscribe(handleSelect, YAHOO.calendar.cal, true);
	YAHOO.calendar.cal.render();

	// перехват нажатия кнопки - вызов календаря
	YAHOO.util.Event.addListener("calShow", "click", YAHOO.calendar.cal.show, YAHOO.calendar.cal, true);

	// отключаем субботу и воскресенье
	var myCustomRenderer = function(workingDate, cell) { return YAHOO.widget.Calendar.STOP_RENDER; }
	YAHOO.calendar.cal.addWeekdayRenderer(7, myCustomRenderer);
	YAHOO.calendar.cal.addWeekdayRenderer(1, myCustomRenderer);

	YAHOO.calendar.cal.render();
}

</code></pre>

<p>вот и сказочке конец... а в следующей сказочке будет автокомплит с ajax для продвинутых</p>

<p>PS. вопросы не задавать, почту не писать, google вам поможет.</p>
<p>PSS. меня вот спросили чем эта библиотека лучше чем например <a href="http://www.dynarch.com/projects/calendar/" rel="nofollow external">вот эта</a> - ответ может и не чем, просто она есть!</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2006/11/27/yui-calendar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

