jQuery form input into an array not working - javascript

I'm working on a game and there is a form input where the user enters the number of characters. Once this happens more inputs appear for each character's name. My problem right now is reading those names into an array.
When the new inputs are created also a new button called nameButton is created and that is my issue, when I attempt to click that nothing happens when the values should be stored in an array. I put a prompt at the end of the function just to check and that does not even get called.
If you all have any suggestions please let me know here is the jsFiddle
function nameRecording(names,$this){
var addRows='<tr id=newRows>';
for(var i =1; i<=names; i++)
{ var nearTr=$this.closest('tr');
addRows=addRows+'<td>Name one:</td><td><form><input type="text" name="charcItem" class = "newR"/></form></td>';
}
addRows=addRows+'<td><div class="button" id="nameButton"> Add! </div></td></tr>';
nearTr.after(addRows);
};
$('#nameButton').click(function(){
names=$(".newR").map(function(){
return $(this).val();
});
prompt(names);
});
And there are some of my functions.

Try this way:
$(".form").on('click', '#nameButton', function () {
names = $(".newR").map(function () {
return this.value;
}).get();
prompt(names);
});
You can use event delegation using on for dynamic elements
You need to do a .get() on .map() result to convert the collection object into array.
Demo

Related

How to generate one object key with an array of stored values from multiple on click events using localstorage and Jquery

I'm new to coding, and I need to display past search values from an input field using localstorage. The only way I can think of is by using one object key with an array of stored values from an on click event. Problem is, I can only get one position to appear as a value, with each value generated replacing the last. I've tried for loops and can't seem to get it to work. This is the code I have so far:
$('.search-city').on('click', function(e){
e.preventDefault();
var textArr = [];
var text = $(".form-control").val();
textArr.push(text);
localStorage.setItem("value1", textArr);
});
$('.search-city').on('click', function(e){
e.preventDefault();
var search = localStorage.getItem("value1")
This would work:
$('.search-city').on('click', function(e){
e.preventDefault();
// get the value from local storage
var localValue = localStorage.getItem('value1');
// if we had a value, parse it back to an array, if we dont, create an empty array
var textArr = localValue ? JSON.parse(localValue) : [];
// get the text from the search input, dont use "form-control"
// you're likely to have several of those on the page
// give the element a custom class like "search-input" and use that (id would be even better)
var text = $('.search-input').val();
// add the text to the array
text = trim(text);
if (text) {
textArr.push(text);
}
// enforce a size limit here by removing the 0 index item if the count has grown too large
var maxAllowed = 10;
while (textArr.length > maxAllowed) {
textArr.shift();
}
// localstorage can only hold simple strings so we'll JSON stringify our object and store that
localValue = JSON.stringify(textArr);
localStorage.setItem("value1", localValue);
});

jQuery detect input change

I'm working on a feature where the user needs to be informed that there are unsaved changes in a form in case if they decide to navigate away from the page.
I am almost done but there's a tiny problem-
I am setting a boolean dirty on input change event.
The .change() event will detect any kind of change, as in it doesn't keep track of changes. For example, if an input field has the original value hello, which is modified to bye and back to hello, it will still set the dirty boolean.
Is there any way where I can take a backup of the form with initial values and then compare it with itself at every change event?
You need a way to serialize the form data into a JSON object, and then you could either compare the JSON object by iterating the properties or by comparing the JSON.stringify values.
I have slightly modified the method of objectifying the form data from here in order to do this.
var form = document.getElementById("myForm");
var originalFormData = objectifyForm(form);
var originalFormDataString = JSON.stringify(originalFormData);
setInterval(function() {
var formData = objectifyForm(form);
var formDataString = JSON.stringify(formData);
console.log("Form is dirty: " + (formDataString != originalFormDataString));
},1000);
function objectifyForm(formArray) {//serialize data function
var returnArray = {};
for (var i = 0; i < formArray.length; i++){
returnArray[formArray[i]['id']] = formArray[i]['value'];
}
return returnArray;
}
<form id="myForm">
<input id="myInput" value="test" type="text" />
</form>
You can do something like this. Remember this solution is just a sample. You have multiple input element, than use array/object to save there defaultValue.
var defaultValue = document.getElementById("myText").defaultValue;//Get the default value
var handleChange = function (){
let value = document.getElementById("myText").value;//get the current value
if(defaultValue===value){
console.log("dirty false")
}else {
console.log("Dirty True")
}
}
<input type="text" id="myText" value="abc" onkeyup="handleChange()">
I think you can create a javascript empty initial_values = {} object. initialised it with the default values in the form of key:value pairs. and if dirty boolean is set, it can be used to compare later on.

Get value of all dynamically created hidden fields with class?

I would like to get the values of dynamically created hidden fields with a class reference.
Example of created hidden field
<input class="SelectedClaimants" id="CodesList_2__Claimant" name="CodesList[2].Claimant" type="hidden" value="Jason Statham">
This is something along the lines of what i have tried.
$('.listSelected').on('DOMSubtreeModified', function (event) {
$(".SelectedClaimants").find('input[type=hidden]').each(function () {
var testC += $(this).val();
});
});
I was aiming to have them create into an array object, but at the moment i am happy just to get the values out into a concatenated string.
Try this (the result is logged to the console). It's based onn Tushar's answer, but the selector was wrong.
$('input[type="hidden"].SelectedClaimants').map(function () {
return $(this).val();
}).get().join(',')
You can use .querySelectorAll(), spread element, for..of loop. Note, id, e.g., CodesList_2__Claimant should be unique in document.
var testC = [];
for (let el of [...document.querySelectorAll("input[type='hidden'].SelectedClaimants")]) {
testC.push(el.value)
}

HTML How to pass two variables on a radio button press?

How can I pass two variables on a button press? This may seem basic but I am completely stuck!
I am creating a table that has a radio button on the left side, and when you press it I want to retrieve two values. I am currently retrieving one value but I am missing the other.
Currently I am passing one value onto my onRadioButtonPress function like this:
html += "<tr><td><center><br>
<input type='radio'
onclick='onRadioButtonPress(this.value)'
name='siteChosen'
value='"+siteIDArray[i]+"'>
<center></td>";
And I am calling the function like this:
//function for on radio button press
function onRadioButtonPress(val){
//blah blah blah
}
Which is working great, but how do I add a second value of
usagePlanArray[i]
to my on onClick function? How would I change my input?
Thank you in advance!!! :) Please let me know if you have any questions, or if I missed something that would help you out!
SOLVED!
Please see the marked answer from #mplungjan. I used his alternative method that is useful for jQuerys.
value='"+siteIDArray[i]+"|"+usagePlanArray[i]+"'>
but you need to remove the newlines from the HTML too
Then in the function you can use
var vals=val.split("|");
var siteID=vals[0], usagePlan=vars[1];
Alternative - especially useful in jQUery:
html += "<tr><td><center><br><input type='radio'"+
" onclick='onRadioButtonPress(this)' name='siteChosen'"+
" data-siteid='"+siteIDArray[i]+"'"+
" data-usageplan='"+usagePlanArray[i]+"'><center></td>";
and
function onRadioButtonPress(rad) {
var siteID=rad.getAttribute("data-siteid"),
usageplan=rad.getAttribute("data-usageplan"),
}
Pass an array in JSON:
value='"+JSON.stringify(siteIDArray)+"'>
That would pass the entire Array as JSON Array string.
Passing to single values:
value='["+siteIDArray[i] + "," + usagePlanArray[i] + "]'>
or, as an object:
value='{ \"val1\":\""+siteIDArray[i] + "\",\"val2\":\"" + usagePlanArray[i] + "\"]'>
Now decode in the function
values = JSON.parse(val);
...
xyz = values[0]; // for the array
...
xyz = values.val1; // for the object
code could even be optimized, if you direct pass that to the onclick instead of the value parameter, but that might have some additional purposes.
If you are using the same index for both arrays, why not just store the index as the value and look up the desired values in the click callback?
var html= "";
var siteIDArray = [1, 5, 2, 33];
var usagePlanArray = ["unlimited", "20gb", "10gb", "5gb" ]
function arrayCombo(index){
return {siteId: siteIDArray[index], usagePlan: usagePlanArray[index]};
}
for(var i=0; i<siteIDArray.length; i++){
html += "<tr><td><center><br><input type='radio' name='siteChosen' value="+i+"><center></td>";
}
$('#content').html(html);
$('input').on('click', function(event){
//Do whatever you want with the values you are looking for here
var x = arrayCombo(this.value);
alert(x.siteId+", "+x.usagePlan);
});
Also, to demonstrate this tight-knit relationship between your arrays it would probably be better to store their values at shared indexes as properties of objects in an array.

Renaming formelements in a particular range with jquery

I've multiple autogenerated forms on a page. They are named in a particular manner like:
form-0-weight, form-1-weight, form-2-weight etc.
<ul>
<li>
<input id="id_form-0-weight" type="text" name="form-0-weight">
<a class="deleteIngredient" href="">x</a>
</li>
<li>
....more forms
</li>
</ul>
The user can add and delete forms. If a form get's deleted, the remaining ones should be renamed to stay in order. e.g. "form-1-weight" gets deleted >> "form-2-weight" will be renamed to "form-1-weight".
The total number of forms is stored in a hidden field named TOTAL_FORMS.
I'm trying to achieve this with a simple for loop.
The problem is that all the forms after the deleted one get the same name.
e.g. If I delete form-2-weight, all the following forms get the name form-2-weight instead of 2, 3, 4 etc.
$(".deleteIngredient").click(function(e){
e.preventDefault();
var delete = $(this).closest('li');
name = delete.children('input').attr("name");
count = name.replace(prefix,'');
count = name.replace("-weight",'');
var formCount = parseInt($("#TOTAL_FORMS").val())-1;
delete.remove();
for (var i = parseInt(count); i<=formCount; i++){
var newName = "form-"+i+"-weight";
$("#id_form-"+(i+1)+"-weight").attr("name",newName);
}
});
I suppose it has something to do with how I select the elements inside the loop because when I use just the variable "i" instead of "newName" it works as expected.
The problem is you're not initializing i properly.
This happens because "count" doesn't contain a string that can be parsed into an integer under the conditions of parseInt, I suggest you look here:
w3Schools/parseInt
Note: If the first character cannot be converted to a number, parseInt() returns NaN.
When you assign a string to "count" you're actually inserting the string "form-i" into the variable.
What you should do is this:
count = name.replace(prefix,'');
count = count.replace("-weight",'');
You should also rename your "delete" variable to "form" or any other descriptive name, as delete is a reserved word in javascript and also an action so it doesn't really suit as a name for an object.
Don't forget to change the id attribute of the item so it'll fit the new name.
As a note, you should probably consider following through some tutorial on Javascript or jQuery, Tuts+ learn jQuery in 30 days is one i'd recommend.
My first impulse is just to solve this a different way.
Live Demo
var $ul = $('ul');
// Add a new ingredient to the end of the list
function addIngredient() {
var $currentIngredients = $ul.children();
var n = $currentIngredients.length;
var $ingredient = $('<li>', {
html: '<input type="text" /> x'
});
$ul.append($ingredient);
renameIngredientElements();
}
// Rename all ingredients according to their order
function renameIngredientElements() {
$ul.children().each(function (i, ingredient) {
var $ingredient = $(ingredient);
var $input = $ingredient.find('input');
var name = 'form-' + i + '-weight';
$input
.attr('id', 'id_' + name)
.attr('name', name);
});
}
// Delete an ingredient
function deleteIngredient($ingredient) {
$ingredient.remove();
renameIngredientElements();
}
// Bind events
$('.add-ingredient').on('click', addIngredient);
$ul.on('click', '.delete-ingredient', function (event) {
var $ingredient = $(event.currentTarget).closest('li');
deleteIngredient($ingredient);
event.preventDefault();
});
As to why your particular code is breaking, it looks like user2421955 just beat me to it.

Categories

Resources