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

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?

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.
Populate the form in a non traditional way when the page loads.
Initialize various plugins with values from the form when the page loads
Initialize content from hidden fields when the form loads and update the hidden fields when submitting the form.
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>

Related

Dynamic Kendo UI Grid editable datetime column not using value

I have a kendo UI Grid that has in-line editing on a single column. That column should be using a datepicker as the input when editing.
However, after setting the value on the datepicker, and then returning to the same row/column, the date does not then show in the datepicker input.
I have created a Dojo to show what I mean:
https://dojo.telerik.com/eJEmoVEv/4
And a quick gif to explain the issue better:
Dealing with bindings on kendo is always tricky. I have update your demo with a few changes:
Editor:
When you're using data-bind you're not suposed to handle the widget's state. Kendo should deal with it by itself, but you need to tell kendo to handle that using kendo.bind(element, model)(bind() docs). Hence, you don't need to set data-value attribute.
function commentEditor(container, options) {
var datePicker = $('<input data-role="datepicker" data-format="dd/MM/yyyy" type="date" name="Comment" data-bind="value:Comment">');
datePicker.appendTo(container);
kendo.bind(datePicker, options.model);
}
Comment field type:
In order to make kendo to know how to handle the Comment field value as a date and to set it properly to the widget, you need to set the right data type in it's model definition:
Comment: { type: "date", editable: true }
Template:
A small fix to the template:
template: function (dataItem) {
if (dataItem.Comment != "") {
let date = kendo.parseDate(dataItem.Comment);
if (date) {
return kendo.toString(date, "dd/MM/yyyy");
}
}
return (dataItem.Comment || "");
}
I'm making sure that the Comment content is a valid date by checking the parseDate result. If not valid, proceed to another condition where it verifies if Comment is not null, undefined, etc, if yes, prints an empty string.
I hope it helps.
Update
Not sure why, but it seems that kendo saves the selected value as string to the bound property. I have added this handler to the widget's change event that seems to work:
datePicker.data("kendoDatePicker").bind("change", function(e) {
let model = this,
widget = e.sender;
model.Comment = widget.value();
}.bind(options.model));
Updated demo
That forces Comment property to be of Date type.
After the help from #DontVoteMeDown I finally found an answer to this.
The datepicker is expecting the Comment field to be of date type, so adding in a kendo.parse and then resetting the comment field fixed this issue.
See updated kendo dojo: https://dojo.telerik.com/eJEmoVEv/4
var dateTimeComment = kendo.parseDate(options.model.Comment);
options.model.Comment = dateTimeComment;

fullCalendar on click of date number - get Date data attribute

I'm having an issue with the FullCalendar jQuery Library, found HERE:
I'm attempting change up the normal functionality of things. When clicking the date number in month view instead of it switching to DAY view, I want it to go to another page and pass the date attribute int he data-goto attribute that is listed.
Each day, after the calendar is render has this markup:
<td class="fc-day-top fc-xxx fc-yyyy" data-date="YYYY-MM-DD">
<a class="fc-day-number" data-goto='{"date": "YYYY-MM-DD", "type":"day"}'>DD</a>
<td>
So after initializing the calendar, I have an on click event:
$('.fc-day-number').each(function(){
var $this = $(this);
$this.on('click', function(){
console.log($(this).data('goto', 'date'));
});
});
BUT, when I click on the number of the date, it gives me a Uncaught TypeError: Cannot read property 'charAt' of undefined
All I want to do, just to make sure it's collecting the proper data is just get the date value from the goto data-attribute. Once I have that then loading a new page is easy.
Thanks again in advance.
So I found a work around that, albeit doesn't serve 100% of the criteria, but still works all the same.
For the number in each cell, I applied a pointer-events: none, so that it would be non-clickable, and in the initialization code for FullCalendar, I took advantage of the dayClick method and used THAT to pass through the date, add that to a URL query and the simple javascript to redirect the page.
Here's the code:
$('#calendar').fullCalendar({
dayClick: function(date){
var dateFormat = date.format()
console.log("Clicked on: "+dateFormat); //returns the date
window.location.href = "newPage.jsp?datepicker="+dateFormat;
}
});
$('a.fc-day-number').each(function(){
var $this = $(this);
$this.css('pointer-events','none');
});

bootstrap datepicker and local storage

I would like the user to select a date from a bootstrap datepicker component and store the selected value in local storage. When the user has completed their selection they can select the button whereupon an ajax call will use the local storage.
At this moment I'm having trouble getting the datepicker component to set a value in the local storage. The date picker component renders when the user selects is and the user's selection becomes the value of the input field.
Here is the mark up:
<form>
<div class="form-group">
<label for="edge-name" class"control-label">Start:</label>
<input type="text" class="form-control" id="filterStart">
</div>
</form>
And the javascript
$(document).ready(function(){
$('#filterStart').datepicker();
$('#filterStart').on('changeDate' function(){
var newValue = $('#filterStart').datepicker('getFormattedDate')
localStorage.setItem('filterStart',newValue);
});
I've inserted console.log in various places throughout the javascript but the code never writes to the console therefore I know that its not writing to the local storage. I know that the local storage is working because I'm using it other parts of the code.
Also, any suggestions on how to do this better would be greatly appreciated.
If you are using this bootstrap-datepicker you can take a look to the following jsfiddle:
$('#filterStart').datepicker();
$('#filterStart').on('changeDate', function (e) {
var newValue = $('#filterStart').datepicker('getFormattedDate')
localStorage.setItem('filterStart', newValue);
});
$('#btn').on('click', function(e) {
$('#logMsg').val('Value saved in local storage is: ' +
localStorage.getItem('filterStart'));
})
I can't find if method 'getFormattedDate' exists but there is a standard getDate method for that. By the way you miss a semicolon in definition line of newValue;
I think you might be instantiating a new datepicker in your changeDate event. You could try getting the formatted date from the .data:
var newValue = $('#filterStart').data('datepicker').getFormattedDate('yyyy-mm-dd');

Dynamically setting date and time in DateBox Jquery Mobile

I need to populate date and time dynamically to JQuery DataBox input field. I teried to do but it is populating the current date in the input fields irrespective of the data I pass.
Here is the date picker which I am cloning to dynamically have in my interface.
Html:-
<input class="time-input day-time-picker day-time-picker-inline-input" type="text" data-role="datebox" data-options='{"mode":"datebox", "useFocus": true}' style="width:8em" />
Javascript:-
var datePicker = $("#date-time-picker-template-container .date-time-picker-template").clone();
Similar way I created a time picker and cloned as did above,
Html :-
var timePicker = $("#time-picker-template-container .time-picker-template").clone();
Javascript :-
<input class="time-input day-time-picker day-time-picker-inline-input" type="text" data-role="datebox" data-options='{"mode":"timebox", "useFocus": true}' />
Inserting Date
$(".time-input", datePicker).datebox();
$(".time-input", datePicker).datebox("refresh");
$(".time-input", datePicker).datebox('setTheDate', dynamicDate);
Inserting Time
$(".time-input", dayTimePicker).datebox();
$(".time-input", dayTimePicker).datebox("refresh");
$(".time-input", dayTimePicker).val('datebox', {'method':'set', 'value':dynamicTime});
I want to set date and time to these DateBox input fields dynamically based on the response I get.
Is there any control to get date and time in a single control using DateBox ?
Thanks.
Clone your templates, add them to a container DOM element and then tell the element to enhanceWithin(). This creates the databox widgets, then set the date and time using the setTheDate method:
$("#btnAdd").on("click", function(){
var dynamicDate = new Date(2014,3,22,10,11,0,0);
var datePicker = $("#templates .date-time-picker-template").clone();
var dayTimePicker = $("#templates .time-picker-template").clone();
$("#time-picker-block").append(datePicker).append(dayTimePicker).enhanceWithin();
$(".date-input", datePicker).datebox('setTheDate', dynamicDate);
$(".time-input", dayTimePicker).datebox('setTheDate', dynamicDate);
});
DEMO
I'm not sure I follow what it is you are trying to accomplish, but yes, there is a mode that allows both date and time operation at the same time - slidebox.
You will need to set (at least) the following options:
{
mode = "slidebox",
overrideSlideFieldOrder = ["y","m","d","h","i"],
overrideDateFormat = "%Y-%m-%d %k:%M
}
For what it's worth, flipbox could probably be altered to work with both, but it's non-trivial. datebox can likely already work (I've never tried), but you'll need to pretty heavily alter the CSS - at least making the control a good deal wider first.

Prevent deselect date (Bootstrap-datepicker sandbox)

I have a question about the bootstrap-datepicker.
When I select a random Date and then open the Popup again and click the same Date, the Input-Field clears. Is there any way to prevent this from happening?
I need this because in my case the Input-Field is not allowed to be empty.
I use Angular, and have a directive defined that inserts this little snip of hacky javascript... you might be able to do something similar:
.on('changeDate', function (ev) {
if (ev.dates && !ev.date && selectedDate)
{
// Fixes bug in bootstrap calendar without multiselect, where picking the same day unselects it
$(this).datepicker('setDate',selectedDate);
}
else if (ev.date && ev.date!=selectedDate) selectedDate = ev.date;
});
By having a variable named "selectedDate" somewhere before the constructor for your datepicker, this additional event handler will store valid dates and strip the bogus deselection. You'll notice the event object passed includes the array "dates" when incorrectly deselected, and only "date" when correctly selected.

Categories

Resources