Get Array of Input fields values and append itinto the associated textarea - javascript

I have some input field dynamically generated inside form. I am trying to read the value of hidden input and append to to the end of text area
.<input type="hidden" id="formtype_loans_0_comment" name="formtype[loans][0][comment]" disabled="disabled" value="VAlue 1 value 123" />
<textarea id="formtype_loans_0_description" name="formtype[loans][0][description]">Text Area 1 or 1 </textarea>
<input type="hidden" id="formtype_loans_1_comment" name="formtype[loans][1][comment]" disabled="disabled" value="VAlue value 123" />
<textarea id="formtype_loans_1_description" name="formtype[loans][1][description]">test desc</textarea>
and Here is the js code, but it's not working,
var values = [];
$("input[name='formtype[loans][][description]']").each(function() {
values.push($(this).val());
});
alert(values);

Your selector "input[name='formtype[loans][][description]']" won't match any elements, because the [] in the middle will not match to the [0] or [1] (etc.) in the middle of the actual element name attributes.
For the HTML shown you could use the attribute starts with selector [name^=value]:
$('input[name^="formtype[loans]"]').each(function() {
If each textarea will always immediately follow its associated hidden input then within the .each() loop that iterates over the inputs you can say $(this).next() to get the textarea.
If the textareas might be elsewhere in the DOM then you could find them by selecting by the name attribute based on the name of the current input:
$('textarea[name="' + this.name.replace("comment", "description") + '"')
Demonstrated in context:
$('input[name^="formtype[loans]"]').each(function() {
var val = this.value
// add input's value to end of associated textarea's existing value:
$('textarea[name="' + this.name.replace("comment", "description") + '"')
.val(function(i, v) { return v + ' ' + val })
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="hidden" id="formtype_loans_0_comment" name="formtype[loans][0][comment]" disabled="disabled" value="Hidden value 0" />
<textarea id="formtype_loans_0_description" name="formtype[loans][0][description]">Text Area A</textarea>
<input type="hidden" id="formtype_loans_1_comment" name="formtype[loans][1][comment]" disabled="disabled" value="Hidden value 1" />
<textarea id="formtype_loans_1_description" name="formtype[loans][1][description]">Text Area B</textarea>
If you want to simply replace the textarea's current value rather than adding to the end of it then you can simplify the above to:
$('input[name^="formtype[loans]"]').each(function() {
$('textarea[name="' + this.name.replace("comment", "description") + '"')
.val(this.value)
})

var values = [],
inputs = $('input[type="hidden"]'),
textareas = $('textarea');
if (inputs.length === textareas.length) {
$.each(inputs, function(i, input) {
var val = ($(input).val()) ? $(input).val(): undefined;
if (val) {
$(textareas).eq(i).empty().val(val);
}
});
}
alert(values);
The working code above assumes a couple of things:
There will always be one textarea per hidden input.
The associated textarea will always be the next sibling after the hidden input.
Even if that is not the case, there are still various ways to resolve this challenge. But I'll break down the different parts of the code:
First, instantiate your variables. Most importantly, cache your selected HTML elements into vars: touching the DOM is expensive and negatively impacts performance (e.g. querying the DOM each time in a loop).
Next, we put a conditional test to ensure there is one textarea for each input. No need to waste time iterating through a loop looking for elements that aren't there.
Finally, iterate through each of the selected inputs confirming each of them have a value. Again, no need manipulating textarea if there is no value to insert. If there is a value in the input, insert it into the textarea that occupies the same position as the input in each of your arrays of elements.

Related

Getting value of multiple text inputs by class name and only returning value from the one that has value

I have multiple text inputs that all share the same class name.
Assuming the code has been written so that only one of those text inputs can have value at any one time, is it possible to search for the value of those text inputs by class name and only return the value of the one that has data written in it by the user?
For the purpose of this question, how would I get that value to be returned in the alert box in the code below?
var input = document.getElementsByClassName("input").value;
alert("input");
If it isn't possible using class names, is there an alternative solution that would achieve the same effect?
I would rather avoid having to give each text input an id and write code for each one, hence wanting to use class names.
//find all the elements, filter out the ones without a value, get the value
$('.theClass').filter(function(){ return this.value.trim(); }).val()
var $inputs = $('.aClass');
$inputs.on('input', function(){
$inputs.not(this).prop('disabled', this.value.trim());
});
$('button').on('click', function(){
console.log(
$inputs.filter(function(){ return this.value.trim(); }).val()
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><input type="text" class="aClass"></div>
<div><input type="text" class="aClass"></div>
<div><input type="text" class="aClass"></div>
<div><input type="text" class="aClass"></div>
<div><button>Get Value</button></div>
Please try this below code,
var matches = document.getElementsByClassName('input');
for (var i=0; i<matches.length; i++) {
//do action
console.log(matches[i].value)
}

Manipulating textarea value for in memory jQuery object

Given an array of strings where each string is the html for a form element that has a value assigned, I'd like to loop over the array and remove the values for each element.
I need to end up with the same array of strings but where:
input and textarea element values are all set to ''
select element options are all deselected
checkbox elements are all unchecked
I set the element backgrounds to yellow just to show the text areas are being selected
To do this, I figured I'd wrap the elements in a div, set all the element attributes, then get the div's html.
This works for all the elements except textareas
I've tried
.val('')
.attr('value', '')
.prop('value', '')
None worked to remove the value of a textarea in memory.
var elements = [
'<input type="checkbox" checked>',
'<input type="text" value="1041">',
'<input type="text" value="activities">',
'<textarea>some text</textarea>',
'<select><option value=""></option><option value="1" selected>1</option></select>',
'<select><option value=""></option><option value="1" selected>1</option></select>',
'<textarea>some text</textarea>'
];
var newElements = [];
$.each(elements, function(i, item) {
var $temp = $('<div>').html(item);
var $tempElements = $temp.find('input:not(.row-select), textarea, select').addClass('test');
//$tempElements.val(''); // doesnt work at all
$tempElements.attr('value',''); // works for text inputs but not textarea
$tempElements.attr('checked', false);
$tempElements.find('option').attr('selected', false);
newElements.push($temp.html());
});
$('#result').html(newElements.join(''));
.test{
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
Expected result:
var elements = [
'<input type="checkbox">',
'<input type="text" value="1041">',
'<input type="text" value="activities">',
'<textarea>some text</textarea>',
'<select><option value=""></option><option value="1" selected>1</option></select>',
'<select><option value="" selected></option><option value="1">1</option></select>',
'<textarea></textarea>'
];
Here is a jsFiddle
I do understand that I could just append the html to a div in the dom and do what I need there, but Im curious if there isn't a way to do this in memory.
Just use .text('') to remove the content of textarea.
$tempElements.text('');
And you don't need prop when using attr before.
// change
$tempElements.attr('value', '').prop('value', '');
// to
$tempElements.attr('value', '');
Wokring example.
.attr('value', '') and .val('') don't work because you're pushing the element's html and appending that, rather than the actual dom element/jquery object.

Grab the value of latest textbox on a particular variable having multiple textbox with same ID

I want the value of last textbox to be grabbed by the varialble on multiple textbox with same ID.
HTML
<input type="text" id="get"><br>
<input type="text" id="get"><br>
<button id="grab">Click</button><br>
SCRIPT
$("#grab").click(function(){
var value = $("#get").val();
});
Or, a way to delete the first textbox might also work. Working Example
Your HTML is invalid: HTML elements can't have the same id attribute.
Use the class attribute, instead.
You can then use .last() to get the last element that matches the .get selector:
$("#grab").click(function(){
var value = $(".get").last().val();
alert(value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="get" value="foo"><br>
<input type="text" class="get" value="bar"><br>
<button id="grab">Click</button><br>
(I added the value attributes for demonstrative purposes. Obviously, they can be removed.)
If you want to get the first element's value if the second one is empty, you could do this:
$("#grab").click(function(){
var firstValue = $(".get").val(); // `.val()` gets the first element's value by default
var secondValue = $(".get").last().val();
var result = secondValue || firstValue;
alert(result);
});
If you don't have any control on ids you should use following solution. If you can change the ids you should change them.
You approach will not work because the id is not unique. It will always get the first input.
$("#grab").click(function() {
// var value = $(this).prev("input").val(); // Will work when there is no `<br>`
alert($('input[id="get"]').last().val());
});
Here $('input[id="get"]') will get all the elements having id get and last() will get the last element from it.
Demo: https://jsfiddle.net/orghoLzg/1/

Persisting textbox value using jQuery

I'd like to save the newly entered values, so I could reuse them. However, when I try to do the following, it does not work:
// el is a textbox on which .change() was triggered
$(el).attr("value", $(el).val());
When the line executes, no errors are generated, yet Firebug doesn't show that the value attribute of el has changed. I tried the following as well, but no luck:
$(el).val($(el).val());
The reason I'm trying to do this is to preserve the values in the text boxes when I append new content to a container using jTemplates. The old content is saved in a variable and then prepended to the container. However, all the values that were entered into the text boxes get lost
var des_cntr = $("#pnlDesignations");
old = des_cntr.html();
des_cntr.setTemplate( $("#tplDesignations").html() );
des_cntr.processTemplate({
Code: code,
Value: val,
DivisionCode: div,
Amount: 0.00
});
des_cntr.prepend(old);
This is the template:
<div id="pnlDesignations">
<script type="text/html" id="tplDesignations">
<div>
<label>{$T.Value} $</label>
<input type="text" value="{$T.Amount}" />
<button>Remove</button>
<input type="hidden" name="code" value="{$T.Code}" />
<input type="hidden" name="div" value="{$T.DivisionCode}" />
</div>
</script>
</div>
You want to save the previous value and use in the next change event?
This example uses .data to save the previous value. See on jsFiddle.
$("input").change(function(){
var $this = $(this);
var prev = $this.data("prev"); // first time is undefined
alert("Prev: " + prev + "\nNow: " + $this.val());
$this.data("prev", $this.val()); // save current value
});
jQuery .data
If you want old/Initial text box value, you can use single line code as follows.
var current_amount_initial_value = $("#form_id").find("input[type='text']id*='current_amount']").prop("defaultValue");
If you want current value in the text box, you can use following code
$("#form_id").find("input[type='text']id*='current_amount']").val();

add templated div to page multiple times with different ids

I am using ASP.Net MVC along with Jquery to create a page which contains a contact details section which will allow the user to enter different contact details:
<div id='ContactDetails'>
<div class='ContactDetailsEntry'>
<select id="venue_ContactLink_ContactDatas[0]_Type" name="venue.ContactLink.ContactDatas[0].Type">
<option>Email</option>
<option>Phone</option>
<option>Fax</option>
</select>
<input id="venue_ContactLink_ContactDatas[0]_Data" name="venue.ContactLink.ContactDatas[0].Data" type="text" value="" />
</div>
</div>
<p>
<input type="submit" name="SubmitButton" value="AddContact" id='addContact' />
</p>
Pressing the button is supposed to add a templated version of the ContactDetailsEntry classed div to the page. However I also need to ensure that the index of each id is incremented.
I have managed to do this with the following function which is triggered on the click of the button:
function addContactDetails() {
var len = $('#ContactDetails').length;
var content = "<div class='ContactDetailsEntry'>";
content += "<select id='venue_ContactLink_ContactDatas[" + len + "]_Type' name='venue.ContactLink.ContactDatas[" + len + "].Type'><option>Email</option>";
content += "<option>Phone</option>";
content += "<option>Fax</option>";
content += "</select>";
content += "<input id='venue_ContactLink_ContactDatas[" + len + "]_Data' name='venue.ContactLink.ContactDatas[" + len + "].Data' type='text' value='' />";
content += "</div>";
$('#ContactDetails').append(content);
}
This works fine, however if I change the html, I need to change it in two places.
I have considered using clone() to do this but have three problems:
EDIT: I have found answers to questions as shown below:
(is a general problem which I cannot find an answer to) how do I create a selector for the ids which include angled brackets, since jquery uses these for a attribute selector.
EDIT: Answer use \ to escape the brackets i.e. $('#id\\[0\\]')
how do I change the ids within the tree.
EDIT: I have created a function as follows:
function updateAttributes(clone, count) {
var f = clone.find('*').andSelf();
f.each(function (i) {
var s = $(this).attr("id");
if (s != null && s != "") {
s = s.replace(/([^\[]+)\[0\]/, "$1[" + count + "]");
$(this).attr("id", s);
}
});
This appears to work when called with the cloned set and the count of existing versions of that set. It is not ideal as I need to perform the same for name and for attributes. I shall continue to work on this and add an answer when I have one. I'd appreciate any further comments on how I might improve this to be generic for all tags and attributes which asp.net MVC might create.
how do I clone from a template i.e. not from an active fieldset which has data already entered, or return fields to their default values on the cloned set.
You could just name the input field the same for all entries, make the select an input combo and give that a consistent name, so revising your code:
<div id='ContactDetails'>
<div class='ContactDetailsEntry'>
<select id="venue_ContactLink_ContactDatas_Type" name="venue_ContactLink_ContactDatas_Type"><option>Email</option>
<option>Phone</option>
<option>Fax</option>
</select>
<input id="venue_ContactLink_ContactDatas_Data" name="venue_ContactLink_ContactDatas_Data" type="text" value="" />
</div>
</div>
<p>
<input type="submit" name="SubmitButton" value="AddContact" id='addContact'/>
</p>
I'd probably use the Javascript to create the first entry on page ready and then there's only 1 place to revise the HTML.
When you submit, you get two arrays name "venue_ContactLink_ContactDatas_Type" and "venue_ContactLink_ContactDatas_Data" with matching indicies for the contact pairs, i.e.
venue_ContactLink_ContactDatas_Type[0], venue_ContactLink_ContactDatas_Data[0]
venue_ContactLink_ContactDatas_Type[1], venue_ContactLink_ContactDatas_Data[1]
...
venue_ContactLink_ContactDatas_Type[*n*], venue_ContactLink_ContactDatas_Data[*n*]
Hope that's clear.
So, I have a solution which works in my case, but would need some adjustment if other element types are included, or if other attributes are set by with an index included.
I'll answer my questions in turn:
To select an element which includes square brackets in it's attributes escape the square brackets using double back slashes as follows: var clone = $("#contactFields\[0\]").clone();
& 3. Changing the ids in the tree I have implemented with the following function, where clone is the variable clone (in 1) and count is the count of cloned statements.
function updateAttributes(clone, count) {
var attribute = ['id', 'for', 'name'];
var f = clone.find('*').andSelf();
f.each(function(i){
var tag = $(this);
$.each(attribute, function(i, val){
var s = tag.attr(val);
if (s!=null&& s!="")
{
s = s.replace(/([^\[]+)\[0\]/, "$1["+count+"]");
tag.attr(val, s);
}
});
if ($(this)[0].nodeName == 'SELECT')
{ $(this).val(0);}
else
{
$(this).val("");
}
});
}
This may not be the most efficient way or the best, but it does work in my cases I have used it in. The attributes array could be extended if required, and further elements would need to be included in the defaulting action at the end, e.g. for checkboxes.

Categories