Creating Inline Timepicker with JavaScript and jQuery

Blog Projects
javascript jeditable jquery
HEADS UP! This article was written in 2008. Information provided might not be valid anymore and should be taken with a grain of salt.

Inline editing is not only limited to text and textarea inputs. In this tutorial you will learn how to make inline timepicker with JavaScript. We will be using the usual tools: jQuery and Jeditable.

Before continuing you might be interested in reading introduction to custom input types for Jeditable.

Available methods for creating custom input

When creating custom input type you want to define one or several of following methods. None of them are mandatory.

$.editable.addInputType('example', {
    element : function(settings, original) { },
    content : function(string, settings, original) { },
    buttons : function(settings, original) { },
    submit  : function(settings, original) { },
    plugin  : function(settings, original) { },
    reset   : function(settings, original) { }
});

All methods receive two parameters. Settings is Jeditable settings hash. Original is the original element which was clicked. Method content() also receives third parameter string which is the value input should be set to. Inside all methods this represents the form.

For this example we will be using three methods.

element(settings, original) should create input element and attach it to form. Form is available inside function as variable this. Input element returned stores the final value to be submitted to server. Finally function should return the newly created element. If you do not provide this method an hidden input will be created by default.

submit(settings, original) is called before submitting the form. It should set the value of input element returned by element(). This is only needed in special cases such as having multiple selects.

content(string, settings, original) should set the value of custom input. For example for multiple selects it should set the selected options in each select.

Creating custom input

Throughout the tutorial we will be using following code to trigger Jeditable.

$("#id").editable("http://www.example.com/save.php", {
        type       : "time",
        submit     : "OK",
        style      : "display: inline",
        tooltip    : "Click to edit..."
});

We will start by adding custom input type called time.

$.editable.addInputType('time', {
});

Right now it does not do much anything. Since no methods are defined plugin will simply call the default methods.

Click time 13:30 to see how code works this far.

Add hour and minute pulldowns

Our timepicker will have two selects. One for hour and one for minutes. To keep minutes select short we will use 15 minute steps. To create these elements, we need to use element() method.

The two loops build the pulldowns. When they are ready the are appended to the form. As you remember, inside all helper methods this represents the form.

$.editable.addInputType('time', {
    element : function(settings, original) {
        var hourselect = $('<select id="hour_">');
        var minselect  = $('<select id="min_">');

        /* Hour loop */
        for (var hour=1; hour <= 24; hour++) {
            if (hour < 10) {
                hour = '0' + hour;
            }
            var option = $('<option>').val(hour).append(hour);
            hourselect.append(option);
        }
        $(this).append(hourselect);

        /* Minutes loop */
        for (var min=0; min <= 45; min = parseInt(min)+15) {
            if (min < 10) {
                min = '0' + min;
            }
            var option = $('<option>').val(min).append(min);
            minselect.append(option);
        }
        $(this).append(minselect);

        /* Hidden input to store value which is submitted to server. */
        var hidden = $('<input type="hidden">');
        $(this).append(hidden);
        return(hidden);
    }
});

Why did we create hidden input in the end? When new value is submitted to server Jeditable expects there is only one input field to read value from. It could be any kind of field such as text or textarea. In this case it is best to use hidden. Later in the code I will show how to write pulldown values to the hidden input.

Note! element() method must return this single input in the end of function.

Click time 13:30 to see how code works this far.

Now selects are created. One problem exists though. Nothing is submitted to server. Our hidden field has empty value.

Sending correct value to server

We need to combine hours and minutes from two pulldowns. This combined value needs to be written to our hidden input. For that we will use submit method. This method is called just before form is submitted.

We read values from both pulldowns and put : character in between. Resulting string is then written into previously created hidden input.

$.editable.addInputType('time', {
    element : function(settings, original) {
        ...
    },
    submit: function (settings, original) {
        var value = $("#hour_").val() + ":" + $("#min_").val();
        $("input", this).val(value);
    }
});

Hey, what was that $("input", this) selector? Especially why is variable this inside selector?

There is optional second parameter for jQuery selectors. It is called context. Without second parameter selector is matched against current HTML page. If it is provided, selector is matched only against contents of second parameter.

Inside all methods this refers to the form Jeditable created. Selector above will search for our hidden input inside created form and not full HTML document.

Click time 13:30 to see how code works this far.

In demo selects are created. Correct value is submitted. One problem still exists. Default value for timepicker always is 24:45.

Setting default values

content() method set inputs default value. If editable time value is 13:30 and we click it, hour pulldown should be 13 and minute pulldown 30.

13:30 is passed in as parameter called string. Hours and minutes are parsed from this string. Both hour and minute pulldown are then looped. Inside loop correct hour and minute are set as selected.

$.editable.addInputType('time', {
    element : function(settings, original) {
        ...
    },
    submit: function (settings, original) {
        ...
    },
    content : function(string, settings, original) {
        var hour = parseInt(string.substr(0,2));
        var min  = parseInt(string.substr(3,2));

        $("#hour_", this).children().each(function() {
            if (hour == $(this).val()) {
                $(this).attr('selected', 'selected');
            }
        });
        $("#min_", this).children().each(function() {
            if (min == $(this).val()) {
                $(this).attr('selected', 'selected')
            }
        });
    }
});

Click time 13:30 to see finished inline timepicker.

What now?

Code could still be improved. Various aspects could be configurable. Some poeple might prefer minutes pulldown have five minute interval. Other people might prefer AM/PM time format.

In meanwhile download and experiment with code we just did.



When asking a question include an URL to example page where the problem occurs. Even better is to make a Fiddle which demonstrates the problem. If you have longer code examples please use pastie.org.
CATEGORIES
Built using the awesome Flat UI Pro framework by Designmodo.

Mika Tuupola is a Member of the Leanpub Affiliate Program.

© 2014 Mika Tuupola.