On Jsfiddle: http://jsfiddle.net/jhzux/
I've wasted a lot of time in this simple script.. What I want to do is to enable to clone forms in jQuery and then make them work correctly.
In first place when I run this code on JsFiddle it does not work but in my browser it does.. strange... -.-
Secondly $(this).next(".persianaops").slideToggle(300);
part does not even work, nothing happens only the .persianaver part appears
When the persianaver part appers the radio button not always works, in the first cell it works ok but later in the other clones the radio is behaving like every radio button belongs to the same group so it only can be aplied two times: in the first part and than in one of the clones.. (I hope you can see this in Js fiddle because my expnatation is kinda confusing..)
So is there any better method to clone a table with JQ with working radio buttons and fix the .persianaops part?
HTML:
<ul id="listing" style="list-style:none;">
<li>
<table class="pedido">
<tr>
<td><select name="product[]">
<option value="0">
Perfil:
</option>
<option value=
"68mm 5 Cámaras AD rendszer egyenes szárny, ütköző tömítéssel">
68mm 5 Cámaras 7001AD, con dos juntas
</option>
<option value=
"68mm 7 K AD rendszer íves szárny, ütköző tömítéssel">
68mm 7 Cámaras 7001AD con dos juntas
</option>
<option value=
"80 mm 6 K Tok + 7 K íves szárny AD rendszer, ütköző tömítéssel">
80 mm Marco 6 Cámaras + Hoja de 7 Cámaras 7001AD con
dos juntas
</option>
<option value=
"68mm 7 K MD rendszer ütköző és középtömítéses, íves szárny">
68mm 7 Cámaras 7001MD con tres juntas
</option>
<option value=
"80 mm 8 K MD rendszer ütköző és középtömítéses, íves szárny">
80 mm 8 Cámaras 7001MD con tres juntas
</option>
</select></td>
</tr>
<tr>
<td><input class="comment" name="h[]" value="Horizontal"> x
<input class="comment" name="v[]" value="Vertical"> uds:
<input name="uds[]" style="width:60px;"></td>
</tr>
<tr>
<td>
<select>
<option>
Color
</option>
</select> Persiana <input class="persiana" name=
"persiana[]" type="checkbox">
<div class="persianaver" style=
"float:right; display:none">
Con motor<input name="f[]" type="radio" value=
"auto"> Manual<input name="f[]" type="radio" value=
"manual">
</div>
</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td style="width:435px;">
<div class="persianaops" style=
"float:right; display:none">
IMPORTANTE: En caso de haber seleccionado la opción
persiana usted tiene que especificar el tamaño de
la tapa del cajón (Lugar donde se sitúa la caja de
persiana) Puede especificarlo en el campo
comentario <a href="images/demo.jpg" id="pregunta"
name="pregunta"><img alt="pregunta" height="15"
src="images/ask.jpg" width="15"></a>
</div>
</td>
</tr>
<tr>
<td>
<textarea class="comment" cols="59" name="comment[]" rows=
"5">Comentario</textarea></td>
</tr>
</table>
</li>
</ul><button id="clonar" name="colnar">Cloneme</button><br>
<br>
<h3>Datos personales:</h3><br>
<table>
<tr>
<td>Nombre y apellido:</td>
<td><input name="name" type="text"></td>
</tr>
<tr>
<td>Email:</td>
<td><input name="mail" type="text"></td>
</tr>
<tr>
<td>Teléfono:</td>
<td><input name="telefono" type="text"></td>
</tr>
</table>
JQ
$(document).ready(function() {
var $orig = $(".pedido").clone();
$("#clonar").live('click', function(e) {
e.preventDefault();
$("#listing").append($orig.clone());
$(".persiana").click(function() {
$(this).next(".persianaver").slideToggle(300);
$(this).next(".persianaops").slideToggle(300);
});
$(".comment").focus(function() {
if (this.value === this.defaultValue) {
this.value = '';
}
}).blur(function() {
if (this.value === '') {
this.value = this.defaultValue;
}
});
});
});
As for it not working on JsFiddle; it's probably not working because you have it set to use MooTools and not jQuery.
As for the cloning logic; it appears it should work; although I find it strange that you're "cloning" the variable, after the "#clonar" click event, as opposed to using the variable to execute the clone event and retrieve the content fresh.
I would change it to this:
$(document).ready(function()
{
var $orig = $(".pedido").clone();
$("#clonar").live('click' , function(e){
e.preventDefault();
$("#listing").append($orig);
// or the non variable instance:
// $("#listing").append( $("#pedido").clone(); )
});
});
I fixed your Fiddle for you: http://jsfiddle.net/8v6CP/1/.
You were missing some ending })
and your HTML was missing a </tr>
. I suggest you indent your code well to avoid this kind of problem.
Regarding the ".persiana"
checkbox, you where attaching the click
event inside the "#clonar"
event handler. You should have attached it outside using live
:
$(document).ready(function(){
var $orig = $(".pedido").clone();
$(".persiana").live("click", function () {
$(this).next(".persianaver").slideToggle(300);
$(this).next(".persianaops").slideToggle(300);
});
$("#clonar").live('click', function (e) {
e.preventDefault();
$("#listing").append($orig.clone());
$(".comment")
.focus(function() {
if (this.value === this.defaultValue) {
this.value = '';
}
})
.blur(function() {
if (this.value === '') {
this.value = this.defaultValue;
}
});
});
});
I would restructure this completely. See example. You are double binding events by adding click
events inside the live
statement.
Here I use on
instead. I monitor the body level, but you should tighten it down to the form container or form to boost performance. Just declare your event handlers once using on
.
Then clone the clone is only one line. You don't have to prevent default on buttons because the default doesn't do anything anyways.
The radio buttons are cloned, and so they share the same name. This means only one of the radio buttons can be active at a time. I added some code to rename them.
$(document).ready(function() {
var $orig = $(".pedido").clone();
var counter = 0;
$("body").on('click', '.persiana', function() {
$(this).next(".persianaver").slideToggle(300);
$(this).next(".persianaops").slideToggle(300);
});
$("body").on('focus', '.comment', function() {
if (this.value === this.defaultValue) {
this.value = '';
}
}).on('blur', '.comment', function() {
if (this.value === '') {
this.value = this.defaultValue;
}
});
$("#clonar").click(function(e) {
//have to change radio button names to be unique
counter++;
$orig.find(':radio').each( function() {
$(this).prop('name', $(this).prop('name') + counter);
});
//append clone
$("#listing").append($orig.clone());
});
});
live
which has been deprecated. You should be usingon
ordelegate
as of jQuery 1.7 - mrtsherman 2012-04-04 17:28