I've got a jQuery date picker control that works fine for once instance, but I'm not sure how to get it to work for multiple instances.
<script type="text/javascript">
$(function() {
$('#my_date').datepicker();
});
</script>
<% Using Html.BeginForm()%>
<% For Each item In Model.MyRecords%>
<%=Html.TextBox("my_date")%> <br/>
<% Next%>
<% End Using%>
Without the For Each loop, it works fine, but if there's more than one item in the "MyRecords" collection, then only the first text box gets a date picker (which makes sense since it's tied to the ID). I tried assigning a class to the text box and specifying:
$('.my_class').datepicker();
but while that shows a date picker everywhere, they all update the first text box.
What is the right way to make this work?
This question is related to
javascript
jquery
jquery-ui
<html>
<head>
<!-- jQuery JS Includes -->
<script type="text/javascript" src="jquery/jquery-1.3.2.js"></script>
<script type="text/javascript" src="jquery/ui/ui.core.js"></script>
<script type="text/javascript" src="jquery/ui/ui.datepicker.js"></script>
<!-- jQuery CSS Includes -->
<link type="text/css" href="jquery/themes/base/ui.core.css" rel="stylesheet" />
<link type="text/css" href="jquery/themes/base/ui.datepicker.css" rel="stylesheet" />
<link type="text/css" href="jquery/themes/base/ui.theme.css" rel="stylesheet" />
<!-- Setup Datepicker -->
<script type="text/javascript"><!--
$(function() {
$('input').filter('.datepicker').datepicker({
changeMonth: true,
changeYear: true,
showOn: 'button',
buttonImage: 'jquery/images/calendar.gif',
buttonImageOnly: true
});
});
--></script>
</head>
<body>
<!-- Each input field needs a unique id, but all need to be datepicker -->
<p>Date 1: <input id="one" class="datepicker" type="text" readonly="true"></p>
<p>Date 2: <input id="two" class="datepicker" type="text" readonly="true"></p>
<p>Date 3: <input id="three" class="datepicker" type="text" readonly="true"></p>
</body>
</html>
The solution here is to have different IDs as many of you have stated. The problem still lies deeper in datepicker. Please correct me, but doesn't the datepicker have one wrapper ID - "ui-datepicker-div." This is seen on http://jqueryui.com/demos/datepicker/#option-showOptions in the theming.
Is there an option that can change this ID to be a class? I don't want to have to fork this script just for this one obvious fix!!
The obvious answer would be to generate different ids, a separate id for each text box, something like
[int i=0]
<% Using Html.BeginForm()%>
<% For Each item In Model.MyRecords%>
[i++]
<%=Html.TextBox("my_date[i]")%> <br/>
<% Next%>
<% End Using%>
I don't know ASP.net so I just added some general C-like syntax code within square brackets. Translating it to actual ASP.net code shouldn't be a problem.
Then, you have to find a way to generate as many
$('#my_date[i]').datepicker();
as items in your Model.MyRecords
. Again, within square brackets is your counter, so your jQuery function would be something like:
<script type="text/javascript">
$(function() {
$('#my_date1').datepicker();
$('#my_date2').datepicker();
$('#my_date3').datepicker();
...
});
</script>
In my case, I had not given my <input>
elements any ID, and was using a class to apply the datepicker as in SeanJA's answer, but the datepicker was only being applied to the first one. I discovered that JQuery was automatically adding an ID and it was the same one in all of the elements, which explained why only the first was getting datepickered.
There is a simple solution.
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"> </script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script type="text/javascript" src="../js/flexcroll.js"></script>
<script type="text/javascript" src="../js/jquery-ui-1.8.18.custom.min.js"></script>
<script type="text/javascript" src="../js/JScript.js"></script>
<title>calendar</title>
<script type="text/javascript">
$(function(){$('.dateTxt').datepicker(); });
</script>
</head>
<body>
<p>Date 1: <input id="one" class="dateTxt" type="text" ></p>
<p>Date 2: <input id="two" class="dateTxt" type="text" ></p>
<p>Date 3: <input id="three" class="dateTxt" type="text" ></p>
</body>
</html>
A little note to the SeanJA answer.
Interestingly, if you use KnockoutJS and jQuery together the following inputs with different IDs, but with the same data-bind observable:
<data-bind="value: first_dt" id="date_1" class="datepick" />
<data-bind="value: first_dt" id="date_2" class="datepick" />
will bind one (the same) datepicker to both of the inputs (even though they have different ids or names).
Use separate observables in your ViewModel to bind a separate datepicker to each input:
<data-bind="value: first_dt" id="date_1" class="datepick" />
<data-bind="value: second_dt" id="date_2" class="datepick" />
Initialization:
$('.datepick').each(function(){
$(this).datepicker();
});
To change use of class instead of ID
<script type="text/javascript">
$(function() {
$('.my_date1').datepicker();
$('.my_date2').datepicker();
$('.my_date3').datepicker();
...
});
</script>
When adding datepicker at runtime generated input textboxes you have to check if it already contains datepicker then first remove class hasDatepicker then apply datePicker to it.
function convertTxtToDate() {
$('.dateTxt').each(function () {
if ($(this).hasClass('hasDatepicker')) {
$(this).removeClass('hasDatepicker');
}
$(this).datepicker();
});
}
I just had the same problem.
The correct way to use date pick is $('.my_class').datepicker();
but you need to make sure you don't assign the same ID to multiple datepickers.
I had a similar problem with dynamically adding datepicker classes. The solution I found was to comment out line 46 of datepicker.js
// this.element.on('click', $.proxy(this.show, this));
I had the same problem, but finally discovered that it was an issue with the way I was invoking the script from an ASP web user control. I was using ClientScript.RegisterStartupScript()
, but forgot to give the script a unique key (the second argument). With both scripts being assigned the same key, only the first box was actually being converted into a datepicker. So I decided to append the textbox's ID to the key to make it unique:
Page.ClientScript.RegisterStartupScript(this.GetType(), "DPSetup" + DPTextbox.ClientID, dpScript);
Source: Stackoverflow.com