jQuery UI Datepicker, move from one Calendar to the next? - javascript

I'm looking for a way of moving from one Calendar to the next once the user has selected a date e.g:
User picks dateFrom
Automatically close dateFrom calendar and show dateTo version
I feel like I'm close to a solution but the dateTo calendar pops up and then disappears instantly, I'm hooking into the onSelect function of the calendar and when the inst is the dateFrom calendar, then i call .focus() on the dateTo text box e.g:
$('.datepicker > input').datepicker({
// snip.....
onSelect: function (dateText, inst) {
var type = $('#' + inst.id).data('calendar');
if (type === 'date-from') {
$('.js-hook--date-to').focus();
}
}
});
Markup:
<div class="large-2 columns">
<div class="datepicker">
<asp:TextBox ID="txtDateFrom" runat="server" placeholder="CHECK IN" data-calendar="date-from" />
</div>
</div>
<div class="large-2 columns">
<div class="datepicker">
<asp:TextBox ID="txtDateTo" runat="server" CssClass="js-hook--date-to" placeholder="CHECK OUT" data-calendar="date-to" />
</div>
</div>
This causes the next Calendar to pop up but it then disappears, is there an easy way to achieve this?
Edit*
I've also tried using .datepicker("show"); with no success.
2nd Edit*
jsFiddle to demonstrate

Use a short delay before triggering the focus.
onSelect: function(dateText, inst) {
var type = $('#' + inst.id).data('calendar');
if (type === 'date-from') {
setTimeout(function() {
$('.js-hook--date-to').focus();
}, 50)
}
}
As mentioned in comments the plugin only uses one container for all instances.
I think what is happening is since the first instance hasn't quite closed and cleaned up when you trigger the focus, the new instance is getting hidden from event in first
I arbitrarily set the delay and didn't play with it much to see what is best.
DEMO

I managed to do this using onClose and checking if a date was selected with getDate:
onClose: function (dateText, inst) {
var picker = $('#' + inst.id);
var type = picker.data('calendar');
var date = picker.datepicker('getDate');
if (type === 'date-from' && date !== null) {
$('.js-hook--date-to').focus();
}
}

Related

Capturing manually entered date before jquery datapicker resets to current date while restricting with Maxdate

I have a datapicker class (datepicker_nfd) that is attached to an input field that uses maxdate to limit the date widget to only current dates. I have a custom knockoutjs binding to display a custom error message and reset the date when the users leaves the field (onchange). My problem is if a user manually enters a date in the future and presses enter, the widget sets the date to the current date before the onchange is fired and therefore I am unable to check to display the message. I have tried the onseect method of the datepicker and also tried to capture the "enter" keypress to no avail. Any suggestion on how to capture the manually entered date before the datepicker widget resets to current date?
Javascript (applicable code only for brevity)
$(document).ready(function () {
$(".datepicker_nfd").datepicker({maxDate: 0});
});
KnockoutJS Binding (applicable code only for brevity)
ko.bindingHandlers.preventFutureDate = {
init: function (element, valueAccessor, allBindingsAccessor, vm) {
$(element).change(function () {
var selectedDate = Date.parse(ko.unwrap(valueAccessor()));
var curDate = Date.now();
if (selectedDate > curDate) {
var value = valueAccessor();
var eMsg = ($(element).data("emessage") || "Date") + " can not be set to a future date. Defaulting to current day.";
value(DateTime.fromMillis(Date.now()).toFormat('MM/dd/yyyy'));
showToast("Invalid Date", eMsg.trim(), "exclamation-triangle", "yellow");
}
});
}
};
HTML (applicable code only for brevity)
<div class="form-group col-md-2">
<label for="someDate-datepicker_nfd">Some Date Label</label>
<input type="text" class="form-control datepicker_nfd" id="someDate-datepicker_nfd" data-bind="value: model.SomeDate, preventFutureDate: model.SomeDate" data-emessage="Some Date Error Message" />
</div>
So the solution that I found is that you indeed you have to use the keydown press, which MUST be before the date picker is initialized...... so in my case I had the binding being initialized in one file and the datepicker in another. This was causing the keydown to not fire(assuming the datepicker prevents default. So HTML remains the same and the js is now as follows (order is important).
Javascript/KnockoutJS (applicable code only for brevity)
let keyedDate;
ko.bindingHandlers.preventFutureDate = {
init: function (element, valueAccessor, allBindingsAccessor, vm) {
$(element).keydown(function (e) {
if (e.keyCode === 13) {
checkForFutureDate(element, valueAccessor, keyedDate);
}
});
$(element).change(function () {
checkForFutureDate(element, valueAccessor, ko.unwrap(valueAccessor()));
});
}
};
$($(".datepicker_nfd")).keydown(function (e) {
if (e.keyCode === 13) {
keyedDate = $(this).val();
}
});
// NOTE: This needs to be placed after the Knockout Binding Handler for preventFutureDate to capture the keydown event.
// The companion selector for $(".datepicker").datepicker(); in in site.js
$(".datepicker_nfd").datepicker({maxDate: 0});
function checkForFutureDate(element, valueAccessor, dateToVerify) {
var selectedDate = Date.parse(dateToVerify);
var curDate = Date.now();
if (selectedDate > curDate) {
var value = valueAccessor();
var eMsg = ($(element).data("emessage") || "Date") + " can not be set to a future date. Defaulting to current day.";
value(DateTime.fromMillis(Date.now()).toFormat('MM/dd/yyyy'));
showToast("Invalid Date", eMsg.trim(), "exclamation-triangle", "yellow");
}
};
HTML (applicable code only for brevity)
<div class="form-group col-md-2">
<label for="someDate-datepicker_nfd">Some Date Label</label>
<input type="text" class="form-control datepicker_nfd" id="someDate-datepicker_nfd" data-bind="value: model.SomeDate, preventFutureDate: model.SomeDate" data-emessage="Some Date Error Message" />
</div>
Kind of quirky but gets the job done. Noticed the let with keyedDate to capture the date before the datepicker changes it outside the binding. Which need the binding to access the other values in the HTML bind.

Javascript: compare two dates inside an if

The function card should return the card of a certain concert.
But only if the concert's date match the date selected with the datepicker's function. So if I choose the date 06/22/2018 I should see the concert card because the date is the same. But right now it doesn't work because the line:
if(document.getElementById("datepicker").value == this.date)
is picking the value of the input at the top, which is undefined, so it doesn't show anything. So I think I have first to call the function datepicker(),but I don't know how to do.
Here's the code I'm using:
<input type="text" id="datepicker"/></div>
<div id="corpo1"></div>
$(function()
{
$("#datepicker").datepicker({
showOn: "button",
buttonText: "Select date",
buttonImage: "https://i.imgur.com/cvkNy5G.png"
});
});
function Concert(id, name, date, price)
{
this.id = id;
this.name = name;
this.date = date;
this.price = price;
this.card = function()
{
if(document.getElementById("datepicker").value == this.date)
return "<span class='concert'>"+this.name+" "+this.date+"</span>";
}
}
var concerti = [ new Concert(1,"The Fame Ball","06/22/2018",50) ];
function showcard(f)
{
var ris = "";
for(var i in concerti)
{
ris+=concerti[i].card();
}
document.getElementById('corpo1').innerHTML=ris;
}
Anyone who can help?
Try this solution: http://jsfiddle.net/6gub2smo/2/
The key change is the following:
$("#datepicker").datepicker({
showOn: "button",
buttonText: "Select date",
buttonImage: "https://i.imgur.com/cvkNy5G.png",
onSelect: showcard
});
jQuery UI recommends using the onSelect event. Documentation here.
Allows you to define your own event when the datepicker is selected.
The function receives the selected date as text and the datepicker
instance as parameters. this refers to the associated input field.
The problem I think you're having that your showcard code isn't being run, at least not at the right time. Adding the following to your Javascript should fix the issue.
$("#datepicker").change(showcard);
It will cause the showcard function to be run when the user selects a new date, when the text of the textbox is changed. The issue you might be having with "undefined" showing up if you don't select the date of the Concert is because the showcard function returns nothing (turned into "undefined") if the dates don't match. You can fix this by adding return ""; to the end of the function to force it to return an empty string and have nothing show up.

Open datepicker only if condition is true?

I'm using a datepicker in my To Do List table that the user can use to select a certain date. I'm using it to select a certain "completed date" and I only want the datepicker to open if the To Do is marked 100% complete. Right now the datepicker will open if the To Do isn't marked 100%. Does anyone know how to add a conditional saying
if (todos[i].progress != 100) { *dont open datepicker* }
I've tried adding this to my event function but it does not work as I had hoped.
HTML: The last td element is for the datepicker.
tr class="rowTable dropdown-button" data-id="%todoID%" data-activates="todo_dropdown" data-context="true" data-type="edit-%canedit%" data-canedit="%canedit%" data-constrainwidth="false">
<td class="tableData">
<div class="checkbox" data-complete="%notTrue%" data-show="hidden">
<div class="todo_checkbox"></div>
</div>
</td>
<td class="tableData">%todoTitle%</td>
<td class="tableData">%resources%</td>
<td class="%isOverdue% tableData">%duedate%</td>
<td class="tableData">%percentcomplete%</td>
<td class="completedCalendar tableData"><input value="%dateCompleted%" class="datepicker picker_input" data-id="%todoID%" id="todo_completeddate" style="border:none" readonly="readonly"/></td>
JavaScript:
$('.datepicker').on('change', function (e) {
var $targ = $(e.currentTarget);
var todoID = $targ.parents(".rowTable").data("id");
var todos = currentItems;
for (var i = 0; i < todos.length; i++) {
if (todoID == todos[i].id) {
if (todos[i].progress == 100) {
var dateSet = $('.datepicker[data-id=' + todoID + ']').val();
todos[i].completed_date = dateSet;
}
}
}
})
You should try using
beforeShow: function(input, inst) {
// check condition here
}
You can check your condition on change much like you're currently doing in your on change for the datePicker. This could be a change within the form, table, etc. Within that OnChange, you can check the condition and access the datepicker and hide it or show it like this
$(".datepicker").hide();
$(".datepicker").show();
I think in your case you should disable/hide the date field when data are loaded from server.
You can also use beforeShow event of datepicker widget. But you'll not able to block opening datepicker window. You can hide calendar just after it is shown. Notice you have to use setTimeout in beforeShow otherwise it won't work.
beforeShow: function(input, inst) {
setTimeout(function() {
if (condition) {
$(".foo").datepicker("widget").hide();
}
}, 0);
}
See here for example

JQuery : Event not getting triggered while changing date in datepicker

I want to call a function whenever user changes date in a datepicker but it is not working. I have already checked link for Question JQuery Datepicker onchange event help! but it didnt help.
Below is my code and what i have tried:
<h:inputText id="animalBornDateId"
value="#{myController.animalBornDate}"
styleClass="dtp dateClass" style="width: 80px !important;" >
</h:inputText>
What i tried:
$("#animalBornDateId").datepicker({
onSelect: function(dateText, inst) {
var date = $(this).val();
var time = $('#time').val();
alert('on select triggered');
}
});
Another:
$('#animalBornDateId').on('input',function(e){
alert('Changed!')
});
The below works when i manually enter date inside textbox and click tab which i dont want.
$('#animalBornDateId').change(function() {
alert("test");
});
I want to call alert function when i select date from the calendar

Opening new datepicker when old one is closed

I'm using a custom JS library called datepicker, that you can find here.
I have it set up and working, but I need some extra functionality from it, and I have absolutely no idea how to get it done.
Here's what I have so far:
<h:panelGroup>
<h:panelGrid>
<input id="depatureDate" value="Departure date" class="datepicker dp1"></input>
<script>
$(".datepicker, dp1").pickadate({
format: "dd/mm/yyyy",
formatSubmit: "dd/mm/yyyy"
})
</script>
</h:panelGrid>
<h:panelGrid id="returnDate">
<input value="Return date" class="datepicker dp2"></input>
<script>
$(".datepicker, dp2").pickadate({
format: "dd/mm/yyyy",
formatSubmit: "dd/mm/yyyy"
})
</script>
</h:panelGrid>
</h:panelGroup>
What I need to do is the following:
If the first datepicker's input is clicked and a date is selected, that datepicker needs to close(it's already doing this, so that's fine) and the second datepicker needs to open, with the date that was selected in the first one marked on it. The user must then select another date on the second datepicker
If anyone has any idea how to do this, advice and pointers would be more than welcome!
Okay, i've done a small example here, working with the close event.
<input type="text" class="datepicker1" />
<br />
<input type="text" class="datepicker2" />
<script type="text/javascript">
// init second picker
var $input = $('.datepicker2').pickadate();
// init first picker
$('.datepicker1').pickadate({
// handle close event
onClose: function() {
var picker = $input.pickadate('picker');
// set unix timestamp to the second picker
// maybe theres a better solution for this...currenlty it works
picker.set('select', this.component.item.select.pick );
picker.open();
}
});
</script>
dont forget to load all pickadate libraries and jquery.....
i've defined 2 divs with classed datepicker1 and datepicker2. then i'm creating
the datepicker objects. the datepicker1 object handles the onClose event.
When the first datepicker is closed, the scripts opens the second and sets the value of datepicker1...
hope this helps
cheers
the datepicker provides an close event, maybe you can use this? Take a look at the API here
http://amsul.ca/pickadate.js/api.htm#method-on
some lines further down, you find
$('.datepicker').pickadate({
onOpen: function() {
console.log('Opened up!')
},
onClose: function() {
console.log('Closed now')
},
onRender: function() {
console.log('Just rendered anew')
},
onStart: function() {
console.log('Hello there :)')
},
onStop: function() {
console.log('See ya')
},
onSet: function(event) {
console.log('Set stuff:', event)
}
})
when entering the close event, open a new datepicker and set default value of the currently closed.

Categories

Resources