jQuery clone() leaves user data in input field - javascript

See jsfiddle: http://jsfiddle.net/bjCz3/
html
<table>
<tr class="copyMe">
<td><input type="text" name="test" /></td>
</tr>
</table> <a id="clickMe" href="#">Click Me</a>
jquery
$('#clickMe').click(function(event){
event.preventDefault();
var tr = $('.copyMe:last');
var newTr = tr.clone();
newTr.appendTo(tr.parent());
});
If you type text in the input, and click the click me, the row (including the input) is cloned and inserted - and has the data you entered.
The API for clone() says:
The .clone() method performs a deep copy of the set of matched
elements, meaning that it copies the matched elements as well as all
of their descendant elements and text nodes. For performance reasons,
the dynamic state of form elements (e.g., user data typed into input, and textarea or user selections made to a select) is not copied
to the cloned elements. The clone operation sets these fields to
their default values as specified in the HTML.
http://api.jquery.com/clone/
So why does my input have the value filled in, and more important, how can I prevent it? I want them to be empty/default like the documentation implies. I tried specifying both arguments as false even though they default to that, and it still copies it.

If you are working with inputs that aren't checked or have values set on page load. ( or you want defaults that are set)...cache a row before user touches one . Then clone that stored row to append when needed
/* store row on page load*/
var tr = $('.copyMe:last').clone();
$('#clickMe').click(function(event){
event.preventDefault();
var newTr = tr.clone();....
})

As far as a way to clear it yourself.
$('#clickMe').click(function(event){
event.preventDefault();
var tr = $('.copyMe:last');
var newTr = tr.clone();
newTr.find('input').val('');
newTr.appendTo(tr.parent());
});
Update
newTr.find("input[type=text], textarea").val("");
newTr.find('input:checkbox').removeAttr('checked');
http://jsfiddle.net/bjCz3/3/

Do it yourself after filling a bug report at jquery:
$('#clickMe').click(function(event){
event.preventDefault();
var tr = $('.copyMe:last');
var newTr = tr.clone();
newTr.find(":input").val(''); //find all input types (input, textarea), empty it.
newTr.appendTo(tr.parent());
});
Updated working fiddle: http://jsfiddle.net/bjCz3/2/

Related

Use JQuery to multiply values from dynamically created input fields

I'm using JQuery to dynamically create table rows. Each row contains 3 text fields. As users type into a text field, the table row is cloned and multiple rows are added as required. All that works fine.
Numerical values are entered into the first 2 fields, which are multiplied. The output automatically appears in the 3rd text box. As the input fields are clones, I can't use getElementById to run the function & multiply the values.
I was told to use onchange using parent siblings, but I don't know how to do that. Can someone give me an example?
Here is a sample of my code in JS Fiddle: https://jsfiddle.net/mzctb778/
Since you are adding things dynamically you should use event delegation to listen for change events. Do this by attaching it to the table. So listen for a change on an input. Once you detect the change, get the row by looking up the DOM and select the inputs you need to multiply. Since you can not use ids since they need to be unique, use classes to reference the elements.
$("table").on("change", "input", function () { //use event delegation
var tableRow = $(this).closest("tr"); //from input find row
var one = Number(tableRow.find(".one").val()); //get first textbox
var two = Number(tableRow.find(".two").val()); //get second textbox
var total = one * two; //calculate total
tableRow.find(".three").val(total); //set value
});
$("button.add").on("click", function() {
var tbody = $("table tbody");
tbody.find("tr:eq(0)").clone().appendTo(tbody).find("input").val("");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><input class="one" /></td>
<td><input class="two" /></td>
<td><input class="three" readonly="readonly"/></td>
</tr>
</tbody>
</table>
<button class="add">Add</button>
Add this to your script and it will do the calculations you want:
$("table select").on("change", function(){
var x=$(this).find(":selected").val();
var y=$(this).closest("td").siblings().find(":selected").val();
$(this).closest("td").siblings().find("input").val(x*y);
});
New JS Fiddle

Appending/Replicating HTML from DOM in current state to a div

I have a form on a page. The form contains text inputs, checkboxes, selects (interactive elements). I want the user to be able to click a button, and reproduce a portion of the form elsewhere on the page, in the current state, preserving the text entered, the checkboxes checked, and the selects selected.
Currently I have this, which appends the HTML, however it grabs the HTML in the state it was when the page was loaded.
$('#create_unique_field').click( function() {
$('#unique_field_cnt').append($('#template_cnt').html());
});
I have tried using delegation using on(), like so, with the same results.
$( 'body' ).on( 'click', '#create_unique_field', function() {
$('#unique_field_cnt').append($('#template_cnt').html());
});
What I want is the current state of the HTML, not the HTML at the point when the page was loaded. How can I accomplish this?
It doesn't work that way, you need to bind values of form elements and create new form elements with that data. More or less it falls on var inputText = $('#someInputEl').val(); and then applying that values on new form elements and THEN inserting it.
Try this:
<input type="text" id='one'>
<button>submit</button>
<div id="target"></div>
$(function(){
$('button').click(function(){
var inputVal = $('#one').val();
var newInputEl = $("<input type='text' id='two'>");
newInputEl.val(inputVal);
$('#target').html( newInputEl );
});
});
This is rough sketch but you should make it work this way, here is fiddle.

Insert value in input box by clicking a hyperlink

A table column displays student id numbers as follows:- (PHP code)
echo "<td><b><a href = '#'><h1>".$res['studid']."</h1></a></b></td>";
Below the table there is an input box to enter student id
I want to add the value of $res variable into the input box when the user clicks the above link.
That value will be later used to search the result of that particular student
How to achieve this with Javascript?
var studentLinks=document.querySelectorAll('td>b>a>h1');
for(var i=0;i<studentLinks.length;i++){
studentLinks[i].parentNode.addEventListener('click',function(){
document.getElementById('yourInputField').value=this.children[0].innerHTML;
});
}
Non-jQuery way of applying this functionality to all elements.
By the way, the a element is then non-essential, so it could as well be removed and td>b>h1 be written as the selector instead.
Anyways, the above JavaScript is applied to all links. You can also put an e inside the brackets after function and at the top of the function block add e.preventDefault(); to make absolutely sure that the page doesn’t redirect anywhere.
var link = document.getElementById('studentId');
var input = document.getElementById('search');
link.addEventListener('click', function() {
input.value = this.innerText;
});
<td><b><h1>Some text</h1></b>
</td>
<input type="text" id="search">
Well a Jquery way...
$("#table a").click(function(){
$("#input").val($(this).find('h1').text());
});

HTML: Get value from input with no ID

Been looking around and I cant seem to find an answer to this so maybe im wording it wrong but here it goes.
So I have a table displaying data from a database. In jQuery I have made it so a row can be added with empty inputs and then submitted to the database, this works fine.
I am now attempting to be able to edit it. So each row will have a button to edit that row, the button will put the row values into inputs so you can change the value and update the database. How can I do this? I was looking into using this here but Im not sure how I can get the value of the input boxes without them having some sort of ID.
jQuery I was trying to use:
$('#tbl').on('click','.xx',function() {
$(this).siblings().each(
function(){
if ($(this).find('input').length){
$(this).text($(this).find('input').val());
}
else {
var t = $(this).text();
$(this).text('').append($('<input />',{'value' : t}).val(t));
}
});
});
Am I over thinking this? Should I just be grabbing the values and then putting them in pre-made input boxes?
Update:
HTML:
sb.AppendLine("<table style='width: 80%;'>")
sb.AppendLine("<tr class='inputRowbelow'>")
sb.AppendLine("<td style='width: 20%;' class='ui-widget-header ui-corner-all'>Area</td>")
sb.AppendLine("<td class='ui-widget-header ui-corner-all'>Details</td>")
sb.AppendLine("<td class='ui-widget-header ui-corner-all'>Options</td>")
sb.AppendLine("</tr>")
For Each w In workItems
sb.AppendLine("<tr>")
sb.AppendLine("<td>" & w.area & "</td>")
sb.AppendLine("<td>" & w.details & "</td>")
sb.AppendLine("<td><a href='#' class='fg-button ui-state-default ui-corner-all edit'><img src='/images/spacer.gif' class='ui-icon ui-icon-pencil' /></a></td>")
sb.AppendLine("</tr>")
Next
sb.AppendLine("</table>")
There are a couple of ways to do this, including changing your VB code to add extra data to the html, but I will answer this from a pure javascript/JQuery solution.
First of all you need to handle the click event for each edit button, after that you find the matching row, and then you can get the first to td elements of that row...
$(".edit").click(function(e){
e.preventDefault();//prevent the link from navigating the page
var button = $(this);//get the button element
var row = button.closest("tr");//get the row that the button belongs to
var cellArea = row.find("td:eq(0)");//get the first cell (area)
var cellDetails = row.find("td:eq(1)");//get the second cell (details)
//now you can change these to your inputs and process who you want
//something like this...
ConvertToInput(cellArea, "area");
ConvertToInput(cellDetails, "details");
});
function ConvertToInput(element, newId){
var input = $("<input/>");//create a new input element
input.attr("id", newId);//set an id so we can find it
var val = element.html();//get the current value of the cell
input.val(val);//set the input value to match the existing cell
element.html(input);//change the cell content to the new input element
}
Here is a working example
From that you can then do the saving that you say you have already implemented, using the ID values of each field to get the values to save.
Instead of using a For Each ... in ... Next loop, use a a For loop with a counter. give each button and each row an ID with the current counter value at the end. You can then use Jquery to make each row editable separately, because each row has a row number now.

Adding new row on a table tbody by cloning the last row with events attached

I'm trying to clone the last row of a table with input fields that might have events attached, (in this case it's the keyup event). I also change the id's of the input fields to reflect the row where they are, something like:
table[0].field1,table[0].field2...table[1].field1...etc.
The problem is that I can add a row and it gets the events too, and when i write on the new cloned inputs they do start the events. But only on the first row created. If i create a new one, it will render the row with the inputs correctly but not the events. Here's the method:
addRow= function(tableid){
//jquery selector get table tbody with id
var table=jQuery('table[id="'+tableid+'"] >tbody');
//get last row containing input fields with tr class hoverTransparente
var lastRow=jQuery('table[id="'+tableid+'"] > tbody > tr:last');
//make a clone of the row
var clones = lastRow.clone(true); // copy events/children too
//get the input fields from the cloned row
var clonedInPuts=clones.find('input');
//for each input
jQuery(clonedInPuts).each(function (){
//set new input val to empty
jQuery(this).val("");
var inputId=jQuery(this).attr('id');
//table id
var table=inputId.split("[")[0];
//column id
var tableField=inputId.split(".")[1];
var idnumber=inputId.indexOf("[")+1;
//convert to number to make addition for new id index
var number = Number(inputId.charAt(idnumber))+1;
//replace id index with incrementaed value
var newId=inputId.replace(inputId.charAt(idnumber),number);
//change id for new one
jQuery(this).attr('id',newId);
//check if this variable exists/is not undefined
if(window["elements_"+table+"_"+tableField]){
window["elements_"+table+"_"+tableField].push(jQuery(this).get(0));
}
});
clones.appendTo(table);
}
Any ideas? when i try to debug in chrome the event onkeyup from the domtree of the input element is null but if i select using jquery directly and get the .data('events') method it does return an array with the events attached to the input field. Shouldn't the onkeyup return something different from null?
Ok, so the problem is not on this side but on the original method that creates the events in the original inputs of the existing rows. You need to do this:
var selectorStr='input[id^='+table+']&[id$='+tableField+']';
jQuery(document).on('keyup',selectorStr,function(event) {...})
instead of:
var elements=jQuery('input[id^='+table+']&[id$='+tableField+']');
elements.each(function() {
jQuery(this).keyup(function(){...})
});
This will solve the problem of adding new rows to the tablet and the input events actually search for newly added inputs.

Categories