text gets scrambled when inserted through .html() jquery method - javascript

In a web page I'm doing there's a table where by clicking on each row you can modify it. This is done by substituting the content of each cell with an input field containing the relative value. In order to let the user cancel the changes made I save the contents of the whole table row before making the substitution, which I then use to compose the new html string to put in the table row (basically, I just put it in a function call which is then called when a button is pressed to revert the changes). if I try to display it through alerts the string looks fine. However, firebug returns an error because apparently the string gets scrambled after I put it in the page by calling .html on the .
What I mean is that instead of being
<tr><td>somedata</td><td><input type=button onclick=fun('oldTrContent')/></td></tr>
it's
<tr><td>somedata</td><td><input type=button oldTrContentNotInOrder') onclick=fun(/></td></tr>
which clearly can't work. I tried putting some alerts in the function in order to see if this behavior was caused by some formatting error, but everything looks fine up to the moment of the call to .html().
The code I used is this:
function mostraModificaCompet(ids, nome){
var id='#'+nome;
var statoPrec=escape($(id).html());
alert(statoPrec);
var d=$(id+" .data").html();
var c=$(id+" .caus span").html();
var de=$(id+" .descr").html();
var pu=$(id+" .prezzou").html();
var q=$(id+" .qta").html();
var pt=$(id+" .prezzot").html();
var iu=$(id+" .ivau").html();
var it=$(id+" .ivat").html();
var t=$(id+" .tot").html();
var r=$(id+" .res").html();
var pr=$(id+" .progr").html();
var str="<td class=data ><input type=text value="+d+" /></td><td class=caus ><select class=selcaus ></select></td><td class=descr ><input type=text value="+de+" />\
</td><td class=prezzou ><input type=text value="+pu+" /></td><td class=qta ><input type=text value="+q+" /></td><td class=prezzot ><input type=text value="+pt+" disabled /></td>\
<td class=ivau ><input type=text value="+iu+" /></td><td class=ivat ><input type=text value="+it+" disabled /></td><td class=tot ><input type=text value="+t+" disabled /></td><td>\
<input type=button value='Conferma' onclick=modificaCompet("+ids+", '"+nome+"') /></td><td><input type=button value=Annulla onclick=ripristinaCompet('"+nome+"', '"+statoPrec+"') /></td>";
alert(str);
$(id).html(str);
}
the variable where I save the old content is statoPrec, which I then use when composing str (it's at the end of the string).
Thanks in advance to anyone who answers.

You're trying to set the value to invalid html, onclick=modificaCompet("+ids+", '"+nome+"') needs some quotes around it so it's onclick=\"onclick=modificaCompet("+ids+", '"+nome+"')\". And any other attributes you failed to quote.

The problem seems to be that when initially going from the values within the td cells, those are accessible via the innerHTML. However, once they turn into inputs, they are the value of the input, not the input's innerHTML. You may have to make two functions where one uses the .html() of the element and the other looks for the .val() of the element.

Related

Understand adding rows on click, confusion with .cloneNode(true);

Consider this http://jsfiddle.net/99CL3/224/, Which adds rows on click
HTML
<br /><br />
<table id="tbl">
<tr>
<td><input type="text" name="links" /></td>
<td><input type="text" name="keywords" /></td>
<td><input type="text" name="violationtype" /></td>
<td><input type="submit" class="button" value="Add another line" onclick="addField(this);" /></td>
</tr>
</table>
JS
function addField(n)
{
var tr = n.parentNode.parentNode.cloneNode(true);
document.getElementById('tbl').appendChild(tr);
}
I'm trying to understand why this code which adds rows on click actually works.
First I realize that it will take what I click (the input), and go two parent nodes above it.
so the first .parentNode points to td, and the next to tr. So basically we are making a table on click with these new properties. Now my question is basically what is the role of .cloneNode(true) here? I have read mozilla documentation, but I can't really understand from their example. Why can't I just append n.parentNode.parentNode right away?
Each element is unique. if you don't clone the element then the element is moved to the target location. So using clone here is necessary for creating another row.
.cloneNode(true) duplicate the selected [tr] tag, if you remove it, your code however works but its behavior is different because the [tr] you selected already belongs to your table.
By the way, you should change name/id of cloned row's input, to make them unique.
p.s: your jsfiddle has only one parentNode, instead of two.

Textbox that is added dynamically to table is behaving like readonly field

I have table with row expand option. On row expand adding one more table row with cell and appending textbox to the same cell using jquery. This is working fine, but textbox that is added dynamically is behaving like readonly field. Please let me know the solution for the same.
<table>
<tr><td> href field here</td><td></td><td></td></tr>
</table>
on click of href field adding row with one cell and textbox in it
<tr><td colspan=3 id="test-cell"></td></tr>
After appending this to table appending textbox to cell with id "test-cell"
$('#test-cell').append('<input type="text" size="10" value="abd" id="test-input" />');
Finally table becomes
<table>
<tr><td> href field here</td><td></td><td></td></tr>
<tr><td colspan=3 id="test-cell"><input type="text" size="10" value="abd" id="test-input" /></td></tr>
</table>
Tested same code in Chrome, FF, IE 11.
Code that I am using for the same (I extracted this code and replaced generic variable with hard code)
var table = $('#C1tbl');
var selectedRow = table.find('tbody>tr.grid-row:eq(2)');
var expandRow = $('<tr class="ag-row-expand"><td colspan="3" id="test-cell"></td></tr>');
expandRow.attr('id', Util.getNextComponentId());
selectedRow.after(expandRow);
var expandCol = expandRow.find('>td');
expandCol.html('<input type="text" size="10" value="abd" id="test-input" />');
After this my web page is not allowing to edit the text.
Probably you can use $('#test-cell').after().html('< input type="text" size="10" id="test-input" />')
This is my mistake only. Table has keydown event to havigate across the rows using navigation keys where function is calling event.preventDefault for all the keys.

Removing duplicates and not valid entries from a select box, but not refreshing the whole box

I'm trying to write a web form, which will have selectable options based on users input from earlier in the form.
Where I'm getting stuck is;
I have a table room types, which is just td tags with input tags (type=text). These are filled in by a user, so I've no idea what they are..
I've got a button to add extra lines to this table (Jquery to add another td tag and input tag)
Users add as many lines as needed
The next part of the form is to fill in Rooms, and select the type for each room. The table layout is the same (except there are two columns, rather than one), and extra lines are added via another button with Jquery.
What I'd like to be able to do, is for new lines added to have two columns in the table. One input text field, and the other a select box with options taken from the table above.
I've managed to get this working to a point. But as users may go back to edit options from the original (room types) table, I need the select boxes to adjust their values based on what the original table currently says.
I can get this working by emptying and re-populating my select boxes everytime one of the input fields accessed (using OnBlur, which is probably not the most effective way to do this), but since it removes entries from the bxes, and then re-populates, any of the select boxes that have been populated already get reset. I only want invalid options (i.e. values that do not exist in the original table) to be reset.
I've been looking/playing at this for a long time now, but my programming abilities are only what I've taught from here and google, whilst messing around on a few very small things before...
My HTML code as it stands (well, part of my code, I've removed all the irrelevant code to keep it simple) is here:
<div id="rm_types_info">
<table id="room_types_table">
<tr>
<td><input type="text" class="room_types" onblur="edit_rooms_select();" /></td>
</tr>
</table>
<button type="button" onclick="rmtypes('room_types_table');">Add Another Room Type</button>
</div>
<div id="rooms_info">
<table id="rooms_table">
<tr>
<th>Room Number</th>
<th>Room Type</th>
</tr>
<tr>
<td><input type="text" /></td>
<td>
<select class="room_type_select">
<option value="Please Choose">Please Choose</option>
</select>
</td>
</tr>
</table>
<button type="button" onclick="rooms('rooms_table');">Add Another Room</button>
</div>
and my JQuery is;
<script>
var userscounter=2
var rmtypescounter=1
var roomscounter=2
function users(ID){
document.getElementById(ID).insertRow(userscounter).innerHTML = '<td><input type="text" /></td><td><input type="text" /></td>';
userscounter++;
};
function rmtypes(ID){
document.getElementById(ID).insertRow(rmtypescounter).innerHTML = '<td><input type="text" class="room_types" onblur="edit_rooms_select();" /></td>';
rmtypescounter++;
}
function rooms(ID){
document.getElementById(ID).insertRow(roomscounter).innerHTML = '<td><input type="text" /></td><select class="room_type_select"><option value="Please Choose">Please Choose</option></select></td>';
roomscounter++;
};
function edit_rooms_select(){
var roomtypelist = $('.room_type_select');
roomtypelist.empty()
$('#room_types_table tr td input').each(function(){
var text = $(this).val();
roomtypelist.append('<option value='+text+'>'+text+'</option>');
});
}
</script>
I've removed the Jquery that was removing the duplicates, since it was definately not working how it needs to...
I'm aware that I may be going about this completely the wrong way, and if using td tags or inputs etc is completely wrong, I'm happy to change the whole form it necessary.
I'm sure this isn't the most effective way to do what I need, but this is how I managed to get it to work...
My HTML...
<div id="rm_types_info">
<table id="room_types_table">
<tr>
<td><input type="text" name="2" class="room_types" onblur="edit_rooms_select();" /></td>
</tr>
</table>
<button type="button" onclick="rmtypes('room_types_table');">Add Another Room Type</button>
</div>
<div id="rooms_info">
<table id="rooms_table">
<tr>
<th>Room Number</th>
<th>Room Type</th>
</tr>
<tr>
<td><input type="text" /></td>
<td>
<select class="room_type_select" id="room_type_select1" >
<option value="1">Please Choose</option>
</select>
</td>
</tr>
</table>
<button type="button" onclick="rooms('rooms_table');edit_rooms_select();">Add Another Room</button>
</div>
And the JQuery scripts relevant. In particular, it was the final function "edit_rooms_select()", and specifically the "Add new options to each select" that I was struggling with.
<script>
var rmtypescount=3;
var room_type_select_count=2;
function rmtypes(){
$('#room_types_table tr:last').after('<tr><td><input type="text" name='+rmtypescount+' class="room_types" onblur="edit_rooms_select();" /></td></tr>');
rmtypescount++;
};
function rooms(){
$('#rooms_table tr:last').after('<tr><td><input type="text" /></td><td><select id="room_type_select'+room_type_select_count+'" class="room_type_select"><option value="1">Please Choose</option></select></td></tr>');
room_type_select_count++
};
function edit_rooms_select(){
$('#room_types_table tr td input').each(function(){
var name = $(this).attr('name');
var value = $(this).val();
//Add New Options to each select
$('#rooms_table select').each(function(){
var last = $(this).children('option:last').val();
if (name > last) {
$(this).append('<option value="'+name+'">'+value+'</option>');
};
});
//Change any room types that have been edited
$('.room_type_select option').each(function(){
var match = $(this).val();
if(name == match){
$(this).text(value)
};
});
//Remove Blank Entries
if(value == ''){
$('.room_type_select option[value='+name+']').remove();
};
});
};
</script>
I think that the edit_rooms_select function is much more expensive than it needs to be. For what I require, this isn't going to be a problem, but I would be very interested to see how other people suggest the lists are edited, following my requirements..
- All user inputs from the room_types_table must be options in the select boxes in the rooms_table
- Any input changed in the room_types_table must have its relevant option in the select boxes changed to match
- Any input that is left blank (or later deleted) from the room_types_table must be removed from the select boxes
- Any select box that has a selection which is then removed from the room_types_table must be reset back to its original "Please Choose" option.
If anyone can suggest better ways to do this, or can tidy my code in any way, I'd like to see the code, and also have it explained, as I'm very inexperienced with Javascript/Jquery.

Copy HTML into textarea on submit

I have a form with multiple blocks of inputs with default values assigned by PHP, and I would like to pass the HTML markup of one of the blocks into a PHP script. Here is a modified snippet of my form to exemplify the markup:
<form action="/page/do_work/job_number" id="work_form">
<textarea style="display: none;" name="markup" id="markup"></textarea>
<div id="block_1">
<table>
<tr>
<td><input type="text" value="123" /></td>
<td><input type="text" value="123" /></td>
</tr>
</table>
</div>
<div id="block_2">
<table>
<tr>
<td><input type="text" value="abc" /></td>
<td><input type="text" value="abc" /></td>
</tr>
</table>
</div>
</form>
I am listening for the submission of the form with some jQuery, so that I can copy the HTML of the table into the textarea.:
$('#work_form').submit(function(){
// Snatch the markup
var markup = $('#block_1', '#work_form').html();
// Place it into the textarea
$('#markup', '#work_form').html( markup );
// Move on
return true;
});
The Problem is that the modified values are not being copied into the textarea. For instance, if I were to change the values from "abc" to "xyz" the markup that is passed to the textarea still says "abc". Any help would be greatly appreciated.
Edit: Using .html() or .val() both add the markup in to the textarea, but I would like to know why the changes in value of the inputs are not reflected in the markup that is inserted into the textarea. Upon further inspection, changing the value of the input fields and then inspectigating them in Firebug shows the default value is retained. Do I need to update the DOM in some way?
Edit 2: The markup variable is being set, but the changes I make to the input fields are not reflected in the markup inserted into the textarea.
Try,
$('#markup', '#work_form').val( markup );
Also throw in a console.log(markup) to make sure the markup variable is getting set right.
Well for text area you need to change its 'value' not its 'innerhtml' and thats what .html does.
$('#markup').val(markup)
Try this.
Changes to input fields do not change the DOM, which is what I was supposed to do. To change the DOM, I edited the .submit() function to look like this:
$('#work_form').submit(function(){
// Update the DOM
var block_1 = $('#block_1', '#work_form');
block_1.find('input').each(function(i,e){
el = $(e);
el.attr('value', el.val());
});
// Snatch the markup
var markup = block_1.html();
// Place it into the textarea
$('#markup', '#work_form').html( markup );
// Move on
return true;
});
Thanks #PherricOxide for pointing me to this question:
reading innerHTML of HTML form with VALUE attribute (& its value) of INPUT tags

How to Remove dynamic Parent <tr> via OnClick of child <input>

I'm adding the <tr> via a Javascript var:
var txtBox = "<tr id='dynTR'><td><input type='text' class='textBoxes' /></td><td><input type='text' class='textBoxes' value='0' /></td><td><input type='button' value='-' /></td></tr>";
With my function being:
function AddTR(table) {
$(table).append(txtBox);
}
My table structure (along with the button for the function) in the HTML being:
<table id="tblTest" class="testTable">
<thead>
<tr>
<td>Product</td>
<td>Quantity</td>
<td>Remove TR</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<br />
<input type="Button" id="btnTest" value="Add Table Row" onclick="AddTR($('#tblTest'))" />
So how do I go about using the .remove() function in jQuery to get rid of the parent tag without accidentally removing all <tr id='dynTR'> tags?
Considering this one is the remove button:
<input type='button' value='-' />
The following will do:
$('#tblTest input[type="button"]').click(function () {
$(this).closest('tr').remove();
});
I'd suggest you use jQuery event handlers instead of using inline onclick and friends. $(this) is the jQuery object of the button that was clicked, .closest() will look in the parents of the button and find the first tr, then remove it.
jsFiddle by #ShadowWizard
The best way would be to change the HTML for your remove button:
<input type='button' value='-' class='removeButton' />
so you can target your remove button like this:
$('#tblTest .removeButton').click(...
This is better because with the previous example, every possible input type="button" in the table would get the event, even though we just need it on these special ones (not a problem if there are no other buttons in the table).
bazmegakapa answer should do the trick. Also you should really avoid using inline Javascript, it's generally bad practise. Instead do:
$('#btnTest').click(function() { AddTR($('#tblTest')); });
Also to keep up with the convention of jQuery using the correct scope of the element object, you could do:
$('#btnTest').click(function() { AddTR.call($('#tblTest')[0]); });
Then in your AddTR function you can simply reference the element table as this
function AddTR() {
$(this).append(txtBox);
}
It keeps things predictable and follows the same convention.
Hang on a minute....
In theory although the AddTR() function is adding a table row, it's a bit misleading because all it's doing is just appending an element to that context. What you really want to do is just what the function says; add a table row! instead your doing
var txtBox = "<tr id='dynTR'><td><input type='text' class='textBoxes' /></td><td><input type='text' class='textBoxes' value='0' /></td><td><input type='button' value='-' /></td></tr>";
Which is rather ugly and will cause some changes if you change your table row structures. Instead, use .clone to help you:
function AddTR() {
$(this).append($('tr:last').clone());
}
See fiddle: http://jsfiddle.net/garreh/6NUK3/1/

Categories