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?
Materialize datepicker is a modified pickadate.js picker. Accodging to their API docs, this is how to set the picker:
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.
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.
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.
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.
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.
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>
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