<?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; jqueryUI</title>
	<atom:link href="http://mabp.kiev.ua/tag/jquery-ui/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>Как закрыть диалог</title>
		<link>http://mabp.kiev.ua/2012/01/17/how-to-close-dialog/</link>
		<comments>http://mabp.kiev.ua/2012/01/17/how-to-close-dialog/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 23:50:41 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>
		<category><![CDATA[Modal Dialog]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1386</guid>
		<description><![CDATA[Представьте что у вас на странице есть 5 разных диалогов, они могут быть открыты в любой последовательности но два сразу открытыми быть не могут. Значит надо закрывать все открытые, но как их ывыбрать, не хранить же 5 ссылок на диалоги. Первый пришедший в голову вариант был прост как двери $("#dialog1","#dialog2","#dialog3","#dialog4","#dialog5").dialog("close"); но если хотя бы один [...]]]></description>
			<content:encoded><![CDATA[<p>Представьте что у вас на странице есть 5 разных диалогов, они могут быть открыты в любой последовательности но два сразу открытыми быть не могут. Значит надо закрывать все открытые, но как их ывыбрать, не хранить же 5 ссылок на диалоги.</p>
<span id="more-1386"></span>
<p>Первый пришедший в голову вариант был прост как двери</p>

<pre><code class="javascript">
$("#dialog1","#dialog2","#dialog3","#dialog4","#dialog5").dialog("close");
</code></pre>

<p>но если хотя бы один диалог не был создан при старте страницы то вылетит Exception. Естественно создавать диалоги при старте бессмысленно. ни один может не понадобиться а ресурсов они отъедают нормально. Второй вариант был таким</p>

<pre><code class="javascript">
for (var i=1,j=5;i&lt;j;i++){
	try{
		$("#dialog"+i).dialog("close");
	}catch(e){
		// do nothing
	}
}
</code></pre>

<p>и несколько дней эта конструкция муляла мне глаза. Наконец я переписал это примерно так</p>

<pre><code class="javascript">
for (var i=1,j=5,d;i&lt;j;i++){
	d = $("#dialog"+i);
	if(d.data("dialog")){
		d.dialog("close");
	}
}
</code></pre>

<p>стало лучше но еще не совершенно, последним вариантом стало</p>

<pre><code class="javascript">
$("div:data(dialog)").dialog("close");
</code></pre>

<p>теперь я доволен, а какие еще есть варианты?</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2012/01/17/how-to-close-dialog/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>jQuery UI: Tabs below content</title>
		<link>http://mabp.kiev.ua/2011/11/10/jquery-ui-tabs-below-content/</link>
		<comments>http://mabp.kiev.ua/2011/11/10/jquery-ui-tabs-below-content/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 10:25:05 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1382</guid>
		<description><![CDATA[Похоже открывается очередной сезон этого блога. И вот я вчера приготовил статью про табики, я всего лишь хотел сделать их снизу, и выложить пример даже без объяснения, но все серьезно затянулось и сейчас вам предстоит прочитать достаточно много текста. Как обычно примера из официального мануала мне не достаточно поэтому начал хачить. Собственно то что мне [...]]]></description>
			<content:encoded><![CDATA[<p>Похоже открывается очередной сезон этого блога. И вот я вчера приготовил статью про табики, я всего лишь хотел сделать их снизу, и выложить пример даже без объяснения, но все серьезно затянулось и сейчас вам предстоит прочитать достаточно много текста.</p>

<span id="more-1382"></span>

<p>Как обычно примера из <a href="http://jqueryui.com/demos/tabs/#bottom" rel="nofollow external">официального мануала</a> мне не достаточно поэтому начал хачить. Собственно то что мне надо было находиться в низу страницы, а как я его делал я расскажу сейчас.</p>

<p>Основная идея примера из мануала: чтобы на одной и той же разметке можно было сделать табики и сверху и снизу. Это очень хорошая идея но мне явно не подходила. Вкратце табики выглядят так: общий контейнер, в нем сверху UL с закладками, снизу - DIV с контентом. Это верно как для разметки так и для отображения. Для табиков снизу разметка та же, но табики имеют position:absolute и bottom:0 . Казалось бы все должно работать, НО есть одно НО, и это не IE! Это как не странно WebKit. Все размерности в JQuery UI указаны в EM, что бы все одинаково хорошо смотрелось с любым размером текста, так вот при переходе из EM (да в общем и из остальных относительных величин) в PX, WebKit  округляет числа в большую сторону, тогда как все остальные в меньшую, или подгоняют. Об этом еще <a href="http://ejohn.org/blog/sub-pixel-problems-in-css/" rel="nofollow external">Resig</a> писал в далеком 2008 году. При таком подходе прижатые к низу табики налазят на текст на 1-2PX. Это совершенно не волнует пример в мануале, потому что текст там не имеет бордера и заранее короче на несколько пикселей, так что между ним и прижатыми табами есть зазор. Ради красоты пришлось пожертвовать первоначальной разметкой, перенеся табики под текст. Хотя по моему вообще это не принципиально, потому что я сделал это скриптом, да и вернуть их тоже не проблема.</p>

<p>Вторая проблема это !important. <a href="http://teambook.ru/approaches/the-ezhupa" rel="nofollow external">ежупанятна</a> что универсальность в таком большом CSS framework требует перекрывать что-то, что было написано позже, тем что было написано раньше. Тут кроется проблема всего framework. Я свято уверен что классы типа ui-state-[default|hover|active] не должны определять толщину и тип бордера, а только цвет, потому что потом надо городить огороды. В своем маленьком примере я это поправил. </p>

<p>Ну и последние, надо открывать таб по урлу. Как бы самое обычное дело, но предусмотрено в документации только через куки, а если руками указывать то надо знать индекс таба а не скажем его ID. С этой маленькой гадкой проблемой я тоже очень элегантно справился двумя строками кода.</p>


<link rel="stylesheet" type="text/css" media="screen" href="/content/css/jquery-ui-tabs-below-content.css"/>
<script type="text/javascript" src="/content/js/jquery-ui-tabs-below-content.js"></script>

<div id="tabs" class="tabs-bottom">
	<ul>
		<li><a href = "#tabs-1">1</a></li>
		<li><a href = "#tabs-2">2</a></li>
		<li><a href = "#tabs-3">3</a></li>
		<li><a href = "#tabs-4">4</a></li>
		<li><a href = "#tabs-5">5</a></li>
	</ul>
	<div id="tabs-1">
		<h1>1</h1>
	</div>
	<div id="tabs-2">
		<h1>2</h1>
	</div>
	<div id="tabs-3">
		<h1>3</h1>
	</div>
	<div id="tabs-4">
		<h1>4</h1>
	</div>
	<div id="tabs-5">
		<h1>5</h1>
	</div>
</div>

<p>KISS</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2011/11/10/jquery-ui-tabs-below-content/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>jQuery UI: RangePicker</title>
		<link>http://mabp.kiev.ua/2010/12/21/jquery-ui-rangepicker/</link>
		<comments>http://mabp.kiev.ua/2010/12/21/jquery-ui-rangepicker/#comments</comments>
		<pubDate>Tue, 21 Dec 2010 11:03:43 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1318</guid>
		<description><![CDATA[Сегодня у меня выдался свободный день поэтому расскажу вам как выбрать период на стандартном jquery datepicker Поскольку офицальный пример - гавно, делать все надо самим. Сначала немного подхачим jQuery UI, вот таким образом (function(){ var old_selectDate = $.datepicker.constructor.prototype._selectDate; // forget about this /* Update the input field with the selected date. */ $.datepicker.constructor.prototype._selectDate = function(id, [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня у меня выдался свободный день поэтому расскажу вам как выбрать период на стандартном jquery datepicker</p>
<span id="more-1318"></span>

<script type="text/javascript" src="/content/js/jquery-ui-rangepicker.js"></script>  

<p>Поскольку офицальный пример - <a href="http://jqueryui.com/demos/datepicker/date-range.html" rel="nofollow external">гавно</a>, делать все надо самим.</p>
<p>Сначала немного подхачим jQuery UI, вот таким образом</p>
<pre><code class="javascript">
(function(){
	var old_selectDate = $.datepicker.constructor.prototype._selectDate; // forget about this
	
	/* Update the input field with the selected date. */
	$.datepicker.constructor.prototype._selectDate = function(id, dateStr) {
		var target = $(id);
		var inst = this._getInst(target[0]);
		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
		
		var onSelect = this._get(inst, 'onSelect');
		if (onSelect &#038;& false === onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst])){
			return;
		}
		
		if (inst.input){
			inst.input.val(dateStr);
			inst.input.trigger('change'); // fire the change event
		}
		this._updateAlternate(inst);
		
		if (inst.inline)
			this._updateDatepicker(inst);
		else {
			this._hideDatepicker();
			this._lastInput = inst.input[0];
			if (typeof(inst.input[0]) != 'object')
				inst.input.focus(); // restore focus
			this._lastInput = null;
		}
	}

})();
</code></pre>

<p>Как видете я добавил небольшую проверку на возврат коллбэка onSelect, теперь если он возвращает false то значение инпуту не присваиваеться. Это не должно мешать обычной работе календаря.</p>

<p>Дальше конфигурируем сам календарь, значение настроек смотрите в мануале</p>

<pre><code class="javascript">
jQuery(document).ready(function($){

	var click = 1, from = new Date, to = new Date;
	$("[name=from], [name=to]").datepicker({
		numberOfMonths: 2,
		minDate : new Date("12/01/2010"),
		maxDate : new Date("01/31/2011"),
		dateFormat: "dd/mm/yy",
		showButtonPanel: true,
		closeText : "Применить",
		onSelect: function( selectedDate ) {
			var format = $(this).data("datepicker").settings.dateFormat || $.datepicker._defaults.dateFormat,
				date = $.datepicker.parseDate(format, selectedDate);
			if (click++%2){
				from = date;
				to = date;
			} else {
				if (date &lt; from){
					from = date;
				} else {
					to = date;
				}
			}
			$(this).datepicker("refresh");
			return false;
		},
		beforeShowDay : function(date){
			if (date &gt;= from &#038;& date &lt;= to){
				return [true, "ui-state-highlight"];
			}

			return [true, ""];
		},
		beforeShow : function(input, inst){
			var format = inst.settings.dateFormat || $.datepicker._defaults.dateFormat
			from = $.datepicker.parseDate(format, $("[name=from]").val());
			to = $.datepicker.parseDate(format, $("[name=to]").val());
		},
		onClose: function(dateText, inst) {
			if (inst.dpDiv.find(".ui-datepicker-close").is(".ui-state-hover")){
				var format = inst.settings.dateFormat || $.datepicker._defaults.dateFormat
				$('[name=from]').val($.datepicker.formatDate(format, from));
				$('[name=to]').val($.datepicker.formatDate(format, to));
			}
		}
	});
		
});
</code></pre>

<p>А вот и пример</p>

<div style="text-align:center;">
	<input name="from" value="20/12/2010"/>
	<input name="to" value="10/01/2011"/>
</div>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/12/21/jquery-ui-rangepicker/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jQuery UI: fullscreen button for Dialog</title>
		<link>http://mabp.kiev.ua/2010/12/15/jquery-ui-fullscreen-button-for-dialog/</link>
		<comments>http://mabp.kiev.ua/2010/12/15/jquery-ui-fullscreen-button-for-dialog/#comments</comments>
		<pubDate>Wed, 15 Dec 2010 18:56:13 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1316</guid>
		<description><![CDATA[Сегодня небольшой энчант для диалога - добавление кнопки развернуть на весь экран, хотя конечно не на весь экран а только на весь вьюпорт. Вот такой небольшой код добавляет новую кнопку в заголовок диалога. При первом нажатии на кнопку диалог разворачивается, при втором - сворачивается до первоначального размера. Ручной ресайз на кнопку никак не влияет. .ui-dialog [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня небольшой энчант для диалога - добавление кнопки развернуть на весь экран, хотя конечно не на весь экран а только на весь вьюпорт.</p>
<span id="more-1316"></span>

<link rel="stylesheet" type="text/css" media="screen" href="/content/css/jquery-ui-fullscreen-button-for-dialog.css"/>
<script type="text/javascript" src="/content/js/jquery-ui-fullscreen-button-for-dialog.js"></script>   

<p>Вот такой небольшой код добавляет новую кнопку в заголовок диалога. При первом нажатии на кнопку диалог разворачивается, при втором - сворачивается до первоначального размера. Ручной ресайз на кнопку никак не влияет. </p>
<pre><code class="css">
.ui-dialog .ui-dialog-titlebar-full {
	position: absolute;
	right: 2em;
	top: 50%;
	width: 19px;
	margin: -10px 0 0 0;
	padding: 1px;
	height: 18px;
}

.ui-dialog .ui-dialog-titlebar-full span {
	display: block;
	margin: 1px;
}

.ui-dialog .ui-dialog-titlebar-full:hover,
.ui-dialog .ui-dialog-titlebar-full:focus {
	padding: 0;
}
</code></pre>
<pre><code class="javascript">
(function(){
	var old = $.ui.dialog.prototype._create;
	$.ui.dialog.prototype._create = function(d){
		old.call(this, d);
		var self = this,
			options = self.options,
			oldHeight = options.height,
			oldWidth = options.width,
			uiDialogTitlebarFull = $('&lt;a href="#"&gt;&lt;/a&gt;')
				.addClass(
					'ui-dialog-titlebar-full ' +
					'ui-corner-all'
				)
				.attr('role', 'button')
				.hover(
					function() {
						uiDialogTitlebarFull.addClass('ui-state-hover');
					},
					function() {
						uiDialogTitlebarFull.removeClass('ui-state-hover');
					}
				)
				.toggle(
					function() {
						self._setOptions({
							height : window.innerHeight - 10,
							width : window.innerWidth - 30
						});
						self._position('center');
						return false;
					},
					function() {
						self._setOptions({
							height : oldHeight,
							width : oldWidth
						});
						self._position('center');
						return false;
					}
				)
				.focus(function() {
					uiDialogTitlebarFull.addClass('ui-state-focus');
				})
				.blur(function() {
					uiDialogTitlebarFull.removeClass('ui-state-focus');
				})
				.appendTo(self.uiDialogTitlebar),

			uiDialogTitlebarFullText = $('&lt;span&gt;&lt;/span&gt;')
				.addClass(
					'ui-icon ' +
					'ui-icon-newwin'
				)
				.text(options.fullText)
				.appendTo(uiDialogTitlebarFull)

	};
})();
</code></pre>

<p>Диалог принимает новую опцию options.fullText с текстом кнопки.</p>
<p>И еще для любителей пооптимизировать: _setOptions нельзя совместить с _position потому что позиционирование выполняется раньше ресайза, как ни странно.</p>



<div style="text-align:center;">
<input type="button" value="Тыцалка!" id="showDialog"/>
</div>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/12/15/jquery-ui-fullscreen-button-for-dialog/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lavalamp</title>
		<link>http://mabp.kiev.ua/2010/11/27/lavalamp/</link>
		<comments>http://mabp.kiev.ua/2010/11/27/lavalamp/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 16:06:10 +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[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1308</guid>
		<description><![CDATA[Незнаю в силу каких обстоятельств сложилось что при поиске данного эффекта все ссыки рано или позно заканчиваються тут. Возможно потому что этот плагин был первым, возможно потому что потому что эффект действительно похож на лавовую лампу. В обoем это не важно моя статья тоже веден на этот плагин ;) Так вот есть у этого плагина [...]]]></description>
			<content:encoded><![CDATA[<p>Незнаю в силу каких обстоятельств сложилось что при поиске данного эффекта все ссыки рано или позно заканчиваються <a href="http://www.gmarwaha.com/blog/2007/08/23/lavalamp-for-jquery-lovers/" rel="nofollow external">тут</a>. Возможно потому что этот плагин был первым, возможно потому что потому что эффект действительно похож на лавовую лампу. В обoем это не важно моя статья тоже веден на этот плагин ;)<p>

<span id="more-1308"></span>

<link rel="stylesheet" type="text/css" media="screen" href="/content/css/lavalamp.css"/>
<script type="text/javascript" src="/content/js/lavalamp.js"></script>


<p>Так вот есть у этого плагина большой недостаток - он однострочный и все похожие плагины тоже, тоесть если у меня менюшка в две строки то хрен мне. Надо было срочно исправить недоразумение и я написал свой.<p>

<ul id="lavalamp" class="ui-corner-all">
<li style="top:60px;left:20px" class="active"><span class="text">Один</span></span></li>
<li style="top:40px;left:150px"><span class="text">Два</span></li>
<li style="top:10px;left:50px"><span class="text">Три</span></li>
<li style="top:60px;left:100px"><span class="text">Четыре</span></li>
<li style="top:120px;left:10px"><span class="text">Пять</span></li>
<li style="top:10px;left:150px"><span class="text">Шесть</span></li>
<li style="top:100px;left:100px"><span class="text">Семь</span></li>
</ul>

<div id="lava" class="ui-corner-all"></div>

<p>Код такой<p>
<pre><code class="html">
&lt;ul id="lavalamp" class="ui-corner-all"&gt;
&lt;li style="top:60px;left:20px" class="active"&gt;&lt;span class="text"&gt;Один&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style="top:40px;left:150px"&gt;&lt;span class="text"&gt;Два&lt;/span&gt;&lt;/li&gt;
&lt;li style="top:10px;left:50px"&gt;&lt;span class="text"&gt;Три&lt;/span&gt;&lt;/li&gt;
&lt;li style="top:60px;left:100px"&gt;&lt;span class="text"&gt;Четыре&lt;/span&gt;&lt;/li&gt;
&lt;li style="top:120px;left:10px"&gt;&lt;span class="text"&gt;Пять&lt;/span&gt;&lt;/li&gt;
&lt;li style="top:10px;left:150px"&gt;&lt;span class="text"&gt;Шесть&lt;/span&gt;&lt;/li&gt;
&lt;li style="top:100px;left:100px"&gt;&lt;span class="text"&gt;Семь&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div id="lava" class="ui-corner-all"&gt;&lt;/div&gt;
</code></pre>

<pre><code class="css">
#lavalamp {
	display: block;
	height: 150px;
	border: 5px solid #FF7F04;
	background: #ff7f04; /* old browsers */
	background: -moz-linear-gradient(top, #ff7f04 0%, #ffb76b 99%); /* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff7f04), color-stop(99%,#ffb76b)); /* webkit */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff7f04', endColorstr='#ffb76b',GradientType=0 ); /* ie */
}

    #lavalamp li {
		color: #808080;
		cursor: pointer;
		display: block;
		float: left;
		height: 25px;
		position: relative;
		z-index: auto;
		padding: 0;
    }

        #lavalamp li span {
			display: block;
			font-size: 14px;
			font-weight: bold;
			line-height: 25px;
			position: relative;
			text-decoration: none;
			z-index: 200;
			padding: 0 5px;
        }

#lava {
	background-color: #e57807;
	position:absolute;
	left:0;
	top:0;
	height:0;
	width:0;
	z-index:100;
}
</code></pre>
<p>Градиент сделан при помощи тулзы <a href="http://www.colorzilla.com/gradient-editor/" rel="nofollow external">Ultimate CSS Gradient Generator</a><p>

<pre><code class="javascript">
jQuery(document).ready(function($){
	$("#lavalamp")
		.delegate("li","mouseenter",null,function(){
			var self = $(this);
			$("#lava").stop().animate({
				top : self.offset().top,
				left : self.offset().left,
				width : self.outerWidth(true),
				height : self.outerHeight(true)
			})
		})
		.delegate("li","click",null,function(){
			alert($(this).text());
		})
		.bind("mouseleave",null,function(){
			$(".active",this).eq(0).trigger("mouseover");
		})
		.trigger("mouseout");
});
</code></pre>

<p><p>
<p><p>
<p><p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/11/27/lavalamp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Легкий список</title>
		<link>http://mabp.kiev.ua/2010/11/23/lightweight-list/</link>
		<comments>http://mabp.kiev.ua/2010/11/23/lightweight-list/#comments</comments>
		<pubDate>Tue, 23 Nov 2010 19:26:17 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1302</guid>
		<description><![CDATA[Давно я не писал ничего полезного, от части потому что не было реальных заданий от части потому, что последние время их было слишком много. А сегодня я расскажу как сделать красивый и "легкий" список. Для списка я использовал jQueryUI, а вы можете написать все стили руками, если есть желание. Итак сначала пример, а потом разбор [...]]]></description>
			<content:encoded><![CDATA[<p>Давно я не писал ничего полезного, от части потому что не было реальных заданий от части потому, что последние время их было слишком много. А сегодня я расскажу как сделать красивый и "легкий" список.</p>
<span id="more-1302"></span>

<link rel="stylesheet" type="text/css" media="screen" href="/content/css/lightweight-list.css"/>
<script type="text/javascript" src="/content/js/lightweight-list.js"></script>


<p>Для списка я использовал jQueryUI, а вы можете написать все стили руками, если есть желание. Итак сначала пример, а потом разбор кода.</p>

<div class="container ui-widget ui-widget-content ui-corner-all">
	<ul id="list">
		<li value="1">Один</li>
		<li value="2">Два</li>
		<li value="3">Три</li>
		<li value="4">Четыре</li>
		<li value="5">Пять</li>
	</ul>
	<div class="controls">
		<span class="ui-state-default ui-corner-all" title=""><span class="ui-icon ui-icon-pencil"></span></span><span class="ui-state-default ui-corner-all" title=""><span class="ui-icon ui-icon-close"></span></span>
	</div>
</div>




<p>Итак в разметке ничего страшного нет, это простой список и две кнопочки: "редактировать", "удалить".</p>

<pre><code class="html">
&lt;div class="container ui-widget ui-widget-content ui-corner-all"&gt;
	&lt;ul id="list"&gt;
		&lt;li value="1"&gt;Один&lt;/li&gt;
		&lt;li value="2"&gt;Два&lt;/li&gt;
		&lt;li value="3"&gt;Три&lt;/li&gt;
		&lt;li value="4"&gt;Четыре&lt;/li&gt;
		&lt;li value="5"&gt;Пять&lt;/li&gt;
	&lt;/ul&gt;
	&lt;div class="controls"&gt;
		&lt;span class="ui-state-default ui-corner-all" title=""&gt;&lt;span class="ui-icon ui-icon-pencil"&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class="ui-state-default ui-corner-all" title=""&gt;&lt;span class="ui-icon ui-icon-close"&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;/div&gt;
&lt;/div&gt;
</code></pre>

<pre><code class="css">
.container {
	width: 300px;
	position:relative;
}
#list {
	padding: 10px;
}
#list li {
	line-height: 18px;
	list-style: none outside none;
	padding: 1px;
	border: 1px solid transparent;
}
.controls {
	cursor:pointer;
	display:none;
	position:absolute;
	right: 10px;
	font-size: 1px;
	padding: 2px;
}
.controls span {
	display: block;
	float : left;
	width : 16px;
	height  : 16px;
	line-height: 0 !important; /*перекрываю стили вордпресса */
}
</code></pre>

<p>CSS тоже достаточно просто, кроме того что я даю контейнеру position:relative, это позволяет задать контролам right: 10px и не высчитывать положение по левой стороне, более того это еще удобно тем что в таком случаи контролов может быть разное количество для разных элементов списка.</p>

<p>А теперь самое интересное.</p>
<pre><code class="javascript">
$(document).ready(function(){

	function doSomething(){
		alert("I'm dummy function");
	}
	
	$("#list")
		.delegate("li","mouseenter",null,function(){
			var self = $(this);
			id = self.attr("value")
			self.addClass("ui-state-hover").siblings(".ui-state-hover").removeClass("ui-state-hover");
			self.parent().siblings(".controls").show().css({top:self.position().top});
		})
		.delegate("li","click",null,function(){
			var self = $(this);
			doSomething(self.attr("value"));
		})
		.parent()
		.bind("mouseleave",null,function(){
			var self = $(this);
			self.find("li.ui-state-hover").removeClass("ui-state-hover");
			self.find(".controls").hide();
		})
		.find(".ui-state-default")
		.bind("mouseenter",null,function(){
			$(this).addClass("ui-state-hover");
		})
		.bind("mouseleave",null,function(){
			$(this).removeClass("ui-state-hover");
		})
		.end()
		.find(".ui-icon-close")
		.bind("click",null,function(){
			doSomething(id);
		})
		.end()
		.find(".ui-icon-pencil")
		.bind("click",null,function(){
			doSomething(id);
		});
})
</code></pre>

<p>Сначала делегируем списку событие появления курсора над конкретным элементом, это дает возможность подсветить его (элемент), и пододвинуть к нему контролы. mouseover тут использовать нельзя потому что при наведении на котнролы они получат mouseover и пропадет подсветка на  элементе и получиться мигание. По этой же причине mouseleave повешен не на список а на его родителя.</p>

<p>Дальше все предельно просто - навешены события на раскрашивание и подсвечивание контролов.</p>

<p>ЗЫ если остался вопрос почему список легкий - потому что события навешиваються не на каждый элмент а дедегируються родителю. Вторая причина это то, что используеться только две кнопки для создания контролов, вместо того чтобы при наведении на каждый элемент динамически создавать новые и добавлять их в дом дерево, или делать видимыми уже существующие.</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/11/23/lightweight-list/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Демка для канадцев</title>
		<link>http://mabp.kiev.ua/2010/10/28/demo-for-canadians/</link>
		<comments>http://mabp.kiev.ua/2010/10/28/demo-for-canadians/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 09:01:49 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[tree]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1280</guid>
		<description><![CDATA[Ну в общем все знают что я сейчас без работы, то есть на вольных хлебах. О том как я хлебаю я и буду рассказывать. Вот давече нашел каких-то noname канадцев, склепал им демку, но договориться не удалось. Собственно особенности демки: jqGrid, jsTree, Layouts. Без особой фантазии скреплено друг с другом - обычное бизнес приложение. Такие [...]]]></description>
			<content:encoded><![CDATA[<p>Ну в общем все знают что я сейчас без работы, то есть на вольных хлебах. О том как я хлебаю я и буду рассказывать.</p>
<span id="more-1280"></span>
<p>Вот давече нашел каких-то noname канадцев, склепал им <a href="http://mabp.kiev.ua/content/source/uberfine/" rel="nofollow external">демку</a>, но договориться не удалось. </p>
<p>Собственно особенности демки: <a href="http://www.trirand.com/blog/" rel="nofollow external">jqGrid</a>, <a href="http://www.jstree.com/" rel="nofollow external">jsTree</a>, <a href="http://layout.jquery-dev.net/" rel="nofollow external">Layouts</a>. Без особой фантазии скреплено друг с другом - обычное бизнес приложение. Такие кстати на ExtJS, наверное, лучше делать. Самым примечательным является D&#038;D между таблицей и деревом и изменение размеров аккордеона и таблицы при изменении размеров панели. Тыкайтесь :)</p>

<p>А ну и к случаю обновил пару статей: <a href="http://mabp.kiev.ua/2010/01/31/jqgrid/">jqGrid</a>, <a href="http://mabp.kiev.ua/2009/12/08/paint/">Paint</a>, <a href="http://mabp.kiev.ua/2009/12/10/ui-layout/">UI.Layout</a>. И соответствующие библиотеки до последних версий.</p>




]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/10/28/demo-for-canadians/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flowplayer</title>
		<link>http://mabp.kiev.ua/2010/09/11/flowplayer/</link>
		<comments>http://mabp.kiev.ua/2010/09/11/flowplayer/#comments</comments>
		<pubDate>Sat, 11 Sep 2010 17:34:42 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Видео]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Разное]]></category>
		<category><![CDATA[hate]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1251</guid>
		<description><![CDATA[Сегодня я пролью свои лучи поноса ненависти на Flowplayer. В двух словах - редкостная хуета! Дальше кодом... А забыл описать задачу. Нужен плеер в попапе, плейлист на странице в виде html (но если надо пара секунд переделать под ajax), у плеера есть две кнопки (вперед, назад) с превьюшками видео. Погнали. Пример разметки одного элемента списка [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня я пролью свои лучи <del>поноса</del> <a href="http://mabp.kiev.ua/tag/hate/">ненависти</a> на Flowplayer.</p>

<p>В двух словах - редкостная хуета! Дальше кодом... А забыл описать задачу. Нужен плеер в попапе, плейлист на странице в виде html (но если надо пара секунд переделать под ajax), у плеера есть две кнопки (вперед, назад) с превьюшками видео. Погнали.</p>

<span id="more-1251"></span>

<script type="text/javascript" src="/content/source/flowplayer/flowplayer-3.2.4.min.js"></script>
<script type="text/javascript" src="/content/js/flowplayer.js"></script>

<p>Пример разметки одного элемента списка</p>
<pre><code class="html">
&lt;div style="float:left; text-align:center; margin:5px;"&gt;
	&lt;a class="progress" href="${video_link}.flv" title="${title}"&gt;
		&lt;img src="${thrumbnail_link}" alt="${title}"&gt;
	&lt;/a&gt;
	&lt;a class="progress" href="${video_link}.png" title="${title}"&gt;
		${title}
	&lt;/a&gt;
&lt;/div&gt;
</code></pre>

<p>Конфигурация плеера с комментариями</p>

<pre><code class="javascript">
$(document).ready(function(){

	// конфигурация плеера
	var player = $f("player", 
	{
		// сам плеер 
		src : "/content/source/flowplayer/flowplayer-3.2.4.swf", 
		// и дополнительные параметры
		wmode: 'transparent'
	}, 
	{
		//debug : true,
		
		// стандартный клип
		clip : {
			// можно не указывать если полный путь прописан в html
			baseUrl: 'http://blip.tv/file/get/',
			// сразу при запуске не играем
			autoPlay: false,
			// но закачиваем
			autoBuffering: true,
			// растягиваем видео
			scaling : 'scale',
			// перед проигрыванием
			onBeforeBegin : function(clip){
				// если вместо видео картинка контролы не показываем
				if  (clip.type == "image"){
					this.getControls().hide();
				}
				
				// вычисляем позицию в списке воспроизведения
				var clip = this.getClip(),
					list = this.getPlaylist(),
					current = $.inArray(clip, list),
					left = current - 1  &gt;= 0 ? current - 1 : list.length - 1,
					right = current + 1 &lt;= list.length - 1 ? current + 1 : 0;
				
				// обновляем кнопки вперед-назад
				this.getPlugin("leftButton")
					.setHtml("&lt;p&gt;"+list[left].title+"&lt;/p&gt;")
					.css({
						background : "transparent url("+list[left].thumbnail+") no-repeat 20 20",
					});
					
				this.getPlugin("rightButton")
					.setHtml("&lt;p&gt;"+list[right].title+"&lt;/p&gt;")
					.css({
						background : "transparent url("+list[right].thumbnail+") no-repeat 20 20",
					});
			}
		},
		
		// список у нас береться из html
		// поэтому тут пусто
		playlist: [	],
		
		// рисуем кнопки
		// поскольку плеер очень убогий, для рисования кнопки
		// которая сначала видна чуть-чуть а при наведении мышьки 
		// расширяется и становиться видно превьюшку следующего видео
		// надо рисовать две кнопки одна маленькая, видна всегда и не меняется,
		// а вторая находиться поверх нее и собственно все события висят на ней
		plugins:  {
			
			// левая маленькая кнопка
			leftFake : {
				url: '/content/source/flowplayer/flowplayer.content-3.2.0.swf',
				top: 130,
				right : 0,
				width : 20,
				height : 100,
				zIndex : 1,
				opacity : 1,
				borderRadius : 0,
				background : "url(/content/source/flowplayer/mp_leftArrow.png) no-repeat 0 0"
			},
			
			// правая маленькая кнопка
			rightFake : {
				url: '/content/source/flowplayer/flowplayer.content-3.2.0.swf',
				top: 130,
				left : 0,
				width : 20,
				height : 100,
				zIndex : 1,
				opacity : 1,
				borderRadius : 0,
				background : "url(/content/source/flowplayer/mp_rightArrow.png) no-repeat 0 0"
			},
			
			controls: {
				//playlist: true,
		
				// ссылка на плагин
				url: '/content/source/flowplayer/flowplayer.controls-3.2.2.swf', 
				// показывать все элементы управления
				all: false,
				// играть
				play: false,
				// ползунок
				scrubber: true,
				// громкость
				volume: true,   
				// тонкая настройка ползунка и громкости
				scrubberHeightRatio: 0.3,
				scrubberBarHeightRatio: 0.2,
				volumeSliderHeightRatio: 0.2,
				// убирать с экрана при бездействии
				autoHide: 'always',
				// еще раз прячем контролы если смотрим на картинку,
				// потому что он (контрол) тупой и с первого раза не понял
				onBeforeShowed : function(){
					if (this.getPlayer().getClip().type == "image"){
						return false;
					}
				},
				onBeforeHidden : function(){
					if (this.getPlayer().getClip().type == "image"){
						return false;
					}
				}
			},

			// рисуем настоящую большую кнопку
			leftButton : {
				// ссылка на плагин
				url:'/content/source/flowplayer/flowplayer.content-3.2.0.swf',
				// какойто CSS
				top: 130,
				left:0,
				width: 20,
				height: 100,
				zIndex : 5,
				opacity: 1,
				padding : 20,
				borderRadius : 10,
				style: {
					p : {
						fontSize:14,
						fontWeight:"bold",
						color:"#000000"
					}
				},
				// задаем анимацию при наведении мыши
				onMouseOver: function() {
					this.animate({width:140}, 500);
				},
				onMouseOut: function() {
					this.animate({width:20}, 500); 
				},
				// играем следующий клип при клике
				onClick : function(){
					var clip = this.getPlayer().getClip(),
						list = this.getPlayer().getPlaylist(),
						current = $.inArray(clip, list),
						index = current - 1  &gt;= 0 ? current - 1 : list.length - 1;
					
					this.getPlayer().play(index);
				}
			},
			
			// тут все тоже самое только для правой кнопки
			rightButton : {
				url: '/content/source/flowplayer/flowplayer.content-3.2.0.swf',
				top: 130,
				right: 0,
				width: 20,
				height: 100,
				zIndex : 5,
				opacity: 1,
				padding : 20,
				borderRadius : 10,
				style: {
					p : {
						fontSize:14,
						fontWeight:"bold",
						color:"#000000"
					}
				},
				onMouseOver: function() {
					this.animate({width:140}, 500);
				},
				onMouseOut: function() {
					this.animate({width:20}, 500); 
				},
				onClick : function(){
					var clip = this.getPlayer().getClip(),
						list = this.getPlayer().getPlaylist(),
						current = $.inArray(clip, list),
						index = current + 1 &lt;= list.length - 1 ? current + 1 : 0;
			
					this.getPlayer().play(index)
				}, 
			},
		},
		
		// при наведении мыши на плеер показываем все кноки
		onMouseOver : function(){
			var plugins = ["leftButton","rightButton","leftFake","rightFake"];
			for(var i in plugins){
				this.getPlugin(plugins[i]).show();
			}
		},
		
		// а при бездействии - убираем
		onMouseOut : function(){
			var plugins = ["leftButton","rightButton","leftFake","rightFake"];
			for(var i in plugins){
				this.getPlugin(plugins[i]).hide();
			}
		},
		
		// ну и еще пара проверок при загрузке
		onLoad : function(){
			var list = this.getPlaylist(),
				left = list.length - 1,
				right = 1;
			
			// если короткий список воспроизведения не показываем кнопуки
			if (list.length&lt;2){
				this.getPlugin("leftButton").hide();
				this.getPlugin("rightButton").hide();
			}else{
				this.getPlugin("leftButton")
					.setHtml("&lt;p&gt;"+list[left].title+"&lt;/p&gt;")
					.css({
						background : "transparent url("+list[left].thumbnail+") no-repeat 20 20",
					});
					
				this.getPlugin("rightButton")
					.setHtml("&lt;p&gt;"+list[right].title+"&lt;/p&gt;")
					.css({
						background : "transparent url("+list[right].thumbnail+") no-repeat 20 20",
					});
			}
		}		
	}),
	
	// обычный JUI диалог
	dialog = $("#videoDialog").dialog({
		//modal:true,
		title:"dialog title",
		resizable:false,
		bgiframe:true,
		draggable:true,
		autoOpen: false,
		width:600,
		height:400,
		minHeight:0,
		open:function(){
			// при открытии диалога загружаем плеер
			player.load();
			// и меняем плейлист
			// для вызова события onPlaylistReplace
			player.play(list);
		},
		close:function(){
			player.unload();
		}
	}),
	
	list = [],
	index = 0;
	
	// вызываеться при смене списка воспроизведения
	// например ajax'ом новый подгрузили
	player.onPlaylistReplace(function(list) {
		// чтото без таймаута не пашет :(
		setTimeout(function(){
			player.play(index);
		},100);
	});
	
	// при старте клипа меняем заголовок диалога
	player.onStart(function() {
		dialog.prev().find(".ui-dialog-title").text(this.getClip().title)
	});
	
	// меняет список воспроизведения
	function getNewPlaylist(){
		list = [];
		// парсит html
		$("#playlist").children().each(function(){
			var self = $(":first",this);
			list.push({
				"url": self.attr("href"),
				"title": self.attr("title"),
				"thumbnail" : self.find("img").attr("src")
			});
		});
		
		// гасим ссылки
		$("#playlist a").click(function(){
			$(this).parent().click();
			return false;
		});
		
		// открываем плеер и играем нужное видео
		$("#playlist").children().click(function(){
			if (!dialog.dialog("isOpen")){
				dialog.dialog("open");
			}
			index = $(this).index();
		});
		
	}
	
	// загружаем список в плеер
	getNewPlaylist();

});
</code></pre>

<p>И немного пощупать что получилось</p>

<div id="videoDialog">
	<a id="player" class="player">&nbsp;</a>
</div>

<div id="playlist" style="margin:auto; width: 440px;">
	<div style="float:left; text-align:center; margin:5px;">
		<a class="progress" href="http://blip.tv/file/get/KimAronson-TwentySeconds59483.flv" title="Palm trees and the sun">
			<img src="http://mabp.kiev.ua/content/source/flowplayer/palm.png">
		</a>
		<a class="progress" href="http://blip.tv/file/get/KimAronson-TwentySeconds59483.flv" title="Palm trees and the sun">
			Palm trees and the sun
		</a>
	</div>

	<div style="float:left; text-align:center; margin:5px;">
		<a class="progress" href="http://blip.tv/file/get/KimAronson-TwentySeconds58192.flv" title="Happy feet in a car">
			<img src="http://mabp.kiev.ua/content/source/flowplayer/feet.png">
		</a>
		<a href="http://blip.tv/file/get/KimAronson-TwentySeconds58192.flv" title="Happy feet in a car">
			Happy feet in a car
		</a>
	</div>

	<div style="float:left; text-align:center; margin:5px;">
		<a href="http://blip.tv/file/get/KimAronson-TwentySeconds63617.flv" title="People jogging">
			<img src="http://mabp.kiev.ua/content/source/flowplayer/park.png">
		</a>
		<a href="http://blip.tv/file/get/KimAronson-TwentySeconds63617.flv" title="People jogging">
			People jogging in park
		</a>
	</div>
</div>

<br clear="both">
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/09/11/flowplayer/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<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>jQuery UI: Progress Bar with custom event</title>
		<link>http://mabp.kiev.ua/2009/03/26/jquery-ui-progress-bar-with-custom-event/</link>
		<comments>http://mabp.kiev.ua/2009/03/26/jquery-ui-progress-bar-with-custom-event/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 14:29:21 +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[animation]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jqueryUI]]></category>
		<category><![CDATA[progress bar]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=928</guid>
		<description><![CDATA[Начитался Брэндона Аарона и решил создать небольшое практическое пособие для начинающих по пользовательским событиям (custom events). Напомню что пользовательские события это такие же события как onclick только запускает их не браузер а сам jQuery. Такими событиями являются, например, события "mouseenter", "mouseleave", "ready" и целый набор ajax'овых событий. jQuery также дает возможность создавать пользовательские события, чем [...]]]></description>
			<content:encoded><![CDATA[<p>Начитался <a href="http://brandonaaron.net/blog/2009/03/26/special-events" rel="nofollow external">Брэндона Аарона</a> и решил создать небольшое практическое пособие для начинающих по пользовательским событиям (custom events). Напомню что пользовательские события это такие же события как onclick только запускает их не браузер а сам <a href="http://mabp.kiev.ua/tag/jquery/" title="jQuery">jQuery</a>. Такими событиями являются, например, события "mouseenter", "mouseleave", "ready" и целый набор <a href="http://docs.jquery.com/Ajax_Events" rel="nofollow external">ajax'овых событий</a>. 
<p><a href="http://mabp.kiev.ua/tag/jquery/" title="jQuery">jQuery</a> также дает возможность создавать пользовательские события, чем я и воспользуюсь, создав собственное событие с помощью которого буду обновлять ползунок из <a href="http://mabp.kiev.ua/2009/01/28/modal-dialog-and-progress-bar/">Modal Dialog и Progress Bar</a>. Практическая польза от этого скрипта нулевая, но для демонстрации самое то что доктор прописал. На самом деле весь код описанный в событии можно перенести в стандартный callback 'change'. Итак задача: обновлять ползунок при помощи пользовательского события, при срабатывании события ползунок увеличивается и меняет цвет.</p>
<span id="more-928"></span>

<link rel="stylesheet" type="text/css" media="screen" href="/content/css/jquery-ui-progress-bar-with-custom-event.css"/>
<script type="text/javascript" src="/content/js/jquery-ui-progress-bar-with-custom-event.js"></script>


<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;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
&lt;head&gt;
&lt;title&gt;Progress Bar with custom event&lt;/title&gt;
&lt;script src="jquery-1.3.2.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="ui/ui.core.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="ui/ui.resizable.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="ui/ui.draggable.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="ui/ui.dialog.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="ui/ui.progressbar.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;link href="themes/smoothness/ui.core.css" type="text/css" rel="stylesheet" /&gt;
&lt;link href="themes/smoothness/ui.theme.css" type="text/css" rel="stylesheet" /&gt;
&lt;link href="themes/smoothness/ui.resizable.css" type="text/css" rel="stylesheet" /&gt;
&lt;link href="themes/smoothness/ui.dialog.css" type="text/css" rel="stylesheet" /&gt;
&lt;link href="themes/smoothness/ui.progressbar.css" type="text/css" rel="stylesheet" /&gt;

&lt;style&gt;
.ui-progressbar-indicator{
	line-height:40px;
	position:absolute;
	text-indent:-20px;
	left:50%;
}
&lt;/style&gt;

&lt;script type="text/javascript"&gt;
jQuery().ready(function($){

	var counter = 0, 
	dialog = $("&lt;div/&gt;")
		.dialog({modal:true,title:"Заголовок",overlay:{backgroundColor:'#000',opacity: 0.5}})
		.parent().find(".ui-dialog-titlebar-close").hide().end().end(),
	indicator = $("&lt;div/&gt;").addClass("ui-progressbar-indicator").text("0").appendTo(dialog),
	// создаю пользовательское событие myEvent
	// вторым параметром можно передавать null потому что он не используеться в примере
	// но я предпочитаю передавать this, тут this является контекстом функцией переданой параметром в jQuery().ready
	// тоесть window, но если этот объект не window то это единственный способ получить к нему доступ.
	// пример такого использования можно посмотреть в плагине autocomplete
	progressbar = $("&lt;div/&gt;").bind("myEvent", this, function(event,data){
			// event.data хранит данные переданые при создании события
			// тоесть event.data == window
			// data хранит данные переданые при срабатывании события 
			// тоесть data == {counter:counter}
			var 	c = data.counter,
				// процет цвета который заполняет ползунок
				seed = Math.round(255*c/100),
				// в HEX
				green = seed.toString(16),
				// форматируем до двух знаков
				green = green.length == 1 ? "0"+green : green,
				// процент цвета который покидает ползунок
				red = (255 - seed).toString(16),
				// его тоже форматируем
				red = red.length == 1 ? "0"+red : red;
			// увеличиваез значение индикатора
			indicator.text(c+"%");
			// удлиняем ползунок
			$(this).progressbar("value",counter);
			// закрашиваем ползунок новым цветом
			$("div",this).css({background:"#"+red+green+"00"});
		})
		.progressbar({value:0})
		.appendTo(dialog),
	// имитируем длительный процесс
	interval = setInterval(function () {
		counter+=1;
		progressbar.trigger("myEvent",{counter:counter});
		if (counter == 100) {
			clearInterval(interval);
			setTimeout(function(){
				progressbar.progressbar("destroy");
				dialog.dialog("destroy");
				indicator.remove();
			},50);
		}
	}, 50);
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<input type="button" id="example" value="Позырить результат"/>
<br />
<p>Более подробные комментарии можно посмотреть в <a href="http://mabp.kiev.ua/2009/01/28/modal-dialog-and-progress-bar/">Modal Dialog и Progress Bar</a></p>
<br />]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/03/26/jquery-ui-progress-bar-with-custom-event/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

