dynamically added form element ids not found - javascript

I have a form in which a user can click a button and add additional fields as needed. Later on, user clicks submit, i do some error checking via ajax. if the additional fields are blank, i want to highlight them in red to let user know its required data.
jquery to add row:
$('#addPerson').click(function(){
var row = "<div id='row_"+rowNum+"'><div class='leftBigRow'><input type='text' class='field' id='addPerson[name][]' name='addPerson[name][]' placeholder='persons name'></div>";
$('.additionalPeople').append(row);
rowNum++;
my ajax call returns a string of field ids that have errors. for example result could be:
//firstname,lastName,zipCode,...etc
so my errorcheck is:
if(result.length > 0)
{
var errors = result.split(",");
for (i=1;i<errors.length;i++)
{
alert(errors[i]);
$('#'+errors[i]).addClass('error');
alert($('#'+errors[i]).val());
}
$("#subForm").attr("disabled", "disabled");
}
the first alert returns what i would expect "addPerson[name][0]";
the second alert returns undefined. telling me it cant find that field....
i have added a fiddle:fiddle
in my fiddle var result is a representation of what i get back from the ajax call. my ultimate goal is to get each field added by pressing yes to turn red if blank....

You don't have an element with id equal to "addPerson[name][0]". When adding new input elements to DOM, you have to include rowNum in their id and name attributes.
Do not include "[" and "]" in name/id attributes. Use:
var row = "<div id='row_"+rowNum+"'><div class='leftBigRow'><input type='text' class='field' id='addPerson_name_"+rowNum+"' name='addPerson_name_"+rowNum+"' placeholder='persons name'></div>";

When you declare your dynamic element's id, you cannot use an array there. You can concatenate it with the rowNum count that you already have.
I have updated your JSFiddle here: http://jsfiddle.net/Myra4/3/
(Observe how I changed the dynamic element's id and your simulated 'result' variable)
I did it in JSFiddle for you so you can immediately verify that it works.

Use .on to bind later created DOM elements.
http://api.jquery.com/on/

Related

JQuery Read or Modify Dynamically Added Text Input

I have a form where the user can dynamically add or remove sets of fields. For each set of fields, when the user enters/changes a value in the upc[] text input I want to make an Ajax query and populate the corresponding desc[] text input. I can capture the change event, but have not been able to read or modify the dynamically create desc[] field:
This snippet does not have the Ajax call as for now I just want to know I can set desc[x].val(). I have tried to associate the dynamic field with a parent element that existed when the DOM was created...but still no luck.
$(document).on('change', '.upcScan', function(){
var upcIdx = $(this).index('.upcScan');
var upcVal = $(this).val();
alert ("The current index is "+upcIdx+" and the value is "+upcVal);
var descName = "desc["+upcIdx+"]";
var descVal = $("#addClient input[name='"+descName+"']").val();
alert("desc field is "+descName+" and value is "+descVal);
});
The code above returns null. If I try to set the val nothing happens.
What am I missing?

The use of JavaScript onchange("<function>(this.id)") on c# CheckBox vs other c# Controls

I have a web document that has its fields populated dynamically from c# (.aspx.cs).
Many of these fields are TextBox or HtmlTextArea elements, but some are Checkbox elements.
For each of these I have the ID attribute populated on creation of the field, as well as using .Attributes.Add("onchange","markChanged(this.id)")
This works great on all the fields except Checkbox. So I created a markCheckChange as I discovered that the Checkbox won't accept style="backgroundColor:red" or .style.backgroundColor = "red" type arguments.
I also added an alert and found that the Checkbox is not actually passing the this.id into the parameter for markCheckChange(param) function.
As a result I am getting errors of the type:
unable to set property of undefined or null reference
Why and what is the difference between these controls, and is there a better way to handle this?
I just reviewed the inspect element again, and discovered that the Checkbox control is creating more than an input field of the type checkbox, it is also wrapping it in a span tag, and the onchange function is being applied to the span tag (which has no id) and not to the input tag that has the checkbox id. Whereas for TextBox and HtmlTextArea the input tag is put directly within the cell/td tag, no some arbitrary span tag.
So now the question becomes how to get the onchange function to apply to the input tag for the checkbox rather than the span tag encapsulating it?
Per request:
function markChange(param) {
if (userStatus == "readonly") {
document.getElementById("PrintRecButton").style.display = "none";
document.getElementById("PrintPDFButton").style.display = "none";
alert("Please login to make changes.\n\nIf you do not have access and need it,\n contact the administrator");
exit();
}
else {
document.getElementById(param).style.backgroundColor = "teal";
saved = false;
var page = document.getElementById("varCurrentPage").value;
markSaveStatus(page, false);
}
}
So far the markCheckChange is about the same, until I get it to pass the id correctly, I won't be able to figure out the right way to highlight the changed checkboxes.
I found an alternative.
As I mentioned in the edit to the question, the inspect element feature revealed that the CheckBox type control was creating a set of nested elements as follows:
<span onchange="markChange(this.id)">
<input type="checkbox" id="<someValue>">
<label for="<someValue>">
</span>
Thus when the onchange event occurred it happened at the span which has no id and thus no id was benig passed for the document.getElementById() to work.
While searching for why I discovered:
From there I found the following for applying labels to the checkboxes:
https://stackoverflow.com/a/28675013/11035837
So instead of using CheckBox I shall use HtmlInputCheckBox. And I have confirmed that this correctly passes the element ID to the JavaScript function.

How to use a variable variable to focus on input

I have a script that looks at a popup modal with a form and should get the first input and focus to that. The forms can change and the input id will always be different.
I am catching the id with var item_id = $('.otf_itm [id]').first().prop('id'); This returns the first. In on case the input has an id of town_name. The problem is that the item does not focus when I use the $('#' + item_id).focus(); How can I get the form item to focus? I have used this method successfully before to get data using .val() and other manipulate parts of the page
// works
$('#town_name').focus();
// doesnt work
$('#' + item_id).focus();
$("#myForm input:first").focus();
Will focus the first input element. Whatever the first input element is.
Remark <select> elements do not fall under this category.

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.

JS and jQuery - loop through textboxes and store value

Here's the function that checks if the form is complete.
So, what I'm trying to do:
If radio is not selected, throw a message.
If radio is "yes", but text is not entered, throw error.
If radio is "no" but text is entered, make the text empty.
If all is good, add stuff into `allResponses
The form was displayed 5 times, and input was as follows:
Yes a1
No
Yes a3
No
Yes
Now, this input should display an error since in 5th case, "yes" is selected but nothing is entered in the textbox.
However, I get this:
http://i.imgur.com/ya2CUp0.png
Also, the text is not being updated as in 1st and 3rd cases.
I don't know a lot about JS, so please provide me with as explained responses as you can.
EDIT: Complete code: http://pastebin.com/scNSNM2H
Thanks
You have this in a loop:
var exaggerationPart = document.getElementById('exaggeration').value
And then you check to make sure it has a value for each item. But you will get the same value each time.
You are creating multiple inputs with the same id, "exaggeration". This is invalid HTML. Id's must be unique. To correct this, you can increment the id the same as you are doing with other elements (such as, input[name='response"+thisJokeIndex+"']).
var exaggerationPart = document.getElementById('exaggeration' + thisJokeIndex).value
tipTD2.append("<input type='text' name='exaggeration' id='exaggeration" + tipIndex + "' size='70'>")
Working demo: jsfiddle.net/svvge/2
Edit: To clear the value of the text box, you must change the value property of the text box element. Right now you are just changing the value of a variable.
var exaggerationInput = document.getElementById('exaggeration' + thisJokeIndex).value;
var exaggerationPart = exaggerationInput.value;
exaggerationInput.value = '';

Categories