Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make the materialize date picker (in fact pickadate) editable?

I'm trying to make the materialize date picker editable. Here is the goal, the user can directly write the date in the input field or use the widget to pick a date.

I did something that is about to work on this jsfiddle. But there is a bug I'm trying to solve. When the user directly writes the date in the input, the picker needs to get the new value also (because I use a different format to submit the date and there is a an hidden input field to update). To accomplish that I tried to do

picker.set('select', $(this.val());

But it creates an infinite loop because the method set in materialize also triggers the event change on the input.

EDIT: oh i just found there is an issue open about that on github. Do you have any idea for a workaround?

like image 624
Clemzd Avatar asked Feb 29 '16 19:02

Clemzd


People also ask

What is materialize datepicker and how to use it?

Materialize datepicker is a modified pickadate.js picker. Accodging to their API docs, this is how to set the picker:

What is the use of datepicker?

The datepicker allows users to select a date from an interactive calendar. Automatically close picker when date is selected. The date output format for the input field value. Used to create date object from current input string. The initial date to view when first opened. Make the defaultDate the initial selected value.

What is the difference between setDate () and defaultdate () in datepicker?

defaultDate will set a default Date that will be shown in input-field of datepicker without even opening the picker. instance.setDate () will select the date in datepicker when you'll open it.

What are the options for internationalization of datepicker?

Internationalization options. An array of string returned by `Date.toDateString ()`, indicating there are events in the specified days. Callback function when date is selected, first parameter is the newly selected date. Callback function when Datepicker is opened. Callback function when Datepicker is closed.


1 Answers

Any specific reason you want to do it in the change method?
Why not something like this?

this.change(function(event) {

});

this.bind('blur keypress',function(e){
  if (moment($(this).val(), "DD/MM/YYYY", true).isValid()) {
      var inputFieldDate=getFmtDate($(this).val());
      picker.set('select',inputFieldDate);
  }

});

This is a utility function to parse the date in DD/MM/YYY format and get a javascript Date object

function getFmtDate(s){
  var valx=new Array();
  if(s!=null && s.length>0){
      valx = s.split('/');
  }
  var d = new Date(valx[2],valx[1]-1,valx[0]);
  return d;
}

This works for me.

Update:

Once you attach a widget to an html element, the usual event callback functions do not work the way you expect them to. Their functionality is overridden by the widget. You cannot use the functions the same way you are used to and have to find a workaround. In short you cannot use the change function to set or unset the date because set triggrers a change event.

In your case you want to address multiple issues which are very common problems. You should be able to get a lot of examples online to achieve each one of those. What I've done is just one way of doing it.

  1. Populate the form in a non traditional way when the page loads.
  2. Initialize various plugins with values from the form when the page loads
  3. Initialize content from hidden fields when the form loads and update the hidden fields when submitting the form.
  4. Fetch the values by name (of the hidden fields) and use them to initialize the widgets.


I've used blur keypress just to give you an idea that all your requirements can be handled without using change. You use the events that work for you. You can set the date by binding picker to calendar object with this keyword and access it from its instance as shown below.

    (function($) {

      $.fn.calendar = function(options) {

    // Options du datepicker
        var settings = $.extend({
            editable: true,
            format: 'dd/mm/yyyy',
            formatSubmit: 'ddmmyyyy'
        },
        options
      );

    this.pickadate(settings);
    //var picker = this.pickadate(''); will not work
    this.picker = this.pickadate('picker');

    this.change(function(event) {

    });
    this.bind('blur keypress',function(e){
      if (moment($(this).val(), "DD/MM/YYYY", true).isValid()) {
            var inputFieldDate=getFmtDate($(this).val());
          picker.set('select',inputFieldDate);
      }
    
    });

    var $triggerIcon = $('<div class="col s2 center-align"><a class="btn-floating btn-large waves-effect waves-light trigger-datepicker">Date</a></div>');
    $triggerIcon.click(function(event) {
      event.stopPropagation();
      event.preventDefault();
      picker.open();
    });
    this.parent().after($triggerIcon);
    // Resolves picker opening for thing
    this.next().unbind("focus.toOpen");
    return this;
      };
    }(jQuery));

To set a date:

//This is how you set a date
var cal = $('.datepicker').calendar();
//You can access picker because we changed
//var picker to
//this.picker above in fn.calendar
cal.picker.set('select', getFmtDate($("[name=hiddenDate]").val()));
// The syntax is 
//cal.picker.set('select', new Date());

$('#formulaireDate').validate();

You have to convert your date to Date(). The below function should give you an idea. You can also use plugins like jquery dateFormat plugin.

function getFmtDate(s){
    var valx=new Array();
      if(s!=null && s.length>0){
                        valx = s.split('/');
              }
  var d = new Date(valx[2],valx[1]-1,valx[0]);
  return d;
}

This is your html.

<div class="row">
<div class="col s4">
  <input type="text" class="datepicker" />
  <input name="hiddenDate" type="hidden" value="12/12/2016">
</div>
</div>
like image 173
Shakeel Avatar answered Oct 16 '22 11:10

Shakeel