jQuery replace integer globally in html var - javascript

I am trying to replace a number globally in my HTML string by regex but it only replaces the number when it's not attached to an attribute.
e.g. I want to replace the number 123 globally. The problem in this example is that only the number in the value has been changed and not the number between the brackets.
var oldId = 123;
var newId = 1234;
<input type="hidden" name="field_name" value="123">
<input type="radio" name="field_name[123]" class="id_123">
$('.settings').replace(/oldId/g, newId);
Current result
<input type="hidden" name="field_name" value="1234"> <-- changed
<input type="radio" name="field_name[123]" class="id_123"> <--- not changed
I guess I need to modify my regex a somehow?

You can use .each(), g flag at RegExp to replace .outerHTML of elements where name attribute includes "field_name"
var oldId = 123;
var newId = 1234;
$("input[name*=field_name]").each(function(i, el) {
el.outerHTML = el.outerHTML.replace(new RegExp(oldId, "g"), newId)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="hidden" name="field_name" value="123">
<input type="radio" name="field_name[123]" class="id_123">

Related

How can I access these form values?

I want to create a form where I will perform an operation with the values entered by the user, but when the function runs, I get NaN return. Thank you in advance for the help.
function test() {
var age = document.getElementsByName("person_age").value;
var weight = document.getElementsByName("person_weight").value;
var size = document.getElementsByName("person_size").value;
document.getElementById("result").innerHTML = weight + size + age;
}
<form>
<input type="text" name="person_age">
<input type="text" name="person_size">
<input type="text" name="person_weight">
<input type="button" value="calculate" onclick="test();">
</form>
<h3 id="result"></h3>`
Output:
NaN
When I get the values from the user and run the function, I get NaN feedback. how can i solve this problem.
There are multiple errors that you have to correct
1) When you use getElementsByName, It will return NodeList array like collection. So you have to get the element by using index as:
var age = document.getElementsByName( "person_age" )[0].value;
2) If you need sum of all three value then you have to convert it into Number type because document.getElementsByName( "person_age" )[0] give you value in String type. So you can do as:
+document.getElementsByName( "person_age" )[0].value
function test() {
var age = +document.getElementsByName("person_age")[0].value;
var size = +document.getElementsByName("person_size")[0].value;
var weight = +document.getElementsByName("person_weight")[0].value;
document.getElementById("result").innerHTML = weight + size + age;
}
<form>
<input type="text" name="person_age">
<input type="text" name="person_size">
<input type="text" name="person_weight">
<input type="button" value="calculate" onclick="test();">
</form>
<h3 id="result"></h3>
Just a Suggestion: You can use Document.getElementById if you want to directly access the value. Just add an ID property in your element. It will return a string value, convert that to int and you're good to go.
function test() {
var age = document.getElementById("person_age").value;
var weight = document.getElementById("person_weight").value;
var size = document.getElementById("person_size").value;
document.getElementById("result").innerHTML = parseInt(weight) + parseInt(size) + parseInt(age);
}
<form>
<input type="text" name="person_age" id="person_age">
<input type="text" name="person_size" id="person_size">
<input type="text" name="person_weight" id="person_weight">
<input type="button" value="calculate" onclick="test();">
</form>
<h3 id="result"></h3>
getElementsByName will always return an array-like nodelist so, if you were to use it you would need to access the first index [0]. Instead add a class to each input and use querySelector to target it.
The value of an input will always be a string (even if the input is type "number"), so you need to coerce it to a number, either by using Number or by prefixing the value with +.
So, in this example I've updated the HTML a little by adding classes to the inputs, and changing their type to "number", and removing the inline JS, and updated the JS so that the elements are cached outside of the function, an event listener is added to the button, and the values are correctly calculated.
// Cache all the elements using querySelector to target
// the classes, and add an event listener to the button
// that calls the function when it's clicked
const ageEl = document.querySelector('.age');
const weightEl = document.querySelector('.weight');
const sizeEl = document.querySelector('.size');
const result = document.querySelector('#result');
const button = document.querySelector('button');
button.addEventListener('click', test, false);
function test() {
// Coerce all the element values to numbers, and
// then display the result
const age = Number(ageEl.value);
const weight = Number(weightEl.value);
const size = Number(sizeEl.value);
// Use textContent rather than innerHTML
result.textContent = weight + size + age;
}
<form>
<input type="number" name="age" class="age" />
<input type="number" name="size" class="size" />
<input type="number" name="weight" class="weight" />
<button type="button">Calculate</button>
</form>
<h3 id="result"></h3>`

Copying text to two inputs with the same ID

When I wrote something in the first input, second input showed it, but:
a) What if i want see text from input "2" showed in input "3"?
HTML:
<input id="1" type="text" oninput=al() /></br>
<input id="2" disabled="disabled" ></br>
<input id="3" disabled="disabled">
JS:
function al() {
var a = document.getElementById("1").value;
var result = a;
var ab = document.getElementById("2");
ab.value=a;
}
b) What if I want to see text from input "1" in two inputs named "2"?
HTML:
<input id="1" type="text" oninput=al() /></br>
<input id="2" disabled="disabled" ></br>
<input id="2" disabled="disabled">
JS:
function al() {
var a = document.getElementById("1").value;
var result = a;
var ab = document.getElementById("2");
ab.value=a;
}
Answer A: To show the same value in an input with ID 2 and an input with ID 3:
function al() {
var a1 = document.getElementById("1").value;
var a2 = document.getElementById("2");
var a3 = document.getElementById("3");
a2.value = a3.value = a1;
}
Answer B: Using elements with the same ID is wrong and will result in an invalid HTML document. To achieve your goal, you can set both elements with a certain class (classA at the example below), then you can use document.querySelectorAll which returns an array of elements, and then set their value with an index [0] and [1]:
<input id="1" type="text" oninput=al() /></br>
<input class='classA' disabled="disabled" ></br>
<input class='classA' disabled="disabled">
function al() {
var a = document.getElementById("1").value;
var result = a;
var ab = document.querySelectorAll("[class='classA']");
ab[0].value = ab[1].value = a;
}
First of all, you can't have two element with the same ID.
Second to copy from one to another, it's better use the keyDown, keyUp or onchange events.
E.g.
<input type="text" id="1" onchange="copypaste()"/>
<input type="text" id="2"/>
function copypaste() {
var first = document.getElementById("1")
var second = document.getElementById("2")
second.value = first.value
}

Javascript replace string with values from dom object

Im trying to make a formula dynamic and also the input fields. First problem is to change the (c1 + d2) into values like (1 + 2) depending on what is the value in input. consider that tdinput is dynamic so I can add as many as I can and formula can change anytime.
<input class="tdinput" type="text" data-key="c1">
<input class="tdinput" type="text" data-key="d2">
<input type="text" data-formula="(c1 + d2)">
<script>
$('.tdinput').on('change', function() {
var key = $(this).attr('data-key');
$('[data-formula*="+key+"]').each(function() {
//now here goes to change the data-formula by inputted values
//calculate using eval()
});
});
</script>
You need to make a more modular approach with this.
And make good use of the javascript jquery api you're using.
When a variable is defined by data-something-something you can access it by jQuerySelectedElement.data('something-something')
Now, eval is evil, but when you sanitise your input variables(in this case by parseInt) you should be relatively save from xss inputs etc..
What happens is, all the variables are inserted as an property in an object t.
then eval will call and and access all the objects in t and do the calculation.
Only requirement is that you define all the variables not as just c2, but as t.c2 in your key definition properties.
have a look below at the play with the data properties and the eval.
When using eval ALWAYS make sure you only eval 'safe' data! Don't eval strings if you plan to safe user input! you open your site for XSS attacks then.
$('[data-formula]').on('keyup', function() {
var $this = $(this);
var formulaName = $this.data('formula');
var $output = $('[data-formula-name="'+formulaName+'"]');
var formula = $output.data('formula-calc');
var t = {};
var keys = [];
$select = $('[data-formula="'+formulaName+'"]');
$select.each(function(index,elem) {
var $elem = $(elem);
var key = $elem.data('key');
t[key] = parseFloat($elem.val());
keys.push(key);
if(isNaN(t[key])) {
t[key]=0;
}
});
for(var c=0;c<keys.length;c++) {
formula = formula.replace(new RegExp(keys[c],'g'),'t.'+keys[c]);
}
var result = 0;
eval('result = '+formula)
$output.val(result)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
sum:
<input class="tdinput" type="text" data-formula="sum" data-key="c1">
<input class="tdinput" type="text" data-formula="sum" data-key="d2">
<input type="text" data-formula-name="sum" data-formula-calc="(c1 + d2)" disabled>
<BR/>
xor
<input class="tdinput" type="text" data-formula="pow" data-key="c1">
<input class="tdinput" type="text" data-formula="pow" data-key="d2">
<input type="text" data-formula-name="pow" data-formula-calc="(c1 ^ d2)" disabled>
<BR/>
sub
<input class="tdinput" type="text" data-formula="sub" data-key="c1">
<input class="tdinput" type="text" data-formula="sub" data-key="d2">
<input type="text" data-formula-name="sub" data-formula-calc="(c1 - d2)" disabled>
<BR/>
silly
<input class="tdinput" type="text" data-formula="silly" data-key="c1">
<input class="tdinput" type="text" data-formula="silly" data-key="d2">
<input type="text" data-formula-name="silly" data-formula-calc="(c1 / d2 * 3.14567891546)" disabled>
You can use eval().
Logic
Fetch formula and save it in string
Get all valid keys
Replace keys with value in formula
Use eval() to process it
Sample
JSFiddle
$("#btnCalculate").on("click", function() {
var $f = $("input[data-formula]");
var formula = $f.data("formula");
formula.split(/[^a-z0-9]/gi)
.forEach(function(el) {
if (el) {
let v = $("[data-key='" + el + "']").val();
formula = formula.replace(el, v);
}
});
var result = eval(formula);
console.log(result)
$f.val(result)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<input class="tdinput" type="text" data-key="c1">
<input class="tdinput" type="text" data-key="d2">
<br/>
<input type="text" data-formula="(c1 + d2)">
<button id="btnCalculate">calculate</button>
Reference
Eval's alternate for string calculation.
Why using eval is not a good idea

Assigning an id to a regex pattern

I need to assign an ID into a pattern so that someone could write something in my first text field, and then write a key word in the second textfield, then the key word will be the pattern searched by the RegExp.
JavaScript
function getInput(textfield)
{ // get value from field
var inString = document.getElementById("string").value;
var inSubstring = document.getElementById("substring").value;
// search for pattern
var patt1 = /Id/g;
// document.writeln(patt1);
var result = inString.match(patt1);
// choose paragraph and write the result
document.writeln(result);
// document.getElementById("Answer").innerHTML = result;
}
HTML
<body>
<form id="form1" name="form1" method="post" action="">
<label>Enter a string
<input id="string" name="string" type="text" />
</label>
<input name="Button" type="submit" value="Submit" id="Button" onclick="getInput('textfield')" />
<br />
<br />
<label>Enter a substring to search
<input id="substring" name="substring" type="text" />
</label>
</form>
<p id="Answer"> </p>
</body>
Use a RegExp object instead of an inline regex :
function getInput(textfield)
{ // get value from field
var inString = document.getElementById("string").value;
var inSubstring = document.getElementById("substring").value;
// search for pattern
var patt1 = new RegExp(inSubstring, "g");
// document.writeln(patt1);
var result = inString.match(patt1);
// choose paragraph and write the result
document.writeln(result);
// document.getElementById("Answer").innerHTML = result;
}
I believe you want this regex to change:
var patt1 = /Id/g;
And support a variable id to be searched.
You can use RegExp object with word boundaries:
var patt1 = new RegExp('\\b' + id + '\\b', 'g');
OR else you can just dump the regex and use String#indexOf like this:
index = inString.indexOf(id);

JQuery - list of string

In JQuery, why do I get information Undefined with the following code?
JS - right part is Undefined
var s = $("[name='CountAnswer']").val();
HTML
<input style="width:150px" type="text" id="CountAnswer_1_" name="CountAnswer[1]">
<input style="width:150px" type="text" id="CountAnswer_2_" name="CountAnswer[2]">
<input style="width:150px" type="text" id="CountAnswer_3_" name="CountAnswer[3]">
You are using equality comparion but you have to use wild card probably jquery attribute starts with ^ but the above statement will give value of first matched element. You can use each to iterate through all elements.
var s = $("[name^='CountAnswer']").val();
Iterating using each().
Live Demo
$("[name^='CountAnswer']").each(function(){
alert($(this).val());
//or
alert(this.value);
});
Edit Based on OP comments. For getting the values of all matches.
Live Demo
strValues = $("[name^='CountAnswer']").map(function(){
return this.value;
}).get().join(',');
Because you don't have an element whose name is == CountAnswer. You need to specify a specific name, for example:
$("[name='CountAnswer[1]']").val();
Alternatively, you could use the "Begins With" wildcard (^) to match all elements whose name begins with CountAnswer:
$("[name^='CountAnswer']").val();
This will of course, only return the value of the first element in the matched set, since that is the behaviour of val().
jsFiddle demo
You should set up an array for your string values, and then on some event use the jquery partial match selector, "starts with"(^), to iterate on the list of inputs denoted by your name.
demo html:
<input value="a" style="width:150px" type="text" id="CountAnswer_1_" name="CountAnswer[1]">
<input value="b" style="width:150px" type="text" id="CountAnswer_2_" name="CountAnswer[2]">
<input value="c" style="width:150px" type="text" id="CountAnswer_3_" name="CountAnswer[3]">
<br><input type="button" id="b" value="show string list" /><div id="console"></div>
demo js:
var stringList = [];
$('#b').click(function(){
stringList = [];
$("[name^='CountAnswer']").each(function(){
stringList.push(this.value);
});
var c = $("#console");
for( var i = 0; i < stringList.length; i++ ){
var d = $("<div>");
d.html(stringList[i]);
c.append(d);
}
console.log(stringList);
});

Categories

Resources