JQuery UI stle time picker plugin

Er bleek naar mijn smaak geen geschikte timepicker plugin te bestaan voor jQuery, daarom ben ik zelf aan de slag gegaan. De plugin is compatible met jqueryUI. De bedoeling is om de code nog verder te refactoren om daarbij gebruik te maken van jqueryUI widgetfactory.

Update : 15-09-2010 --> versie 1.2 is online

Example form:

tijd1:

tijd2:

tijd3:

tijd4:



Select a jqueryUI theme :



A code example :



		$(document).ready(function(){
		/*
		$.timepicker({
			'hour24': [0,1,2,'-->',7,8,'skip',14,15,16,'**',22,23]
		});//common format
		*/
		$("input[name='tijd1']").timepicker({
			'minDivision'  	       	: 10,
			'closeOnFormclick'		: true,
			'button'		  		: 'set time',//button-caption
			'buttonCSS'				: {'width':'10em'},
			'inputReadOnly'			: true
		});
			
		$("input[name='tijd2']").timepicker({'button':'image'});//button-caption
			
		$("input[name='tijd3']").timepicker({ 
			'minDivision'   : [10,30,45],
			'button'	    : 'default',
			'hourFormat'	: 12,// 12 or 24
			'inputReadOnly'	: true
		});
			
		$("input[name='tijd4']").timepicker({
		    
			'hourAM'          		: [12,1,'-->',8,9,10,11],// AM hours
			'hourPM'          		: [12,1,2,3,'-->',8,9,10,11],// PM hours
			'hourFormat'	  		: 12,// 12 or 24
			'hourCols'		  		: 8,// 6 or 8 columns
			'closeOnComplete'	    : false
		});
			
	});
	
	

default settings :



Just change the properties of the [options] object to overrule the default settings.

	
	
	$.fn.timepicker.defaults = {
		'hour24'          : [0,1,2,3,4,5,6,7,8,9,10,11,12,13,
					14,15,16,17,18,19,20,21,22,23],//24h format
		'hourAM'          : [12,1,2,3,4,5,6,7,8,9,10,11],// AM hours
		'hourPM'          : [12,1,2,3,4,5,6,7,8,9,10,11],// PM hours
		'hourFormat'	  : 24,// 12 or 24
		'hourCols'		  : 8,// 6 or 8 columns	
		'minDivision'  	  : 15,//minutebutton captions format array [12,24,36,48,52],
					or preformat values  5, 10, 12, 15, 20, 30 
		'openOnClick'     : true,
		'beforeShow'      : function(event){},//event
		'onSelect'        : function(event, complete){},//event   
		'onClose'         : function(event){},//event
		'hourCaption'     : 'first choose the hour',
		'minuteCaption'   : 'Then choose the desired time',
		'offsetLeft'      : 0,//adjust
		'offsetTop'       : 0,//adjust
		'closeOnFormclick': false
	};
	


Documentation timepicker:

jquery ui style timepicker plugin 


Easy to intergrate in a form. The timepicker is attached to one ore more input textfields, so the user can select any moment in time , in a format predefined by the developer. Fully customizable, uses jqueryUI css, theme switching possible by jqueryUI themeswitcher


optionsdefault valuedescriptionremark
hour240,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]format24 hours , e.g. 0,1,'skip',9,10,11,12,13,14,'-->',18,19,20,21string values are shown as disabled buttons
hourAM12,1,2,3,4,5,6,7,8,9,10,11AM hoursstring values are shown as disabled buttons
hourPM12,1,2,3,4,5,6,7,8,9,10,11PM hoursstring values are shown as disabled buttons
hourFormat12 or 24 AM/PM or 24h format
hourCols86 or 8
minDivision15specify an array with minutevalues or use one of the built-in formats array {value1'value2,...valueN} or preformat : number{5,10,12,15,20,30}
inputReadOnly true or false disables the inputbox false : no textinput possible
beforeShowfunction(event){}timepicker-event event triggered before display timepicker, returns event
onSelectfunction(event,complete){}timepicker-event event triggerd on hour select : returns event and complete=false, next event triggerd on minute select : returns event and complete=true
onClosefunction(event){}timepicker-event triggers just before timepicker closes
hourCaptionFirst choose the whole hour caption value string:{caption}
minuteCaptionThen choose the right time caption value string:{caption}
button''string:{caption} or keyword string {image}, string{default}caption : displays button with caption, image:displays image clock.png, default:displays jqueryUI clock button
buttonObj{}custombutton css jquery css-object : {'width':'10em'} or e.g. {'background','transparent url(img/myImg.png) no-repeat'}
offsetLeft0adjust finetunes position
offsetTop0adjust finetunes position
closeOnFormclickfalse hides timepicker on external click triggers on every element without class="ui-..."




Download JQuery UI Timepicker here Download JQuery here Further documentation will be available soon
See also the projectpage code.google.com/p/jquery-uistyle-timepicker/

© Aaldert van Weelden



Migration of jquery plugin from 1.7 to 1.8 widgets

I needed the jquery checkbox plugin, but no version for jqueryUI 1.8.2 was available, so I decided invest some time to adapt the plugin to version 1.8




jQuery UI Checkbox 0.1 :

 /*
 * jQuery UI Checkbox 0.1
 *
 * Copyright (c) 2009 Jeremy Lea <reg@openpave.org>
 * Dual licensed under the MIT and GPL licenses.
 *
 * http://docs.jquery.com/Licensing
 *
 * Based loosely on plugin by alexander.farkas.
 * http://www.protofunc.com/scripts/jquery/checkbox-radiobutton/
 * migrated to jqueryUI 1.8.4 by Aaldert van Weelden http://vanweeldencodeprojects.eu
 */

(function($){

// Set up IE for VML if we have not done so already...
if ($.browser.msie) {
	// IE6 background flicker fix
	try	{
		document.execCommand('BackgroundImageCache', false, true);
	} catch (e) {}

	if (!document.namespaces["v"]) {
		$("head").prepend("<xml:namespace ns='urn:schemas-microsoft-com:vml' prefix='v' />");
		$("head").prepend("<?import namespace='v' implementation='#default#VML' ?>");
	}
}

$.widget("ui.checkbox", {
	_create: function() {
		// XXX: UI widget will not actually fail...
		if (!this.element.is(":radio,:checkbox")) {
			return false;
		}
		// _radio stores the members of the radio group (if there is one).
		if (this.element.is(":radio")) {
			this._radio = $(this.element[0].form).find("input:radio")
				.filter('[name="'+this.element[0].name+'"]');
		} else {
			this._radio = false;
		}

		var self = this, o = this.options; // closures for callbacks.
		// Set the ARIA properties on the native input
		this.element
			.attr({
				role: (this._radio ? "radio" : "checkbox"),
				"aria-checked": !!this.element[0].checked
			});
		// Create the main wrapper element (which gives the background box)
		this._wrapper = this.element.wrap($("<span />")).parent()
			.addClass((this._radio ? "ui-radio" : "ui-checkbox") +
				" ui-state-default");
		// Create the icon element
		this._wrapper.prepend($("<span/>")
			.addClass("ui-icon " + this._icon(false))
			.click(function(event) {
				// The icon covers the entire box, but is not in a bubbling
				// path, so use it to trigger the native event, and let it
				// take care of the rest.  Gobble up this fake event.
				self.element[0].click();
				event.preventDefault();
				event.stopImmediatePropagation();
				return false;
			}));
		if ($.browser.msie) {
			// IE does not support rounded corners...  We should check
			// something to see if it does.   But anyway, we make another
			// element which is a VML roundrect, and hide the normal wrapper.
			//
			// XXX: Check if we can use this in place of the span.
			// XXX: Implement background images.
			// XXX: Tidy this up to be more jQuery'ish
			//
			// Play tricks to get around arcsize bugs...
			this._wrapper[0].insertAdjacentHTML("afterBegin",
				"<v:roundrect arcsize='" + (this._radio ? "1" : "0.1") +
				"'><v:stroke /><v:fill /></v:roundrect>");
			this._vml = this._wrapper[0].childNodes[0];
			var ss = this._wrapper[0].currentStyle;
			this._vml.style.top = "-1px";
			this._vml.style.left = "-1px";
			this._vml.style.width = parseInt(ss.width)+1+"px";
			this._vml.style.height = parseInt(ss.height)+1+"px";
			this._doVML();
			this._vml.style.visibility = "visible";
			this._wrapper.css('visibility','hidden');
			// Listen for class or other changes to recreate the elements.
			this._wrapper[0].onpropertychange = function() {
				switch (event.propertyName) {
				case 'className':
				case 'style.borderTopWidth':
				case 'style.borderTopColor':
				case 'style.backgroundColor':
				case 'style.filter':
					self._doVML();
					break;
				}
			}
			// Listen for the custom event from the theme switcher.
			$().bind('ui-theme-switch', function() {
				setTimeout(function() {
					self._doVML();
				}, 500);
				return false;
			});
		}
		if ($.browser.opera) {
			// Opera also does not support rounded corners...  Use an SVG
			// element instead.  Same as above, but a little simpler.
			//
			// XXX: Check if we can use this in place of the span.
			// XXX: Implement background images.
			// XXX: Tidy this up to be more jQuery'ish
			var svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
			var rect = document.createElementNS("http://www.w3.org/2000/svg","rect");
			var ss = this._wrapper[0].currentStyle;
			rect.setAttributeNS(null, "x", "1px");
			rect.setAttributeNS(null, "y", "1px");
			rect.setAttributeNS(null, "width", ss.width);
			rect.setAttributeNS(null, "height", ss.height);
			rect.setAttributeNS(null, "rx", (this._radio ? "6px" : "2px"));
			svg.appendChild(rect);
			this._wrapper.prepend(svg);
			this._svg = this._wrapper[0].firstChild;
			this._svg.style.width = parseInt(ss.width)+2+"px";
			this._svg.style.height = parseInt(ss.height)+2+"px";
			this._doSVG();
			this._svg.style.visibility = "visible";
			this._wrapper.css('visibility','hidden');
			// Listen for class changes.
			this._wrapper.bind("DOMAttrModified", function(event) {
				if (event.attrName === 'class') {
					self._doSVG();
				}
			});
			// Listen for the custom event from the theme switcher.
			$().bind("ui-theme-switch", function() {
				self._doSVG();
				return false;
			});
		}

		// Set up events...
		this._wrapper
			.hover(function(event) {
				if (!o.disabled) {
					$(this).addClass("ui-state-hover");
				}
			}, function(event) {
				if (!o.disabled) {
					$(this).removeClass("ui-state-hover");
				}
			})
			.bind("mousedown", function(event) {
				if (!o.disabled) {
					$(this).addClass("ui-state-active");
				}
			})
			.bind("mouseup", function(event) {
				if (!o.disabled) {
					$(this).removeClass("ui-state-active");
				}
			})
			.bind(this.widgetEventPrefix + "focus", function(event) {
				if (!o.disabled) {
					if (self._radio) {
						self._radio.not(self.element)
							.removeClass("ui-state-focus");
					}
					$(this).addClass("ui-state-focus");
				}
			})
			.bind(this.widgetEventPrefix + "blur", function(event) {
				if (!o.disabled) {
					$(this).removeClass("ui-state-focus");
				}
			})
			.bind(this.widgetEventPrefix + "click", function(event) {
				if (!o.disabled) {
					if (self._radio) {
						self._radio.not(self.element).checkbox("uncheck");
						self.check();
					} else {
						self.toggle();
					}
				}
			});
		this.element
			.bind("focus." + this.widgetName, function(event) {
				self._trigger("focus", event); // Actually checkboxfocus
			})
			.bind("blur." + this.widgetName, function(event) {
				self._trigger("blur", event); // Actually checkboxblur
			})
			.bind("click." + this.widgetName, function(event) {
				self._trigger("click", event); // Actually checkboxclick
			});

		// Capture the initial value
		this._setOption("checked", !!this.element[0].checked);
	},
	destroy: function() {
		this._wrapper.replaceWith(this.element);
		this.element.removeAttr("role")
			.removeAttr("aria-checked")
			.unbind("."+this.widgetName);

		$.Widget.prototype.destroy.apply(this, arguments);
	},

	// Most of the work is done here.
	_setOption: function(key, value) {
		$.Widget.prototype._setOption.apply(this, arguments);

		if (key == "disabled") {
			if (value) {
				this.element.attr("disabled","disabled");
				this._wrapper.removeClass("ui-state-focus ui-state-hover ui-state-active");
			} else {
				this.element.removeAttr("disabled");
			}
			this._wrapper
				[value ? "addClass" : "removeClass"](
					this.widgetName + "-disabled " +
					this.namespace + "-state-disabled");
		} else if (key == "checked") {
			this.element[0].checked = !!value;
			this.element.attr("aria-checked", !!value);
			this._wrapper.find(".ui-icon")
				.addClass(this._icon(!!value))
				.removeClass(this._icon(!value));
		}
	},

	check: function() {
		this._setOption("checked", true);
	},
	uncheck: function() {
		this._setOption("checked", false);
	},
	toggle: function() {
		this._setOption("checked", !this._getData("checked"));
	},

	_icon: function(state) {
		if (this._radio) {
			return "ui-icon-"
				+ this.options[state?"radioChecked":"radioUnchecked"];
		} else {
			return "ui-icon-"
				+ this.options[state?"checkboxChecked":"checkboxUnchecked"];
		}
	},

	_opacityFixed: false,
	_inFixup: false,
	_fixStyle: function(jq, re) {
		var s = jq.attr("style").replace(re,"");
		if (s !== "") {
			jq.attr("style",s);
		} else {
			jq.removeAttr("style");
		}
	},
	// Only called for IE
	_doVML: function() {
		if (!this._vml || this._inFixup) {
			return;
		}
		this._inFixup = true;
		var ss, op;
		if (this._opacityFixed) {
			this._vml.childNodes[0].opacity = '1';
			this._vml.childNodes[1].opacity = '1';
			this._fixStyle(this._wrapper.find(".ui-icon"),/filter[^;]*\;?/i);
			this._fixStyle(this._wrapper,/filter[^;]*\;?/i);
			this._opacityFixed = false;
		}
		ss = this._wrapper[0].currentStyle;
		// IE6 needs both of these...
		this._vml.strokecolor = ss.borderTopColor;
		this._vml.strokeweight = ss.borderTopWidth;
		this._vml.fillcolor = ss.backgroundColor;
		this._vml.childNodes[0].color = ss.borderTopColor;
		this._vml.childNodes[0].weight = ss.borderTopWidth;
		this._vml.childNodes[1].color = ss.backgroundColor;
		if (ss.filter && ss.filter.search(/Alpha/i) !== -1) {
			op = /(\d+)/.exec(ss.filter);
			this._wrapper.find(".ui-icon").css("filter",ss.filter);
			this._vml.childNodes[0].opacity = op[1]/100;
			this._vml.childNodes[1].opacity = op[1]/100;
			this._wrapper.css("filter","");
			this._opacityFixed = true;
		}
		this._inFixup = false;
	},
	// Only called for Opera
	_doSVG: function() {
		if (!this._svg || this._inFixup) {
			return;
		}
		this._inFixup = true;
		var ss, op;
		// Opera doesn't carry over opacity from the hidden container...
		if (this._opacityFixed) {
			this._fixStyle(this._wrapper.find(".ui-icon"),/opacity[^;]*\;?/i);
			this._fixStyle(this._wrapper.find("rect"),/opacity[^;]*\;?/i);
			this._fixStyle(this._wrapper,/opacity[^;]*\;?/i);
			this._opacityFixed = false;
		}
		ss = this._wrapper[0].currentStyle;
		this._svg.firstChild.style.stroke = ss.borderTopColor;
		this._svg.firstChild.style.strokeWidth = ss.borderTopWidth;
		this._svg.firstChild.style.fill = ss.backgroundColor;
		if (ss.opacity && ss.opacity !== 1) {
			op = ss.opacity;
			this._wrapper.find(".ui-icon").css("opacity",op);
			this._wrapper.find("rect").css("opacity",op);
			this._wrapper[0].style.opacity = "1";
			this._opacityFixed = true;
		}
		this._inFixup = false;
	}

});
$.ui.checkbox.prototype.options = {
	checkboxChecked: "check",
	checkboxUnchecked: "empty",
	radioChecked: "bullet",
	radioUnchecked: "empty"
};

})(jQuery);