I am using the Chosen JS jQuery plugin & I am trying to get it to rerender every time a cloned element (using true, ture - this is because I need to copy the on click events) is appended to the dom.
This is my code:
var container = jQuery(self.options.parent_class + ' tbody tr:first-child'),
container_clone = container.clone(true,true);
var elem = container_clone.find('select');
elem.chosen('destroy');
elem.chosen();
return container_clone;
Here it is on fiddle: http://jsfiddle.net/udj7t/1/
Try this,
$(document).ready(function(){
$('select').chosen();
$('a#clone_me').on('click', function(){
var $clone = jQuery('#toClone select:first').clone();
$clone.removeAttr('style');
//$clone.chosen('destroy');
jQuery('#toClone').append($clone);
jQuery('#toClone select:last').chosen();
});
});
Demo
For those interested in a possible solution that will work with clone(true, true), as per the OP's actual question I found that doing the following worked for me. I also had multiple selects in my cloned row so I needed to use the each() method. This could easily be adapted though.
// Look through the cloned row and find each select
$clone.find('select').each(function (){
// Because chosen is a bitch with deep cloned events
// We need to make another internal clone with no events
$clonedChosen = $(this).clone().off();
// Now we can delete the original select box
// AND delete the chosen elements and events
// THEN add the new raw select box back to the TD
$parentTd = $(this).closest('td');
$parentTd.empty().append($($clonedChosen).show());
// Finally, we can initialize this new chosen select
$parentTd.find('select').chosen();
}
Related
I'm dynamically adding new form elements using jquery. For some reason, a call to .datepicker() won't work on the new elements I add, but did work on the old ones that were not added dynamically. If I put .attr('style', 'color: red;')
instead of .datepicker(), it works. Note that the original call inside of the document ready function works.
This is the code that gets called when the add button is clicked:
function addMulti(name) {
it = $('[name=' + name + ']');
base = it.data('baseName');
on = it.data('number') + 1;
name = base + "-" + on;
copy = it.clone()
copy.prop("name", name).attr("data-is-default", false).removeAttr('data-number').
fadeIn('slow').appendTo(it.parent());
it.data('number', on);
if(it.hasClass('date-pickable')) { // <-- This returns true, I checked.
copy.datepicker();
// Where if I add clone.attr('style', 'color: red;') it turns it red.
}
}
This is the call that makes all of the fields that are created at that point date pickers:
<script type="text/javascript">
$(document).ready(function() {
$("input.date-pickable").datepicker()
});
</script>
There are no errors that show up in firebug or the google chrome "inspect element" thing. Something odd is happening though. If I type in the same call as in the document.ready function into the firebug consul, it still won't make the newly added elements datepickers. Yet if I hover over the output, it selects the elements that it should be targeting.
$("input.date-pickable").datepicker() // What I typed in
Object[input#dp1371953134342.field-input 06/22/2013, input#dp1371953134343.field-input, input#dp1371953134342.field-input 06/22/2013, input#dp1371953134342.field-input 06/22/2013] // What it put out. The last three numbers are the IDs JQuery assigned to the added elements. I checked.
jQuery UI's datepicker will always add the class hasDatepicker to any element that has a datepicker to avoid attaching multiple datepickers to the same element.
When you're cloning an element that already has a datepicker, you get that class as well, and you can't attach a new datepicker to the clone, as jQuery UI thinks the element already has a datepicker.
Remove the class from the clone:
var copy = it.clone(false);
copy.removeClass('hasDatepicker').prop("name", name)
.attr("data-is-default", "false").removeAttr('data-number')
.fadeIn('slow').appendTo(it.parent());
and try not to make all your variables global.
Will this work?
<script type="text/javascript">
$(document).ready(function() {
$(document).on('focus',"input.date-pickable", function(){
$(this).datepicker();
});
});
</script>
Demo JSfiddle
I am trying and failing to add datepicker to inputs that are created dynamically.
They have different id's and I am specifically targeting the new input and calling datepicker.
In the jsFiddle example below it only works for the 2nd input (first one datepicker is called on) and does not work for any others after that.
Here is the jsFiddle: http://jsfiddle.net/TJfbc/1/ Press the plus sign to add more.
Note: I am aware the first element will not have the datepicker.
Here's a cleaner alternative
$(function() {
//append one handler to the parent to detect append actions
$('.action_items').on('click', '.expand', function() {
var $el = $(this);
$el.parent()
.clone()
.appendTo($el.closest('.action_items'))
.find('input')
.removeClass('hasDatepicker')
.each(function () {
newName = this.name.slice(0,6) + (parseInt(this.name.slice(6)) + 1);
this.name = newName;
this.id = newName;
})
.datepicker();
//change text, remove original handler, add the remove handler
$el.text('-').off('click').on('click',function(){
$(this).parent().remove();
});
})
});
http://jsfiddle.net/TJfbc/27/
You need to "refresh" the previous textfield that has already class of 'hasDatepicker' before you can initialize a new one
new_action_item.find('.dpDate').removeClass('hasDatepicker').datepicker()
An improvement on readability:
No need to repeatedly call $() on new_action_item since clone() returns an already jQuery object
I have a form with which I use jQuery ".clone()" to add new rows. Everything looks great, however I have a binding problem. Basically, on initialization, I use the jQuery ".datepicker()" function for one field (based on class). If I use ".clone()" by itself I don't get any of the ".datepicker()" functionality with the new item. If I use ".clone(true)" I get the functionality, but for cloned rows it fills the date of the row it was cloned from, not the actual row clicked.
I've tried unbinding/rebinding, but none of this works. So, how do I append new rows to a form while still getting all of the jQuery funness to work properly?
Best
EDIT 1 (jQuery):
function addLineItem(){
$('#charges_table tr:last').clone(true).insertAfter('#charges_table tr:last');
}
$(function(){
$('.date_pick').datepicker({"numberOfMonths": 2});
$("#add_line_item").bind('click',function(event){
event.preventDefault();
addLineItem();
$('.date_pick').datepicker('destroy');
$('.date_pick').datepicker();
})
})
FYI, I'm only binding on class, and the HTML elements aren't using an ID to speak of.
When you .clone(), are you changing the ID of the element before you insert it back into the DOM? If not, your ID would be duplicated, and that could be the source of your trouble.
First, as written, your method addLineItem is always going to clone whatever the last row of the table is: $('#charges_table tr:last'). It sounds like you want to clone the table row within which the click occurred. If that is the case, then something like this should do the trick:
function addLineItem(row){
$(row).clone(true).insertAfter('#charges_table tr:last');
}
$(function(){
$('.date_pick').datepicker({"numberOfMonths": 2});
$("#add_line_item").bind('click',function(event){
event.preventDefault();
// Pass the closest 'tr' element to the element clicked.
addLineItem($(this).closest('tr'));
});
});
I haven't tested this code, but it is based on similar table row cloning code in one of my projects.
I want to dynamically add textfield to the webform. There is 'add' icon beside the existing textfield. when clicking the icon, a new combination of 'add' icon and textfield are added. Then, it is the same situation with the new 'add' icon. How can do that in javascript or jquery framework?
Use the clone() method to clone an element.
$("#add").live("click", function(ev){
var clone = $(ev.target).clone();
//Add the clone to the document, eg: clone.appendTo("body");
})
See also: JQuery Docs - Clone.
Assuming something like:
<div><input><button>add</button></div>
Then try:
var elm;
$('button').click(function() {
elm = $(this).parent();
elm.after( elm.clone(true) );
});
Demo: http://jsfiddle.net/KL7QZ/2/
Passing true in the .clone method also clones events.
I have a table wherein the first column is a checkbox and the second one has a text.
Whenever, the checkbox is checked, I want to know the corresponding value which is in the next cell.
Please tell me how to do.
If I use the getelementsbytagname function, it returns from the start of the document.
This is quite simple to do without jquery. We have a input inside a td so we can go up a level and get the next sibling:
var nextTd = myInput.parentNode.nextSibling;
Because some browser insert empty text nodes between tds we can do the following to make sure we're on the right node:
if (nextTd.tagName != "TD")
nextTd = nextTd.nextSibling;
Also, FWIW, getElementsByTagName can be called from any Node. Thus, if I have a table, I can call
myTable.getElementsByTagName("tr");
To return all rows inside of myTable.
Assuming you're using jQuery (or some other civilized framework), it's pretty easy:
$('table#yourTableId input:checkbox').click(function(ev) {
if (this.checked) {
// not sure what you mean by "want to know" ...
console.log($(this).closest('tr').find('td:nth-child(2)').html());
}
});
You could do it with the jQuery "live" event facility similarly, which'd be cheaper if there are a lot of checkboxes.
The simplest way would be yo use jQuery or a similar library, that implements CSS3 selectors.
$('table input:checked').parent().parent().find('td.nth-child(2)').text():
You could also bind onto the change events of the checkboxes
$('input:checkbox').change = function(){
val = $(this).parent().parent().find('td.nth-child(2)').text():
}