jQuery dynamically created datepicker not working - javascript

I already did what most of the solutions I see but it doesn't work on mine.
Here's my code:
function regenerateDatePickers()
{
var length = $( ".forduplication" ).length;
alert( length );
for ( var i = 1 ; i <= length ; i++ ) {
$( "#endDate" + i ).removeClass( "hasDatepicker" );
$( "#endDate" + i ).datepicker();
}
}
Only the original datepicker field is working. The cloned ones are not.
The Weird thing though is that my dynamically created "chosen"* fields are working.
*chosen http://harvesthq.github.com/chosen/
EDIT
- Added HTML code
<tr class="forduplication">
<td>
...
...<!--lots of other HTML codes-->
...
</td>
<td><input id="endDate1" name="endDatefield1" size="10"></td>
...
</tr>

Update 06/01/15
.live() is not longer supported. Using .on() this can be solved.
$('body')
.on('click', '.datePick', function() {
$(this).datepicker();
})
.on('focus', '.datePick', function() {
$(this).datepicker();
});
You could use live and focusin
Have a class for all the input fields, in this case I used datePick as the class
$('input.datePick').live('focusin', function() {
$(this).datepicker();
});​
Hope this helps

One way to do it is to destroy and reassign datepicker on every click but it has performence issue
$('input[id^="endDate"]').live('click', function() {
$(this).datepicker('destroy').datepicker({showOn:'focus'}).focus();
});
it works but remove and add datepicker every time you click on a input. So it's bettter if you can do this just after cloning the input like
....clone().datepicker('destroy').datepicker({showOn:'focus'});
and then add that element to where you want it to be.

Related

Firefox won't update value on second click

So I've taken over a project that is almost ready to launch, a site where you can lease cars. I've uploaded the main part of the service here: http://erikblomqvist.se/junk/car/
Everything works smoothly except for the color changing function (the colored boxes under the headline Färgalternativ). It's supposed to update the price on the colors from brown to light gray (#4 - #8) – those are a bit more expensive, since they are in metallic.
In Chrome, this works as planned, but in Firefox, if I first select a metallic color, then a non-metallic, and THEN a the same metallic again, the price won't change back. It changes correctly the first time, but not the second time I click that metallic color.
In Safari, the price doesn't change at all (I'm guessing that if the Firefox problem gets solved, Safari gets solved as well).
The function is based on a data-name on the color boxes, that gets checked with this function:
$( '#car-colors .color' ).each(function() {
$( this ).on( 'click', function() {
selected_color = undefined;
var color_name = $( this ).data('name');
$( '#car-colors .color' ).not( this ).removeClass('selected');
$( this ).addClass('selected');
$( 'option', color_select ).each( function() {
if( $( this ).val() == color_name ) {
color_select.find( 'option' ).removeAttr('selected');
$( this ).attr('selected', 'selected');
}
});
$( '.selected-color-name' ).fadeIn();
$( '.selected-color-name span' ).html( color_name );
var selected_color = color_select.children(':selected');
checkSelectedColor(selected_color);
});
});
The variable color_select is defined as $( '#order-color-select' ).
The function checkSelectedColor is defined here:
function checkSelectedColor(selected_color) {
if( selected_color.data('is-metallic') == 'yes' ) {
color_checkbox.prop('checked', true);
} else {
color_checkbox.prop('checked', false);
}
color_input.val( selected_color.val() );
calculatePrice();
}
I've added stuff like selected_color = undefined to make sure that the variable is reseted, but after a color that has an <option data-is-metallic="yes"> (inside of #order-color-select) is selected a second time, it handles the value as "no" instead of "yes".
I can't get my head around on why this is, especially only in Firefox/Safari.
I've included the beautified version of the car functions here: http://pastebin.com/i5bup5rx
Appreciate any kind of help that could lead me in the right direction of getting this solved!
Thanks
I think the error is in setting the selected option in the select element using .attr().
Instead you can just set the value of the select element like
$('#car-colors .color').on('click', function() {
var color_name = $(this).data('name');
$('#car-colors .color').not(this).removeClass('selected');
$(this).addClass('selected');
$('#order-color-select').val(color_name);
$('.selected-color-name').fadeIn();
$('.selected-color-name span').html(color_name);
var selected_color = color_select.children(':selected');
checkSelectedColor(selected_color);
});

Triggering datepicker from function doesnt work

I use a pickadate.js plugin.
What i would like to do is to trigger a date container after checkbox is checked, but it somehow doesn't work. I assume it has to do something with out of the scope variables since it works just fine outside the checkbox event function.
Official documentation:
See here and also here
JS:
var pick = $('#chosen').pickadate({format:'dd.mm.yyyy'});
var picker = pick.pickadate('picker');
//picker.open();
// it works here
$(":checkbox").change(function() {
if(this.checked) {
picker.open();
// it doesnt work here
event.stopPropagation();
console.log('checkbox triggers!');
}
});
JSFIDDLE
Use .on() with click. (like (.on("event", fn)))
$(":checkbox").on('click', function () {
if (this.checked) {
picker.open();
event.stopPropagation();
}
});
Fiddle
I used trigger method and now I think it works as intended:
$( "input[type=checkbox]" ).on( "click", function(){
$(":checkbox").trigger("change");
} );
Fiddle

Trying to use jQuery to filter Unordered List

I think I'm on the right track, but I just can't get this to work.
I'm using an inline javascript call with
<script type="text/javascript">
$( 'a.sort' ).on( 'click', function( e ) {
e.preventDefault();
toSort = $( this ).data( 'type' );
$( '.common-li-class' ).not( toSort ).hide();
} );
</script>
And then adding class="common man" or class="common woman", etc.. to my li's
Lastly, I added links to trigger these with:
<a class="sort" data-type="man" href="#">Men</a>
<a class="sort" data-type="woman" href="#">Women</a>
But it doesn't seem to be doing anything.
The script that you had used would evaluate the selector as $('.common-li-class').not('man').hide(); But as per the html reference you had given man is a class, so we have to prefix it with dot in order to make that selector valid.
Try,
$('.common-li-class').not('.' + toSort).hide();
Looking through your jsfiddle (http://jsfiddle.net/3LAHJ), it just seems like you had the wrong selector for selecting the list items that you are trying to filter. You have .common-li-class when all you need is .common or li.common.
<script type="text/javascript">
$('a.sort').on('click', function(e) {
e.preventDefault();
toSort = $( this).data('type');
$('.common').not('.' + toSort).hide();
} );
</script>

How to add new hidden HTML with best performance?

I have a large block of HTML that needs to be replaced, which includes fadeOut/fadeIn transitions. I can't figure out how to add the HTML to the page (hidden) without wrapping it in a div.
$.get('/ajax', function(newHtml){
var $newEvent = $('<div class="new-event" />').hide().html(newHtml);
$('#content .event').fadeOut('slow', function(){
$(this).remove(); //old event
$newEvent.appendTo('#content').fadeIn('slow').removeClass('new-event'); //then remove the wrapper div that I didnt need in the first place
});
});
What is the best way to do this while utilizing best practices for performance?
Solution:
For some reason, I thought that creating a new element like this: $(newHtml) was less efficient (bad performance) than html(newHtml). But apparently, they are the same as far as performance goes (I have no data to back this up other than my own observations).
So the following code is just as efficient as the previous:
$.get('/ajax', function(newHtml){
var $newEvent = $(newHtml).hide();
$('#content .event').fadeOut('slow', function(){
$(this).remove(); //old event
$newEvent.appendTo('#content').fadeIn('slow');
});
});
When adding the code to the page, have top level elements all be hidden
<div style="display:none;">...</div>
When fadeIn is called jQuery automatically removes it for you.
If you can't modify the returned html just do it this way then,
$(newHtml).hide().appendTo('#content');
That will hide it before being added to the DOM.
How about something like
$('#content .event').fadeOut('slow', function()
{
$(this).html(newHtml).fadeIn('slow');
});
Why you don't simply replace the content of .event instead of removing it and creating a new one?
$.get( '/ajax', function( newHtml )
{
$( '#content .event' ).fadeOut( 'slow', function ()
{
$( this ).html( newHtml ).fadeIn( 'slow' );
});
});
Edit
If you really need to remove the entire node, you can do this instead
$( this ).remove();
$( '<div class="new-event">' ).appendTo( $('#content') ).html( newHtml ).fadeIn( 'slow' );
You could just have it as a javascript string, and add it when you need.
var $newEvent = $(newHtml);
// and later on
$( '#content .event' ).fadeOut('slow', function ()
{
$(this).append($newEvent).fadeIn( 'slow' );
});

jQuery Mobile -> Override jQuery UI Datepicker -> Layout broken

I am using jQuery Mobile in my web application. There is a datepicker which overrides the default jQuery UI datepicker.
Here is the source:
https://github.com/jquery/jquery-mobile/tree/master/experiments/ui-datepicker
The JavaScript file which overrides it, is here:
https://github.com/jquery/jquery-mobile/blob/master/experiments/ui-datepicker/jquery.ui.datepicker.mobile.js
I have this line of code:
$(".ui-page").live("pagecreate", function(){
$("input[type='date'], input[data-type='date']").each(function(){
$(this).after($("<div />").datepicker({ altField: "#" + $(this).attr("id"), showOtherMonths: true }));
});
});
In this case, I get a datepicker which is always visible. To have the visibility only if a user clicks into a date text field, the datepicker must be connected to the input field, which is here not the case.
So I have to delete the .after("<div />"). But then, the design of the datepicker is totally broken, it seems that the rewrite of the datepicker does not take effect, because the CSS styles are not applied.
So, what's wrong here?
Thank you in advance & Best Regards.
This was my solution
$( ".ui-page" ).live( "pagecreate", function(){
$( "input[type='date'], input:jqmData(type='date')" ).each(function(){
$(this).after( $( "<div />" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true }) );
});
$('.hasDatepicker').hide();
$( "input[type='date'], input:jqmData(type='date')" ).click(function(){
$(this).next('.hasDatepicker').show();
})
$( '.ui-datepicker-calendar a' ).live('click', function() {
$( '.hasDatepicker' ).hide('slow');
});
});
To fix the calendar problem you just need to change a selector in Squish's code
$( '.ui-datepicker-calendar a' ).live('click', function() {
$( '.hasDatepicker' ).hide('slow');
});
Example Here
Creating this in a dialog is simple too, just put it in another html and call it like so
Open dialog
Dialog Documentation
You were correct, I apologize for not properly implementing it the first time.
This should fix your issue:
It will hide your calendar on load, show it when the input is in focus (clicked on or tabbed to) and hide it again as soon as a date is selected (but will not interfere with switching months).
$(function()
{
$( '.hasDatepicker' ).hide();
$( '#date' ).focus(function() {
$( '.hasDatepicker' ).show('slow');
});
$( '.ui-body-c a' ).live('click', function() { // .live() event important
//or else clicks stop functioning
//after first selection
$( '.hasDatepicker' ).hide('slow');
});
});
Here is the example live
I had the same issue with two datepickers in the same page. This was my solution:
HTML code:
<div data-role="fieldcontain">
<div id="startPicker">
<input type="date" name="startDate" id="startDate" value=""/>
</div>
<div id="endPicker">
<input type="date" name="endDate" id="endDate" value=""/>
</div>
</div>
This was tested in Safari browser.
Inspect the date input element.
Look that, inside the <div data-role="fieldcontain" ...>. there is a new DIV that was created dinamically and has this id="dp1298574069963". I captured it in a variable (var idDivStart = $("#startPicker div").attr("id");) and use it variable to specify that all elements inside that Div that has the ui-datepicker class will be shown ($("#"+idDivStart+" .ui-datepicker").show();).
JS code:
$(function() {
$(".ui-datepicker").hide();
// startDate datepicker
var idDivStart = $("#startPicker div").attr("id");
$("#startDate").focus(function() {
$("#"+idDivStart+" .ui-datepicker").show();
});
// endDate datepicker
var idDivEnd = $("#endPicker div").attr("id");
$("#endDate").focus(function() {
$("#"+idDivEnd+" .ui-datepicker").show();
});
//
$(".ui-datepicker-calendar a").live("click", function() {
$(".ui-datepicker").hide();
});
//
$(".inputsText").focus(function() {
$(".ui-datepicker").hide();
});
//
$("div").attr("tabindex",-1).focus(function() {
$(".ui-datepicker").hide();
});
});
I hope to help you.
The author of mobile datepicker has a functioning example on his git page.
It hides the datepicker and displays an input box as intended. What exactly is the difference between your implementation and the standard? Can you give a working snippet of what you're doing? You can mark it up on JSBin if you feel that'll be easier.
I had a similar problem working with two dates and this worked:
Markup (C# MVC3):
<div data-role="fieldcontain" id="fooDate1Div">
<%: Html.LabelFor(model => model.fooDate1) %>
<%: Html.TextBox("fooDate1", Model == null ? Customer.GetLocalTime().ToString("d") : Model.fooDate1.ToString("d"), new Dictionary<string, object>{{"type", "date"}, {"id", "fooDate1"}})%>
<%: Html.ValidationMessageFor(model => model.fooDate1)%>
</div>
<div data-role="fieldcontain" id="fooDate2Div">
<%: Html.LabelFor(model => model.fooDate2) %>
<%: Html.TextBox("fooDate2", Model != null ? Model.fooDate2 : null, new Dictionary<string, object>{{"type", "date"}, {"id", "fooDate2"}})%>
<%: Html.ValidationMessageFor(model => model.fooDate2) %>
</div>
Script:
<script>
$(function () {
$(".ui-datepicker").hide();
// fooDate1 datepicker
var idDivStart = $("#fooDate1Div div").attr("id");
$("#fooDate1").focus(function () {
$("#" + idDivStart + " .ui-datepicker").show('fast');
});
// followUp datepicker
var idDivEnd = $("#fooDate2Div div").attr("id");
$("#fooDate2").focus(function () {
$("#" + idDivEnd + " .ui-datepicker").show();
});
$(".ui-datepicker-calendar a").live("click", function () {
$(".ui-datepicker").hide();
});
});
</script>

Categories

Resources