Bootstrap datepicker return focus after select - javascript

If you initialize a bootstrap datepicker from eternicode with autoclose: true, two undesirable behaviors happen:
After the picker closes, when you tab into the next field, you'll start at the beginning of the document again. This can be quite cumbersome on long forms.
Because the picker changes the value programatically, any listeners that you have that care about the blur event on the input won't behave properly. The blur actually occurs when you select the picker value and the input's value hasn't changed. Then the bootstrap-datepicker programmatically updates the field so blur is never fired with the new value.
Here's a demo in stack snippets:
*select any field, select a value from the picker, and then hit Tab
$(".datepicker").datepicker({
autoclose: true
});
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
According to the answer to Focus the field after selecting the jQuery UI datepicker, you can tap into the onClose or onSelect events, but the bootstrap picker doesn't offer those events.
Simply replacing them with hide doesn't seem to work either, since the refocusing will create an endless loop that always keeps the picker open any time you try to close it.
$(".datepicker").datepicker({
autoclose: true
})
.on('hide', function () {
$(this).focus();
});
Stack Snippet Demo:
$(".datepicker").datepicker({
autoclose: true
})
.on('hide', function () {
$(this).focus();
});
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>

This is a little bit of a hack job, but you can conditionally hide and show the elements to avoid an infinite loop. On hide, check if this is the first time attempting to hide. If the input does not have focus (meaning they have used the dropdown and we've lost our tab order, then refocusing will cause the picker to show. We'll also catch this show and hide from there, entering back into our original code. We'll pass back and forth a property on the object so we can manage state.
That will look like this:
$(".datepicker").datepicker({
autoclose: true
})
.on('hide', function () {
if (!this.firstHide) {
if (!$(this).is(":focus")) {
this.firstHide = true;
// this will inadvertently call show (we're trying to hide!)
this.focus();
}
} else {
this.firstHide = false;
}
})
.on('show', function () {
if (this.firstHide) {
// careful, we have an infinite loop!
$(this).datepicker('hide');
}
})
Stack Snippet Demo:
$(".datepicker").datepicker({
autoclose: true
})
.on('hide', function () {
if (!this.firstHide) {
if (!$(this).is(":focus")) {
this.firstHide = true;
// this will inadvertently call show (we're trying to hide!)
this.focus();
}
} else {
this.firstHide = false;
}
})
.on('show', function () {
if (this.firstHide) {
// careful, we have an infinite loop!
$(this).datepicker('hide');
}
})
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>

I am trying to achieve the same thing but somehow the solution is a little buggy. For example, if you click the same date picker again, it is not responding. The browser will stop responding if you click multiple times. I have a better solution which is below.
My solution is to trick the datepicker to focus on the next element within the DIV. I have parsley validation, it adds the <UL> for me automatically.
<div>
<input type="text" class="datepicker" />
<ul class="error-message"></ul>
</div>
$('.datepicker').datepicker({
autoclose: true
}).on('hide', function () {
$(this).next('ul').attr('tabindex',-1).focus();
});

Current date selected features added with #KyleMit solutions
var date = new Date();
var today = new Date(date.getFullYear(), date.getMonth(), date.getDate());
var end = new Date(date.getFullYear(), date.getMonth(), date.getDate());
$(".datepicker").datepicker({
autoclose: true
})
.on('hide', function () {
if (!this.firstHide) {
if (!$(this).is(":focus")) {
this.firstHide = true;
// this will inadvertently call show (we're trying to hide!)
this.focus();
}
} else {
this.firstHide = false;
}
})
.on('show', function () {
if (this.firstHide) {
// careful, we have an infinite loop!
$(this).datepicker('hide');
}
})
$('.datepicker').datepicker('setDate', today);
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>

Related

jQuery - Bind Plugin to Textbox with Dynamic Class?

I have the following function to turn a normal text field into a datepicker:
<input type="text" class="datepicker form-control" name="text-150" >
var DatePicker = function () {
if ($(".datepicker").length === 0) {
return;
}
$(".datepicker").pikaday({
firstDay: 1,
format: "D MMM YYYY"
});
};
The above works fine when the text field is hardcoded with datepicker class. But If I have text field and dynamically inject the datepicker class after the page has loaded via some event, then how can I bind the datepicker plugin to the text field?
Is this what are you trying to achieve?
$( function() {
$('button').click(function() {
$('body').append('<input type="text" class="datepicker" name="text-150" >');
var cl = $('input').attr('class');
$( "." + cl ).datepicker();
})
});
Try this. It will help you.
var id=1;
$('#addDate').on('click',function(){
$("#dates").append('Date '+id+' : <input type="text" id="datepicker'+id+'"><br/>');
$("#datepicker"+id).datepicker();
id++;
});
$('#removeAll').on('click',function(){
$("#dates").html('');
id=1;
});
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<button type="button" id="addDate">Add Date</button>
<button type="button" id="removeAll">Remove All</button>
<div id="dates"></div>
Happy Coding...

How to allow only selection of Sundays on my datepicker?

How do I allow only selection of Sundays on my datepicker? I did a little bit of research and came across a lot of answers stating that I need to use beforeShowDay, These are my codes:
<div class="pickaDate" style="width:25%;">
<input type='text' id="date" />
<script>
jQuery(document).ready(function() {
jQuery('#date').datepicker({
beforeShowDay: function(date){
return [date.getDay()===0];
}
});
});
</script>
</div>
I got the codes from this link but changed the input type to date because that's the only way the datepicker would appear. But I can still select all the dates.
My knowledge on this is basic at best. Help is appreciated
beforeShowDay: A function that takes a date as a parameter and must return an array with true/false indicating whether or not this date is selectable
Try this:
$("#date").datepicker({
beforeShowDay: function(date) {
return [date.getDay() === 0];
}
});
<link href="http://code.jquery.com/ui/1.8.21/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.8.18/jquery-ui.min.js"></script>
<input id="date" type="text">
Fiddle here

DatePicker onchange event not firing in jQuery

I have a button and a textbox. Onclick of the button datepicker pop up appears and user selects a date from the calender pop up and the selected date is populated in the text field.
Now I want to fire an event when the result is populated on the textfield. Onchange event does not work for this as textfield onchange event is fired only if it loses focus. In my case it is changed from an external source.
Hence I thought to fire an onSelect event for the button click. But again event is not triggered.
here is my code
<input type="text" class="textbox_small" name=""
value="" id="txt_node" disabled="disabled"
onchange="fnChangeTime();" />
<input type="button" name="" value=""
class="timePicker_button" id="lnk_hpd"
; style="background-image: url('images/Date_time_picker.gif'); width: 29px; height: 20px;"
onclick="" onselect="" "disabled"/></td>
$('#'+fnParseIDForJ('lnk_hpd')).click(function () {
NewCssCal('txt_node','ddmmyyyy','arrow',false, null, null, null, fnInterimSave, 'txt_node');
});
$('#lnk_hpd').datepicker({
onSelect:function(datesel){
alert("hello");
// alert("Selected date: " + dateText + "; input's current value: " + this.value);
// $(this).change();
}
});
Here no event is triggered. Any help would be appreciated
1.Open datepicker on text box on clicking button , so you have to use id of text box , not button and a method $('#txt_node').datepicker('show'); to show the datepicker.
2.If change event triggered , the datepicker will be kept open, it is not closed so the line $('#txt_node').datepicker('hide');
Check this.
$('#txt_node').datepicker({
onSelect: function(datesel) {
$('#txt_node').trigger('change')
}
});
$('#lnk_hpd').click(function() {
$('#txt_node').datepicker('show');
})
$('#txt_node').change(
function(event) {
$('#SelectedDate').text("Selected date: " + this.value);
$('#txt_node').datepicker('hide'); // if youdon't hide datepicker will be kept open
})
<link href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<input type="text" class="textbox_small" name="" value="" id="txt_node" disabled="disabled" onchange="fnChangeTime();" />
<input type="button" name="" class="timePicker_button" id="lnk_hpd" ; onclick="" onselect="" "disabled" value='Open' />
<br/>
<br/>
<span id='SelectedDate'></span>
I've done something similar using:
HTML
<input type="text" id="NewDate" style="display:none" />
JavaScript
jQuery(function($){
$('#NewDate').datepicker(
{
showOn: 'button',
buttonImageOnly: true,
buttonText:"",
buttonImage: 'img/calendar.png',
onClose: function(date) {
if(date !="") {
alert(date);
}
}
})
})
Simple uncomment $(this).change(); this and It'll automatically work. This will tell the datepicker function to trigger Change() after selecting or Choosing a Date.

Linking two bootstrap timepicker input elements

I am trying to implement two dropdown menus: one for a time value, and one for a duration starting from that time onwards. i.e something like this.
I am using a bootstrap timepicker for the dropdown menu.
I wrote this method for the first field:
$('#timeWithDuration')
.timepicker({ 'scrollDefaultNow': true })
.on('change', function() {
var from_time = $("input[name='from_time']").val();
$('#duration').timepicker({
'minTime': from_time,
'maxTime': '11:30pm',
'showDuration': true
});
});
where #timeWithDuration is my first input field and #duration is my second. This works fine the first time I do it (after selecting a value in the first field, I can only see times past that value in the second field) but it then doesn't let me update the values anymore. i.e I can't select a new value for neither the first, nor the second field. The dropdown displays properly, but then doesn't update the value on select.
This is the HTML code for the input fields:
<div class='col-sm-5'>
<input id='timeWithDuration' type='text' class='form-control ui-timepicker-input' name='from_time' placeholder='What time?' autocomplete='off'>
</div>
<div class='col-sm-5'>
<input id='duration' type='text' class='form-control ui-timepicker-input' placeholder='Duration' autocomplete='off'>
</div>
Unexperienced frontend dev here so please be gentle <3 Cheers!
Use the proper event changeTime and reset the duration input every time:
DEMO: JSnippet
HTML:
<div class='row'>
<div class='col-sm-5'>
<input id='timeWithDuration' type='text' class='form-control ui-timepicker-input' name='from_time' placeholder='What time?' autocomplete='off'>
</div>
<div class='col-sm-5'>
<input id='duration' type='text' class='form-control' placeholder='Duration' autocomplete='off'>
</div>
</div>
JS:
$(function() {
var $duration = $('#duration');
var $timeWithDuration = $('#timeWithDuration');
$timeWithDuration
.timepicker({ 'scrollDefaultNow': true })
.on('changeTime', function() {
var from_time = $("input[name='from_time']").val();
if ($duration.hasClass('ui-timepicker-input')) {
$duration.timepicker('remove');
$duration.val('');
}
$duration.timepicker({
'minTime': from_time,
'maxTime': '11:30pm',
'showDuration': true
});
});
});
Looks like you are using this timepicker.
You will want to create an onchange event on the #timeWithDuration input that updates the minTime option on your timepicker.
Also, I would initialize your second timepicker outside of your onchange event for the first.
$('#timeWithDuration')
.timepicker({ 'scrollDefaultNow': true })
.on('changeTime', function() {
var from_time = $("input[name='from_time']").val();
$('#duration').timepicker('option', 'minTime', from_time);
if ($('#duration').val() && $('#duration').val() < from_time) {
$('#duration').timepicker('setTime', from_time);
}
});
$('#duration').timepicker({'maxTime': '11:30pm', 'showDuration': true});
<link href="https://rawgit.com/jonthornton/jquery-timepicker/master/jquery.timepicker.css" rel="stylesheet"/>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/jonthornton/jquery-timepicker/master/jquery.timepicker.min.js"></script>
<div class="col-sm-5">
<input id="timeWithDuration" type="text" class="form-control ui-timepicker-input" name="from_time" placeholder="What time?" autocomplete="off">
</div>
<div class="col-sm-5">
<input id="duration" type="text" class="form-control ui-timepicker-input" placeholder="Duration" autocomplete="off">
</div>
As #Shlomi Hassid pointed out in his answer, you would also want to use the timepicker's changeTime event, rather than the native change event, so that the function will only execute when the input in your #timeWithDuration timepicker is a valid time.

Use jquery timepicker and datepicker simultaneously

I need to use both timepicker and datepicker. But only one of them works. My code is mentioned below. I am using multiple jquery files.
<script type="text/javascript">
$(document).ready(function() {
$(".datepicker").datepicker({
changeMonth: true,
changeYear: true
});
});
</script>
<script type="text/javascript">
$(document).ready(function() {
$('.timepicker').timepicker({
showPeriod: true,
showLeadingZero: true
});
});
</script>
Date : <input type="text" class="datepicker"/>
Time : <input type="text" class="timepicker"/>
Check Timepicker with Datepicker This one plugin has both pickers as a single component.
I used https://github.com/trentrichardson/jQuery-Timepicker-Addon
<link href="yourpath/jquery-ui-timepicker-addon.css'?>" rel="stylesheet" media="all">
<script src="yourpath/jquery-ui-timepicker-addon.js'?>"></script>
$(function() {
$( ".datepicker" ).datepicker();
});
$(function() {
$(".timepicker").timepicker();
});
and html
input type="text" name="date" value="" placeholder="Conference Name" id="datepicker"
input type="text" name="start_time" value="" placeholder="Starting Time" class="timepicker"
input type="text" name="end_time" value="" placeholder="Ending Time" class="timepicker"
it works for me.I think its jquery version problem
Make sure the library is loaded from CDN http://cdnjs.com/libraries/jquery-ui-timepicker-addon
Once the js and CSS are loaded successfully, you can use the plugin as per examples given in httpp://jonthornton.github.io/jquery-timepicker/. I used the following options to get AM/PM selector;
$('input.timepicker').timepicker({controlType: 'select',
timeFormat: 'hh:mm TT',
dropdown: true,
scrollbar: false,
ampm: true});
For detailed options list refer to httpp://timepicker.co/options/
2 links have httpp instead of http cz SO wouldn't allow me to post many links in one answer.

Categories