Jquery functions does not work on dynamic generated form component? - javascript

I'm using this jQuery function with jQuery UI to generate a datepicker when the user hits one textfield:
<script>
$(function() {
var dates = $( "#from, #to" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
changeYear: true,
numberOfMonths: 1,
onSelect: function( selectedDate ) {
var option = this.id == "from" ? "minDate" : "maxDate",
instance = $( this ).data( "datepicker" ),
date = $.datepicker.parseDate(
instance.settings.dateFormat ||
$.datepicker._defaults.dateFormat,
selectedDate, instance.settings );
dates.not( this ).datepicker( "option", option, date );
}
});
});
</script>
As you can see it respond to the textfields from and to. The textfields are in my html code like:
<div class="clearfix">
<label for="from">From</label>
<input type="text" id="from" name="from" class="xlarge"/>
</div>
<div class="clearfix">
<label for="to">to</label>
At this point everything works. Later, in the same form a let the user to clone this form elements using this other code:
$(document).ready(function() {
var removeButton = 'remove';
$('#addl').click(function() {
$('div.jobitems:last').after($('div.jobitems:first').clone());
$('div.jobitems:last').append(removeButton);
$('div.jobitems:last input').each(function(){
this.value = '';
});
});
$('#remove').live('click', function() {
$(this).closest('div.jobitems').remove();
});
});
<input type="text" id="to" name="to" class="xlarge"/>
</div>
When the user clone the elements, the new ones do not respond to the function that generates the datepicker. I'm really confused about this. Here you can check the running code: http://domingo.net46.net/example/reg.php

You have to call the function that make the datapicker happen again after the append of the html elements so that the datepicker work on them because i can see that the datepicker function is called on the document ready and you have another function that append html element so you have to call the datepicker function right after you append the html elemnt.
$(DoAction);
function DoAction() {
var dates = $( "#from, #to" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
changeYear: true,
numberOfMonths: 1,
onSelect: function( selectedDate ) {
var option = this.id == "from" ? "minDate" : "maxDate",
instance = $( this ).data( "datepicker" ),
date = $.datepicker.parseDate(
instance.settings.dateFormat ||
$.datepicker._defaults.dateFormat,
selectedDate, instance.settings );
dates.not( this ).datepicker( "option", option, date );
}
});
}
$(document).ready(function() {
var removeButton = 'remove';
$('#addl').click(function() {
$('div.jobitems:last').after($('div.jobitems:first').clone());
$('div.jobitems:last').append(removeButton);
$('div.jobitems:last input').each(function(){
this.value = '';
});
DoAction();
});
$('#remove').live('click', function() {
$(this).closest('div.jobitems').remove();
});
});

The issue could be on the line that is as follows:
this.value = '';
Try changing this to become:
$(this).value = '';
Then it should work as it's creating a jQuery object

If the cloned elements have the same id as the originals, I'm not surprised that the datepicker will only act on the first elements it finds.

Related

Datepicker ui - check if dates from/to overlapping disabled days

I have 2 datepickers - date from and date to, something like hotel reservation system. How do I check (and show hidden div.error) if there are some disabled days in selected period?
Ex. - selected dates - from 2021-12-20 to 2021-12-31; disabled days are ["2021-12-25", "2021-12-26"] -> show "error".
<div class="error" style="display:none">Sorry, but we have no available rooms in selected dates.</div>
<script>
$( function() {
var disableddates = ["2021-12-25", "2021-12-26"];
$.datepicker.setDefaults($.datepicker.regional["de"]);
$( "#from" ).datepicker({
beforeShowDay: function(date){
var string = jQuery.datepicker.formatDate("yy-mm-dd", date);
return [ disableddates.indexOf(string) == -1 ]
}
});
$( "#to" ).datepicker({
beforeShowDay: function(date){
var string = jQuery.datepicker.formatDate("yy-mm-dd", date);
return [disableddates.indexOf(string) == -1 ]
}
});
});
</script>

jQuery finding descendant by ID not working

I'm trying to change the value of a jQuery datepicker input element in a form to the first date in the week of the user-selected date once the submit button is clicked but before the form is actually submitted.
I'm finding that the following Javascript works (using a class selector in .find()):
$("form").submit( function(event) {
$(this).closest('form').find('.week-picker').datepicker( "setDate", startDate );
var current_date = $(this).closest('form').find('.week-picker').datepicker( "getDate" );
return;
});
startDate is a Date object.
But this code does not work (using an ID selector in .find()):
$("form").submit( function(event) {
$(this).closest('form').find("#week-picker").datepicker( "setDate", startDate );
var current_date = $(this).closest('form').find('.week-picker').datepicker( "getDate" );
return;
});
console.log($(this).closest('form').find(".week-picker").datepicker( "setDate", startDate ).val()); produces a proper date, like 06/27/2018.
console.log($(this).closest( 'form' ).find('#week-picker').val()); produces undefined.
Why is this happening? Isn't an ID a valid selector?
HTML:
<form action="/checkin" method="post">
<div class="form-group row mb-2">
<div class="col-md-6 offset-md-3">
<input class="week-picker form-control" type="text" id="week-picker" name="week_start" placeholder="Select week" style="opacity: 0;position: absolute;">
</div>
</div>
<div class="form-group row mt-4">
<div class="col">
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
</div>
</div>
</form>
The datepicker portion of my JS:
var startDate;
var endDate;
var selectCurrentWeek = function() {
window.setTimeout(function () {
$('.week-picker').find('.ui-datepicker-current-day a').addClass('ui-state-active')
}, 1);
}
$('.week-picker').datepicker( {
showOtherMonths: true,
selectOtherMonths: true,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
var dateFormat = inst.settings.dateFormat || $.datepicker._defaults.dateFormat;
$(this).closest( 'form' ).find('#startDate').text($.datepicker.formatDate( dateFormat, startDate, inst.settings ));
$(this).closest( 'form' ).find('#endDate').text($.datepicker.formatDate( dateFormat, endDate, inst.settings ));
selectCurrentWeek();
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
});
$(document).on( 'mousemove','.week-picker .ui-datepicker-calendar tr',function() {$(this).find('td a').addClass('ui-state-hover'); });
$(document).on('mouseleave','.week-picker .ui-datepicker-calendar tr',function() {$(this).find('td a').removeClass('ui-state-hover'); });
#week-picker is a valid selector, as long as your input has that ID assigned. What is happening in your case is that there is JS turning your input into a datepicker, and it changes the ID of the element when it loads. As you posted from your element inspector, your input no longer has the week-picker ID, it is now dp1529862475978.
This is not uncommon, and the behavior you're getting is the expected one. If you need to make sure that you're targeting this datepicker instead of another one with the same class, you can use the name attribute:
$("input[name='week_starting']")
You should never have 2 inputs with the same name on the same page, so it's as unique as an ID. The ID you're seeing in the element inspector is probably randomly generated, so you don't want to use that.

Datepicker disables previous and future dates wrong

I've created a datepicker for my form and it selects the current date and disables past dates.
jQuery(document).ready(function($){
var dateToday = new Date();
var dates = $("#from, #to").datepicker({
defaultDate: "+1w",
changeMonth: false,
numberOfMonths: 1,
minDate: dateToday,
onSelect: function(selectedDate) {
var option = this.id == "from" ? "minDate" : "maxDate",
instance = $(this).data("datepicker"),
date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings);
dates.not(this).datepicker("option", option, date);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<input type="text" id="from" name="FechaLlegada" class="campo" placeholder="Llegada" focusOnShow="false" ignoreReadonly="true" readonly="true">
<input type="text" id="to" name="FechaSalida" class="campo" placeholder="Salida" focusOnShow="false" ignoreReadonly="true" readonly="true">
But the problem is that when I select a "from" date and then a "to" date, my "to" date block my "from" date. So for example if I select "from" 10 july "to" 15 july, then I can't change my from date anymore after 15 july. It blocks me future dates after the "to" date selected.
Is like if I select the "to" date it makes it the maxDate until I reload the page.
How can I prevent this maxDate so I can always select the date I want? The only restriction I need is to disable past dates from today date.
Try this code
Removed code setting maxDate for from datepicker
var dateToday = new Date();
var dates = $("#from, #to").datepicker({
defaultDate: "+1w",
changeMonth: false,
numberOfMonths: 1,
minDate: dateToday,
onSelect: function(selectedDate) {
var option = this.id == "from" ? "minDate" : null,
instance = $(this).data("datepicker"),
date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings);
if(option!==null){
dates.not(this).datepicker("option", option, date);
}
}
});
var dateToday = new Date();
var dates = $("#from, #to").datepicker({
defaultDate: "+1w",
changeMonth: false,
numberOfMonths: 1,
minDate: dateToday,
onSelect: function(selectedDate) {
var option = this.id == "from" ? "minDate" : null,
instance = $(this).data("datepicker"),
date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings);
if(option!==null){
dates.not(this).datepicker("option", option, date);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" />
<input type="text" id="from" name="FechaLlegada" class="campo" placeholder="Llegada" focusOnShow="false" ignoreReadonly="true" readonly="true">
<input type="text" id="to" name="FechaSalida" class="campo" placeholder="Salida" focusOnShow="false" ignoreReadonly="true" readonly="true">
Assuming that you are talking about jquery 2.1.1 and jquery-ui 1.12.1 as described in documentation you should consider the destroy method to re-elaborate minDate and maxDate options - but that would be tricky. So i would consider to use a timerange datepicker in this case to get the desidered result.
$(function () {
var dateToday = new Date();
var dateFormat = "mm/dd/yy",
from = $("#from")
.datepicker({
defaultDate: "+1w",
changeMonth: false,
numberOfMonths: 1,
minDate: dateToday
})
.on("change", function () {
to.datepicker("option", "minDate", getDate(this));
}),
to = $("#to").datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 3
})
.on("change", function () {
from.datepicker("option", "maxDate", getDate(this));
});
function getDate(element) {
var date;
try {
date = $.datepicker.parseDate(dateFormat, element.value);
} catch (error) {
date = null;
}
return date;
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<input type="text" id="from" name="FechaLlegada" class="campo" placeholder="Llegada" focusOnShow="false" ignoreReadonly="true" readonly="true">
<input type="text" id="to" name="FechaSalida" class="campo" placeholder="Salida" focusOnShow="false" ignoreReadonly="true" readonly="true">

How to show month in one datepicker based on the selection of month in another datepicker

Here is the snippet where i need to fix the requirement
Here i used jquery for datepicker
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes
/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
Here i gave datepicker to choose month by dropdownlist but problem is in two fields the user can select the month but i need to restrict the month selection in "to" field because the second datepicker should show the month of "from field" itself
$(document).ready(function () {
$("#datepicker,#datepicker1").datepicker({
changeMonth: true,
changeYear: true,
yearRange: "-0:c+10",
dateFormat: "dd - M - yy"
});
$('#datepicker,#datepicker1').datepicker("setDate", new Date());
});
Here are the two datepickers with two fieldnames "from" and "to"
<li><label class="label">From:</label></li>
<li><input name="fdate" type="text" class="sel" size="10"
id="datepicker" required /><li>
<li><label class="label1">To:</label></li>
<li><input name="tdate" type="text" class="sel" size="10"
id="datepicker1" required /><li>
<li ><label class="label" >Weeks:</label></li>
Below is the snippet for above requirement......
<head>
<title>Testing</title>
<link href="css/jquery-ui-start-custom-1.10.3.css" rel="stylesheet" type="text/css" />
<style type="text/css">
.ui-datepicker-next, .ui-datepicker-prev { display: none; }
</style>
<script src="scripts/jquery-1.10.1.min.js" type="text/javascript"></script>
<script src="scripts/jquery-ui-custom-1.10.3.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.ui-datepicker-prev ui-corner-all').hide();
$("#datepicker").datepicker({
changeMonth: true,
changeYear: true,
yearRange: "-0:c+10",
dateFormat: "dd - M - yy",
onClose: function(selectedDate) {
$('#datepicker1').datepicker("setDate", selectedDate);
}
});
$('#datepicker').datepicker("setDate", new Date());
$("#datepicker1").datepicker({
yearRange: "-0:+0",
dateFormat: "dd - M - yy"
});
});
</script>
</head>
Small script that Iam using....try with this
var startDateTextBox = $('#datepicker');
var endDateTextBox = $('#datepicker1');
startDateTextBox.datepicker({
changeYear: true,
yearRange : 'c-30:c',
dateFormat:"yy-mm-dd",
onClose: function(dateText, inst) {
if (endDateTextBox.val() != '') {
var testStartDate = startDateTextBox.datepicker('getDate');
var testEndDate = endDateTextBox.datepicker('getDate');
if (testStartDate > testEndDate)
endDateTextBox.datepicker('setDate', testStartDate);
}
else {
endDateTextBox.val(dateText);
}
},
onSelect: function (selectedDate){
endDateTextBox.datepicker('option', 'minDate', startDateTextBox.datepicker('getDate') );
}
});
endDateTextBox.datepicker({
changeYear: true,
yearRange : 'c-30:c',
dateFormat:"yy-mm-dd",
onClose: function(dateText, inst) {
if (startDateTextBox.val() != '') {
var testStartDate = startDateTextBox.datepicker('getDate');
var testEndDate = endDateTextBox.datepicker('getDate');
if (testStartDate > testEndDate)
startDateTextBox.datepicker('setDate', testEndDate);
}
else {
startDateTextBox.val(dateText);
}
},
onSelect: function (selectedDate){
startDateTextBox.datepicker('option', 'maxDate', endDateTextBox.datepicker('getDate') );
}
});
hope it gives you an idea...
$(document).ready(function() {
$(function() {
$( "#fromDate" ).datepicker({
yearRange: "-50:+20",dateFormat: 'dd/mm/yy',showOn: "button",changeMonth: true,changeYear: true,
buttonImage:""+appctx``+"/images/index.jpeg" ,buttonImageOnly: true ,buttonText: "",autoSize:true ,
onSelect: function( selectedDate ) {
$( "#toDate" ).datepicker( "option", "minDate", selectedDate );
},
changeMonth: true,
changeYear: true
});
});
$( "#toDate" ).datepicker({
yearRange: "-50:+20",dateFormat: 'dd/mm/yy',showOn: "button",changeMonth: true,changeYear: true,
buttonImage:""+appctx+"/images/index.jpeg" ,buttonImageOnly: true ,buttonText: "",autoSize:true ,
onSelect: function( selectedDate ) {
$( "#fromDate" ).datepicker( "option", "maxDate", selectedDate );
},
changeMonth: true,
changeYear: true
});
});

Javascript new date() conversion

Im having some troubles with conversion. It says invalid date when alert(first_date) and alert(end_date),etc :s Im using datetimepicker to get the dates.
$( "#start_date" ).datetimepicker({
dateFormat : 'yy-mm-dd',
timeFormat: 'hh:mm:ss',
defaultDateTime: "+1w",
showSecond: true,
changeMonth: true,
changeYear: true,
onClose: function( selectedDateTime ) {
$( "#end_date" ).datetimepicker( "option", selectedDateTime );
}
});
$( "#end_date" ).datetimepicker({
dateFormat : 'yy-mm-dd',
timeFormat: 'hh:mm:ss',
defaultDateTime: "+1w",
showSecond: true,
changeMonth: true,
changeYear: true,
onClose: function( selectedDateTime ) {
$( "#start_date" ).datetimepicker( "option", selectedDateTime );
}
});
Now, I need to do something like this:
var first_date = new Date($('#start_date').val());
var last_date = new Date($('#end_date').val());
var nDifference = (last_date - first_date);
var one_day = 1000*60*60*24;
var days = Math.round(nDifference/one_day);
<input type="text" id="start_date" name="start_date" value=""/>
<input type="text" id="end_date" name="end_date" value=""/>
Javascript date reliably accepts ISO date formats...
d = '2012-01-01 06:16:16'
console.log(new Date(d)) // invalid
console.log(new Date(d.replace(' ','T'))) // valid!
// Z at the end accounts for local timezone offset
console.log(new Date(d.replace(' ','T')+'Z'))

Categories