I am looking at creating an event and reservation system.
I found the Stack Overflow question jQuery - Mobile date picker control which shows jquery-mobile-datebox and jQuery-Mobile-Themed-DatePicker.
I want to display a calendar where certain dates I get from the server are
When a reserved or available date is touched, I want to show times - there can be more than one time per day. The user can then click on a time to reserve it which would hit off an Ajax request.
jQuery UI datepicker, for example, has
onSelect: function(date, inst) {
From what I can see in the above pickers, what I need is not readily available. Before I start hacking them myself:
UPDATE:
Firebug gave me
<div class="ui-datebox-griddate ui-corner-all ui-btn-up-e" data-date="25" data-theme="e">25</div>
where ui-btn-up-e can be changed from a - e.
Now I need to find out if data-theme also needs to be changed
$('.ui-datebox-griddate').click(function () {
alert($(this).attr("class"));
}
What is the nicest way to toggle through three of the classes and save the state each time?
$('.ui-datebox-griddate').toggle(
function () {
$(this).????? // change ui-btn-up-? to ui-btn-up-a
$.get(...)
},
function () {
$(this).????? // change ui-btn-up-a to ui-btn-up-b
$.get(...)
},
function () {
$(this).????? // change ui-btn-up-b to ui-btn-up-c
$.get(...)
}
);
UPDATE: NOTE: When I click, the calendar change the date, reloading the calendar completely. Perhaps I need to stop that :(
What is the nicest way to toggle through three of the classes and save the state each time?
Something like:
$('.ui-datebox-griddate').click(function (e) {
var $this = $(this);
var cycle = ["ui-btn-up-a", "ui-btn-up-b", "ui-btn-up-c"];
if (typeof $this.data("ui-btn-cycle") == "undefined" ) {
this.className = this.className.replace(/ui-btn-up-./, cycle[0]);
$this.data("ui-btn-cycle", cycle[0]);
}
for (var i=0; i<cycle.length; i++) {
if ( $this.hasClass(cycle[i]) ) {
$this.removeClass(cycle[i]).addClass(cycle[i % cycle.length]);
$this.data("ui-btn-cycle", [i % cycle.length]);
break;
}
}
$.get( ... );
e.preventDefault() // stop default click behaviour
});
This can cycle though an arbitrary amount of classes. The current state would be available through calling .data("ui-btn-cycle")
on the respective element.
This is even nicer:
$('.ui-datebox-griddate')
.each(function () {
var cycle = ["ui-btn-up-a", "ui-btn-up-b", "ui-btn-up-c"];
$(this).data("ui-btn-cycle", cycle);
this.className = this.className.replace(/ui-btn-up-./, cycle[0]);
})
.click(function (e) {
var cycle = $(this).data("ui-btn-cycle");
$(this).removeClass(cycle[0]).addClass(cycle[1]);
cycle.push(cycle.shift());
e.preventDefault();
});
The current state would always be .data("ui-btn-cycle")[0]
on the respective element. See it working here: http://jsfiddle.net/Tomalak/mAH4n/
Based on what J.T.Sage said I thought I would have a play with jQuery Mobile Calendar. I think I have something which could potentially be extended to fulfil your requirements. I am not sure to what extent multi-colour themeing would be possible (without extensive modifications).
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQueryMobile - DateBox Demos</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b1/jquery.mobile-1.0b1.min.css" />
<link type="text/css" href="http://dev.jtsage.com/cdn/datebox/latest/jquery.mobile.datebox.min.css" rel="stylesheet" />
<!-- NOTE: Script load order is significant! -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript">
$( document ).bind( "mobileinit", function(){ $.mobile.page.prototype.options.degradeInputs.date = 'text'; });
</script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0b1/jquery.mobile-1.0b1.min.js"></script>
<script type="text/javascript" src="http://dev.jtsage.com/cdn/datebox/latest/jquery.mobile.datebox.min.js"></script>
<script type="text/javascript">
$('#page').live('pagecreate', function(event) {
$('#mydate').bind('change', function () {
alert($(this).val());
});
});
</script>
</head>
<body>
<div id="page" data-role="page">
<div data-role="content">
<input name="mydate" id="mydate" type="date" data-role="datebox" data-options='{"mode": "calbox", "calHighToday": false, "calHighPicked": false, "useInline": true, "useInlineHideInput": true, "highDates": ["2011-06-25", "2011-06-27", "2011-07-04"]}'></input>
</div>
</div>
</html>
UPDATE
I suppose the highDates mechanism could be bypassed completely and the individual days uniquely targeted. The plugin maintains a JavaScript Date object of the last date selected (or today if nothing has been selected) - so it should be possible to get the current month and iterate through all your matching data updating the matching days in the current month as appropriate (e.g. replacing the setColours method below with something that is data/state aware).
<script type="text/javascript">
$('#page').live('pagecreate', function(event) {
$('#mydate').bind('change', function () {
//alert($(this).val());
alert($('#mydate').data('datebox').theDate);
});
setColours();
$('#mydate').bind('datebox', function (e, pressed) {
setColours();
});
$('.ui-datebox-gridplus, .ui-datebox-gridminus').bind('vclick', function(){
// To handle changing months
setColours();
//alert($('#mydate').data('datebox').theDate);
});
function setColours(){
$('div.ui-datebox-griddate[data-date=25][data-theme]').css({"background-color":"red", "background-image":"none", "color" : "white"});
$('div.ui-datebox-griddate[data-date=26][data-theme]').css({"background-color":"green", "background-image":"none", "color" : "white"});
$('div.ui-datebox-griddate[data-date=27][data-theme]').css({"background-color":"blue", "background-image":"none", "color" : "white"});
}
});
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With