I'm trying to be clever with some efficient Javascript but it's causing me headaches and lots of fruitless searching.
I have a set of inputs in a table, each with a given class:
...
<tr>
<td><input name="name" type="text" class="markertitle"/></td>
<td><input name="desc" type="text" class="markerdescription"/></td>
<td><input name="address" type="text" class="markeraddress"/></td>
<td><input name="url" type="text" class="markerurl"/></td>
</tr>
...
I want to take the value of those classes, use it to specify a given variable (which already exists), then assign the value of the input (using +=) to that variable.
This is what I've come up with, but no joy:
var markertitle = {};
var markerdescription = {};
var markeraddress = {};
var markerurl = {};
$('#markermatrixadd input').each(function(){
var field = $(this).attr('class');
window[field] += $(this).val() + ',';
});
It's dead simple I'm sure, but I think my brain's a bit fried :(
Your vars don't seem to be global. They must be declared outside any function. Besides that, you cannot add anything to an object ({}). Use either strings or arrays:
var markertitle = ""
var markerdescription = ""
etc
function() ....
$('#markermatrixadd input').each(function(){
var field = $(this).attr('class');
window[field] += $(this).val() + ',';
});
or
var markertitle = []
var markerdescription = []
etc
function() ....
$('#markermatrixadd input').each(function(){
var field = $(this).attr('class');
window[field].push($(this).val())
});
Better yet, get rid of window and use one single object to store all the data:
var data = {
markertitle: "",
markerdescription: ""
}
function() ....
$('#markermatrixadd input').each(function(){
var field = $(this).attr('class');
data[field] += $(this).val() + ',';
});
Related
I have a javascript OnChange function on a column having textboxes which captures the name of each row in a column. I am appending all the names and storing in variable.
Now , suppose user clicks same textbox again , I don't want to append that name again.
var AppendedString = null;
function onChangeTest(textbox) {
AppendedString = AppendedString;
AppendedString = AppendedString + ';' + textbox.name;
// this gives null;txt_2_4;txt_2_6;txt_3_4;txt_2_4 and so on..and I don't want to append same name again , here it's txt_2_4
}
My Input text :
<input type="text" name="txt_<%=l_profileid %>_<%=l_processstepsequence%>" value="<%= l_comments%>" onfocus="this.oldvalue = this.value;" onchange="onChangeTest(this);this.oldvalue = this.value;">
Those rows seem to have unique names.
you can simply check if AppendedString already contains that name :
var AppendedString=''
function onChangeTest(textbox) {
if (!AppendedString.includes(textbox.name)) {
AppendedString += ';' + textbox.name;
}
}
Codepen Link
You can’t initialize AppendedString as null otherwise, the includes() method won’t be available
otherwise, you can give each row a unique ID, and store in an array IDs that already have been clicked by the user.
var AppendedString = '';
var clickedRows = [];
function onChangeTest(textbox) {
if (!clickedRows.includes(textbox.id)) {
AppendedString += ';' + textbox.name;
clickedRows.push(textbox.id)
}
}
var arr = [];
$("input[type='text']").on("click", function() {
var nowS = ($(this).attr('name'));
if (!(arr.indexOf(nowS) > -1)) {
arr.push(nowS)
}
console.log(arr)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="m1" name="lbl1">
<input type="text" id="m2" name="lbl2">
<input type="text" id="m3" name="lbl3">
Somewhat similar to your need,
var arr = [];
$("input[type='text']").on("click", function() {
var nowS = ($(this).attr('name'));
if (!arr.includes(nowS)) {
arr.push(nowS)
}
console.log(arr)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="m1" name="lbl1">
<input type="text" id="m2" name="lbl2">
<input type="text" id="m3" name="lbl3">
You can add flag your textboxes and ignore if it's clicked again. Like using jquery you can do something like this:
function onChangeTest(textbox) {
AppendedString = AppendedString;
if (!textbox.hasClass("clicked")){
AppendedString = AppendedString + ';' + textbox.name;
textbox.AddClass("clicked");
}
}
I have such code in my view:
<div class="box">
<input type="text" name="product[size_ids][<%= size.id %>][quantity][1]" readonly class="product_quantity" placeholder="quantity from" value="1">
</div>
In my js I'd like to change [1] into [2] or [3] and so on after [quantity], depending on how many additional forms I create. How can I do that?
This is what I have in my JS:
var i = 1
$('.add_another_price_btn').click( function (e) {
e.preventDefault();
$(this).prev().clone().insertBefore($(this));
$(this).prev().find('.remove_another_price_btn').show();
$(this).prev().find('.product_quantity').removeAttr('readonly');
$(this).prev().find('.product_quantity').attr('value', '');
//This is what I tried, but it doesn't work properly.
$(this).prev().find('.product_quantity')
.attr('name', function() { return $(this).attr('name') + '['+ (i++) + ']' });
$('.remove_another_price_btn').click( function (ee) {
ee.preventDefault();
$(this).parent().parent().remove();
});
You can do a simple string operation with substr and lastIndexOf to replace the last part of the name.
// get input and name of input
var input = $("input");
var name = input.attr("name");
// change just the last part
name = name.substr(0, name.lastIndexOf("[")) + "[2]";
// set name back to input
input.attr("name", name);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="product[size_ids][<%= size.id %>][quantity][1]" readonly class="product_quantity" placeholder="quantity from" value="1">
Save the clone
Break the name using substring or split and parseInt
Like this
var $clone = $(this).prev().clone(),
$prodQ = $clone.find('.product_quantity'),
name = $prodQ.attr("name"),
parts = name.split("quantity]["),
newName = parts[0]+"quantity][",
num = parseInt(parts[1],10); // or a counter
num++;
newName += num+"]";
$prodQ.removeAttr('readonly').attr('value', '').attr('name',newName);
$clone.insertBefore($(this));
$clone.find('.remove_another_price_btn').show();
I don't know if this is possible so I figured this would be the place to ask.
I have two inputs and they each hold a unique value. They each have their own respective variable that the value is saved into. I was wondering if there was a way to use just one function to update their values instead of two seperate ones. Below is my code so far.
<form>
<input type="text" id="valueOne" onchange="changeValueOne(this.value)">
<input type="text" id="valueTwo" onchange="changeValueTwo(this.value)">
</form>
var valueOne = parseFloat($('#valueOne'));
var valueTwo = parseFloat($('#valueTwo'));
function changeValueOne(newValueOne) {
valueOne = newValueOne;
}
function changeValueTwo(newValueTwo) {
valueTwo = newValueTwo;
}
Try this:
var valueOne, valueTwo;
$("#valueOne, #valueTwo").change(function(){
if($(this).attr('id') == 'valueOne') {
valueOne = $(this).val();
} else {
valueTwo = $(this).val();
}
});
You could have a second parameter to indicate which variable to store and/or where.
var values;
function changeValue(newValue, pos){
values[pos] = newValue;
}
Change html to:
<input type="text" id="valueOne" onchange="changeValue(this.value, 'first')">
<input type="text" id="valueOne" onchange="changeValue(this.value, 'second')">
Alternatively if you want to store them in separate variables:
function changeValue(newValue, pos){
if(pos == 'first'){
valueOne = newValue;
} else if(pos == 'second'){
valueTwo = newValue;
}
}
the simple expandable way uses a collection instead of vars:
<form>
<input type="text" id="valueOne" onchange="changeValue(value, id)">
<input type="text" id="valueTwo" onchange="changeValue(value, id)">
</form>
<script>
var vals={
valueOne : parseFloat($('#valueOne').val()),
valueTwo : parseFloat($('#valueTwo').val())
};
function changeValue(newValue, slot) {
vals[slot] = newValue;
}
</script>
not only is it incredibly simple and fast, this lets you add many options without reworking the forking code (ifs), all you need to do is modify the vals object and the handler will keep up automatically with all available options, even creating new ones on-the-fly if needed (from new inputs being appended during run-time).
I have the following script
function validateEmailp() {
var messagemail = document.getElementById('emailerrorz').innerText;
var two = document.getElementById('email').value;
var first = two.split("#")[1];
var badEmails = ["gmail.com", "yahoo.com"]
if (badEmails.indexOf(first) != -1) {
document.getElementById("email").value = ""; //this works
messagemail = 'We do not accept free e-mails'; //this doesn't
return false;
}
return true;
}
and HTML
<td>{EMAILFIELD}<span id="emailerrorz"></span></td>
and {EMAILFIELD} is in PHP
<input id="email" class="txt" type="text" name="email" size="25" value="" maxlength="255" onblur="validateEmailp()"></input>
But it doesn't work for me on printing the error in the span id. It only works on resetting the value from there.
When you do var messagemail = document.getElementById('emailerrorz').innerText; your variable stores a string with that content.
When you var messagemail = document.getElementById('emailerrorz'); your variable stores a object/element and then you can use the property .innerText
So use:
var messagemail = document.getElementById('emailerrorz');
// rest of code
messagemail.innerText = 'We do not accept free e-mails';
Properties don't work this way. You want:
document.getElementById('emailerrorz').innerText = 'We do not accept free e-mails'
or
var messagemail = document.getElementById('emailerrorz');
....
messagemail.innerText = etc
http://jsfiddle.net/MJXEg/
How can I pass arguments to a function that is assigned to variable.
For example:
var updateDiv = function() {
var row = this;
var values = "";
$('input[type=text],textarea,input[type=radio]:checked,input[type=checkbox]:checked', this).each(function() {
if ($(this).val()!="" && $(this).val()!=null) {
if (values!="") values = values + ","+ $(this).val();
else values += $(this).val();
}
});
if (values!="") {
if(values.substring(0,1)==",") values = values.substring(1) +"<br>";
else values = values +"<br>";
}
$('.jist', row).append(values);
}
$('tr:has(input)').each(updateDiv);
$('tr:has(textarea)').each(updateDiv);
HTML:
<tr>
<td>ai</td><td> <input type="text" name="ai" id="ai"></td>
<td><input type="checkbox" name="ana" id="ana" value="N/A"></td>
<td><div class="jist"></div></td>
</tr>
I want to pass arguments to updateDiv -> updateDiv("mystring");
and I want to use "mystring" in the function this way - > $('.'+mystring, row).append(values);
Simple and Clean
Not sure how I missed the obvious here.
jQuery
var updateDiv = function(divClass) {
...
$(divClass, row).append(values);
}
$('tr:has(input)').each(function(){ updateDiv('.hist'); });
$('tr:has(textarea)').each(function(){ updateDiv('.something-else'); });
.
Global Variable Method
You could assign global variables with the class name. By defining the variable before each .each() the updateDiv function uses a different class name.
jQuery
var updateDiv = function() {
...
$(window.divClass, row).append(values);
}
window.divClass = '.hist';
$('tr:has(input)').each(updateDiv);
window.divClass = '.something-else';
$('tr:has(textarea)').each(updateDiv);
.
HTML5 Data Method
You could assign values as data objects to the elements which are being called. I also cleaned up some of your selectors and jQuery redundancies.
Fiddle: http://jsfiddle.net/iambriansreed/KWCdn/
HTML
<table>
<tr data-update=".hist">
<td>AutoI</td>
<td> <input type="text" name="autoIH_complaint" id="autoIH_complaint"></td>
<td><input class="NA" type="checkbox" name="autoINA" id="autoINA" value="N/A"></td>
<td><div class="hist"></div></td>
</tr>
</table>
jQuery
var updateDiv = function() {
var row = this, values = "";
$('input:text,textarea,:radio:checked,:checkbox:checked', this).each(function() {
if (this.value != "" && this.value != null) {
if (values != "") values = values + "," + this.value;
else values += this.value;
}
});
if (values != "") {
if (values.substring(0, 1) == ",") values = values.substring(1) + "<br>";
else values = values + "<br>";
}
$(row.data('update'), row).append(values);
}
$('tr:has(input)').each(updateDiv);
$('tr:has(textarea)').each(updateDiv);
We can pass the index into the function, much like jQuery's .each() method.
<div class="test">1</div>
<div class="test">2</div>
This will alert "0" and then "1" for the indexes.
var updateDiv = function( index )
{
alert( index );
}
$('.test').each(updateDiv);
If you pass in strings as parameters, .each(updateDiv("string1")) it is evaluates the function first.