Category Archives: jquery

Jquery Datepicker with Masked Input and Current Time

Examples of using a jquery ui datepicker with masked input and current time as input values. Input is editable for manual change of date and/or time.

Help in this post can from Adding time to jQuery UI Datepicker by Derek Allard and the Masked Input Plugin 1.3 by Josh Bush.

There are two functions:

  1. getTimeAmPm – formats time for standard AM/PM display
  2. getTime24 – format time for 24-hour display (sometimes called military time)
function getTimeAmPm() {

    var date_o = new Date();

    var date_mins = date_o.getMinutes() < 10 ? "0" + date_o.getMinutes() : date_o.getMinutes();

    var date_hours = date_o.getHours() > 12 ? "0" + (date_o.getHours() - 12) : date_o.getHours();

    var date_am_pm = date_o.getHours() < 12 ?  " AM" : " PM";

    // handle midnight
    date_hours = date_hours === 0 ? 12 : date_hours;

    return "'" + date_hours + ":" + date_mins + " " + date_am_pm + "'";
}

function getTime24() {

    var date_o = new Date();

    var date_hours = date_o.getHours() < 10 ? "0" + date_o.getHours() : date_o.getHours();

    var date_mins = date_o.getMinutes() < 10 ? "0" + date_o.getMinutes() : date_o.getMinutes();

    return "'" + date_hours + ":" + date_mins + "'";
}

The datepickers concatenate on the result from one of the time format functions and they both have the mask jquery plugin function by Josh applied to them:

$(".datepicker").datepicker({dateFormat: 'yy-mm-dd ' + getTimeAmPm()});

$(".datepicker").mask("9999-99-99 99:99 aa");

$(".datepicker24").datepicker({dateFormat: 'yy-mm-dd ' + getTime24()});

$(".datepicker24").mask("9999-99-99 99:99");

The HTML just has a couple of inputs for the examples:

<input class="datepicker" type="text" /> AM / PM
<br />
<input class="datepicker24" type="text" /> 24 hour

Recommended

Demo

Using jQuery Datepicker and Dialog Box To Select Date Range

Using a jquery datepicker in a jquery dialog box to select a date range is a handy, slick way of having users input dates. Date handling and validation in forms when input by the user can be tricky at best.

Here a modal dialog box will be used to allow the user to select a date range. That date range will be validated to ensure that it goes from a start date that is prior to the end date. Also, an alternate field will be populated by the datepicker that formats the dates in a specific way. This can be helpful if you are using the dates in a database query or other call that requires a certain format.

First we put a button to open the dialog box and the dialog box itself on the page:

<button id="selectDateRange">Select Date Range</button>	 

<div id="dialog" title="Select Date Range">
<div id="message"></div>
	<form name="dateRange" id="dateRangeForm" action="index.php" method="post">
    <label for="startdate">Start Date</label>
    <input id="startdate" type="text" readonly /><input type="hidden" name="startdate" 

id="start_alternate" />
    <label for="enddate">End Date</label>
    <input id="enddate" type="text" readonly /><input type="hidden" name="enddate" id="end_alternate" 

/>
    </form>
</div>

A message div is in the dialog box to send the user success or error messages related to their date selection. The input boxes are set to readonly so the user cannot type in a date; they must use the datepicker.

Then the jquery to set the datepicker to the appropriate input box in the dialog box, specify the alternate field and format, and specify min and max dates:

$("#startdate").datepicker({altField: '#start_alternate',altFormat: 'yy-mm-dd',minDate: '-1y',maxDate: -1});

$("#enddate").datepicker({altField: '#end_alternate',altFormat: 'yy-mm-dd',minDate: '-1y',maxDate: -1});

The minDate is set to a year from today (user cannot go back more than a year) with ‘-1y’ and the maxDate is set to yesterday (user cannot pick today or a future date) with -1. Check the jQuery documentation on the datepicker min and maxDates for further explanation.

And, of course, the code for the button that opens our dialog box:

$('button#selectDateRange').click(function(){
		$('#dialog').dialog('open');
	});

The dialog box code does several things including:

  • Closing the datepicker when the dialog closes
  • Checking for values in the input boxes
  • AJAX post to validate the date range (alternate javascript validation of date range included below)
  • Displaying a message to the user after validating the date range
  • Sets the additional dialog close button functions
$('#dialog').dialog({
    autoOpen: false,
    width: 400,
    modal: true,
    resizable: false,
    close: function() {
        $('#message').html("");
	    $('#dateRangeForm :input').each(function() {
	    $(this).val('');
	});
    },
    buttons: {
        "Close": function() {
            $(this).dialog("close");
	        $('#message').html("");
	        $('#dateRangeForm :input').each(function() {
	        $(this).val('');
	    });
	},
	"Submit": function() {
	    var errors = 0;
        $('#dateRangeForm :input').each(function() {
	        if($(this).val() == ''){
		       $(this).prev().prev().css("color", "red");
		       $(this).prev().val('Click box and use calendar to enter date.');
		       errors++;
		   } else {
		       $(this).prev().css("color", "black");
		   }
	   });

	  if (errors == 0){
	      dataString = $('form').serialize();
            $.ajax({
			    type: "POST",
			    url: "dateRange.php",
			    data: dataString,
			    dataType: "json",
			    success: function(data) {
			        if(data.error == "invalid"){
				    $('#message').html("<div class='errorMessage'>Date range is invalid.</div>");
			        } else {
				    $('#message').html("<div class='successMessage'>Date range is valid.</div>");
			        }
               } //end of success
            }); //end of ajax
         } //end of if(errors == 0)
      } //end of Submit button function
    } //end of buttons:
}); //end of dialog

Alternate method using javascript (no ajax call) to validate dates:

$('#dialog').dialog({
		autoOpen: false,
		width: 400,
		modal: true,
		resizable: false,
		close: function() {
			$('#message').html("");
			$('#dateRangeForm :input').each(function() {
				$(this).val('');
			});
		 },
		buttons: {
			"Close": function() {
				$(this).dialog("close");
				$('#message').html("");
			     $('#dateRangeForm :input').each(function() {
				$(this).val('');
					 });
			},
			"Submit": function() {
				var errors = 0;

				$('#dateRangeForm :input').each(function() {
					if($(this).val() == ''){
						$(this).prev().prev().css("color", "red");
						$(this).prev().val('Click box and use calendar to enter date.');
						errors++;
					} else {
						$(this).prev().css("color", "black");
					}
				 });

				if (errors == 0){
					var start_date = new Date($("#startdate").val());
					var end_date = new Date($("#enddate").val());
					if(end_date < start_date){
						$('#message').html("<div class='errorMessage'>Date range is invalid.</div>");
					}else{
						$('#message').html("<div class='successMessage'>Date range is valid.</div>");
					}
         } //end of if(errors == 0)
      } //end of Submit button function
   } //end of buttons:
}); //end of dialog

The daterange.php is pretty straightforward:

<?php
$start_date = new DateTime($_POST["startdate"]);
$end_date = new DateTime($_POST["enddate"]);

if ($start_date > $end_date){
    $return_json = '{"error":"invalid"}';
}else{
    $return_json = '{"error":"valid"}';
}

echo $return_json;
?>

Now, it entirely possible that you can validate the dates without a trip to the server; however, this example sets you up to use the dialog datepicker in more advanced processing or database calls on the server.

Recommended:

Demo

Targeting Dynamic Element IDs with jQuery

When elements are added dynamically through a scripting language (usually by a database pull) they can have sequential identifiers in one or more of their attributes. For this example, a series of checkboxes that, when checked, will populate an input box by matching up the numeric portion of the id attribute.

To make the matching easier to set up and understand, setting the id’s should be consistent. In this example the id’s will have a pattern of prefix_00. The elements to be matched will have the same pattern.

<p>
    <input type="checkbox" id="checkbox_01" name="checkbox" value="red was checked" />red<br />
    <input type="checkbox" id="checkbox_02" name="checkbox_02" value="green was checked" />green<br />
    <input type="checkbox" id="checkbox_03" name="checkbox_03" value="blue was checked" />blue
</p>

<table>
    <tr>
        <td>color 01<input type="text" id="color_01" name="color_01" /></td>
    </tr>
    <tr>
        <td>color 02<input type="text" id="color_02" name="color_02" /></td>
    </tr>
    <tr>
        <td>color 03<input type="text" id="color_03" name="color_03" /></td>
    </tr>
</table>

The jquery/javacript will strip off the prefix of an element’s id to grab the numeric value. It will then concatenate the numeric value onto the prefix of the matching element.

The function to grab the number:

function getNum(element, attrPrefix) {
    //set prefix, get number
    var prefix = attrPrefix;
    var num = element.attr("id").substring((prefix.length));
    return num;
}

A checkbox change function calls the getNum function and concatenates the id for the matching element. Then it sets the value of the matched element.

$(":checkbox").change(function() {
    var num = getNum($(this), "checkbox_");
    if ($(this).is(":checked")) {
        $("#color_" + num).val($(this).val());
    } else {
        $("#color_" + num).val("");
    }
});

Fiddle Demo:

Using jQuery Autocomplete When Remote Source JSON Does Not Contain ‘Label’ or ‘Value’ Fields

If the jQuery autocomplete plugin uses a remote datasource, the autocomplete expects it to return json data with a ‘label’ and/or a ‘value’ field. If you return one, either ‘label’ or ‘value’, the autocomplete uses it for both the suggestion menu and the value of the input box. If you return both, it uses the ‘label’ for the suggestion menu and the ‘value’ for the value of the input box.

What happens when the remote source returns neither a ‘label’ or ‘value’ and you cannot change the returned json of the remote source? Or, better yet, it does return them but you want different values used in the autocomplete?

For example, the remote source json string below has neither a ‘label’ or a ‘value’ field. Using this would result in the autocomplete not functioning at all.

[{"id":"3","state":"Alaska","abbrev":"AK"},{"id":"4","state":"Alabama","abbrev":"AL"},{"id":"9","state":"California","abbrev":"CA"}]

You can work around this by modifying the ‘source’ option of the autocomplete to assign one or both of the ‘label’ and ‘value’ fields values found in the json result.

To modify the ‘source’ option of the autocomplete, we add an ajax call to the source and, in the ‘success’ callback, we assign the values of all the variables we want the autocomplete to use.

$("#state").autocomplete({
				source: function( request, response ) {
				$.ajax({
					url: "states_remote.php",
					dataType: "json",
					data: {term: request.term},
					success: function(data) {
            					response($.map(data, function(item) {
                				return {
									label: item.state,
									id: item.id,
									abbrev: item.abbrev
									};
            				}));
						}
					});
				},
				minLength: 2,
				select: function(event, ui) {
					$('#state_id').val(ui.item.id);
					$('#abbrev').val(ui.item.abbrev);
				}
			});

To break this down, the ajax function has the following options:

  1. url: url of page that returns the json; subject to same origin policy (you should use jsonp for cross-domain url’s)
  2. dataType: sets the data coming back to the ajax function as json
  3. data: sets the query parameter of ‘term’ to the value of ‘request.term’ which is what the user types into the input box
  4. success: callback function that maps the returned json and sets the variables that the autcomplete will use

In this example, the ‘select’ option of the autocomplete sets the label field used by the autocomplete in the suggest menu and as the value of the input box. It also sets the values of some additional fields in the form. They are returned to the page in the demo to verify that they are set. ‘id’ is a hidden field in the form and ‘abbrev’ populates a read-only input box in the form.

And, if the json result does set the ‘label’ and/or ‘value’ fields but you don’t want those values in the autocomplete, you can adjust the ‘return’ of the ‘success’ function in th ‘ajax’ call:

return {
    label: item.value,
    yourVar1: item.id,
    yourVar2: item.label
};
// or however you want it as long as a 'label' and/or 'value' field is set

Remember, the autocomplete needs a ‘label’ or ‘value’. Don’t forget to set one, the other, or both.

Demo

Position jQuery UI Dialog Relative to Link or Page Element

Demonstration of positioning a jQuery UI dialog relative to a link or radio buttons. Question from stackoverflow.com. It could be adapted to position under or next to any element on a page. It would work nicely as a form field hint dialog or help dialog.

Two demos are below. One for a single element and one for multiple elements.

Position is adjusted on window resize and scroll.

<div style="text-align:center;"><a id="myLink" href="#">my link</a></div>
<div id="myDialog">
    <p> My positioned dialog</p>
</div>
$(function() {
    $("#myDialog").dialog({
        autoOpen: false,
        show: 'fade',
        hide: 'fade',
        modal: false,
        width: 200,
        minHeight: 200,
        buttons: {
            "Close": function() {
                $(this).dialog("close");
            }
        }
    });

    $("#myLink").click(function(e) {
        e.preventDefault();
        $("#myDialog").dialog("open");
        return false;
    });

    function positionDialog() {
        linkOffset = $("#myLink").position();
        linkWidth = $("#myLink").width();
        linkHeight = $("#myLink").height();
        scrolltop = $(window).scrollTop();
        $("#myDialog").dialog("option", "position", [(linkOffset.left - 200/2) + linkWidth/2, linkOffset.top + linkHeight - scrolltop]);
    }

    positionDialog();

    $(window).resize(function() {
        positionDialog();
    });

    $(window).scroll(function() {
        positionDialog();
    });
});

Demo for single element on page

Demo for multiple elements on page