Not able to fetch values from two dimensional array in Javascript - javascript

I am inserting values in two dimensional array according to my role_id i.e
var tdarray = [[]];
tdarray[40].push(22);
where 40 is my role_id and 22 is its value.
However when i print this value it shows null
alert(tdarray[40][0]); //this shows no value.
I guess two dimensional array in jquery does not allow to insert values at specific position.Can you suggest me what i can do to overcome this.
Entire Code is here
var tdarray = [[]];
var incr = 1;
var check;
$(function () {
$('.toggle_checkbox').change(function () {
if (check === null) {} else {
if (this.name == check) {
incr++;
} else {
incr = 1;
}
}
var tval = $(this).val();
check = this.name;
tdarray[this.name].push(tval);
});
});
Html code
<table border = "0"
cellspacing = "0"
cellpadding = "1" >
<tbody>
<c:forEach items="${accessRightValues}" var="rights" >
<tr style="height: 40px;">
<td style="width: 240px;"><input type="checkbox" name="<c:out value="${rights.roleid}"/>" value="1" class="toggle_checkbox"> Add </td>
<td style="width: 240px;"><input type="checkbox" name="<c:out value="${rights.roleid}"/>" value="2" class="toggle_checkbox">Update</td>
<td style="width: 240px;"><input type="checkbox" name="<c:out value="${rights.roleid}"/>" value="3" class="toggle_checkbox">View </td>
<td style="width: 240px;"><input type="checkbox" name="<c:out value="${rights.roleid}"/>" value="4" class="toggle_checkbox">Delete </td>
<td style="width: 240px;"><input type="checkbox" name="<c:out value="${rights.roleid}"/>" value="5" class="toggle_checkbox">Assign </td>
</tr>
</c:forEach>
</tbody> < /table>
My problem is that id 40 can hold more than one value .So i want to know how i can do it using multidimensional array in jquery.Also there can be more than one role_id's such as 50,57 which will again hold more than one value.Please help me regarding the same.
I want to pass this two dimensional array in my spring controller.
tdarray[40][0] =1;
tdarray[40][1] =3;
tdarray[40][2] =5;
tdarray[48][0] =2;
tdarray[48][1] =3;
where 40,48 is role_id of a user and 1,3,5 are access_rights which i want to store in database.

In order to use push() function in the key 40 you have to initialize that position as an array as well.
var tdarray = [];
tdarray[40] = [];
tdarray[40].push(22)
// It works now
alert(tdarray[40][0]);
In the code you provided:
var tdarray = [];
...
// Check if it's an array before initialize
if(!tdarray[this.name] instanceof Array) {
tdarray[this.name] = []; // or tdarray[this.name] = new Array();
}
tdarray[this.name].push(tval);

Maybe obvious solution, but if you want to be able to access your values by a key (such as 40), why not use an object?
var tdarray = {};
if ( ! tdarray['40']) tdarray['40'] = [];
tdarray['40'].push(22)

You have to check if its an array already and if its not create it.
var tval = $(this).val();
check=this.name;
if( tdarray[this.name]constructor !== Array){
tdarray[this.name]=[]
}
tdarray[this.name].push(tval);

Related

Remove first duplicate from an array of objects in JavaScript

On input change I create an array of objects. When any value enter within the input field, it pushes objects into array but the problem is when a text field is updated, it does again push items into array. I need to update the array instead of pushing more items.
var tableData = [];
$('.aantalNumber').change(function(){
var aantalNumberVal = $(this).val()
var Productnummer = $(this).closest('tr').find('.product_number').text();
var Productnaam = $(this).closest('tr').find('.product_name').text();
var verpakking =$(this).closest('tr').find('.verpakking').text();
tableData.push({aantalNumber:aantalNumberVal,Productnummer:Productnummer,Productnaam:Productnaam,verpakking:verpakking });
console.log(tableData);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr>
<td><input type="number" class="aantalNumber" name="Aantal1"></td>
<td class="product_number">01454</td>
<td class="product_name">Vendor Handdoeken ZZ vouw</td>
<td class="verpakking">5000 velper verpakking</td>
</tr>
<tr>
<td><input type="number" class="aantalNumber" name="Aantal2"></td>
<td class="product_number">218031</td>
<td class="product_name">Vendor Handdoeken ZZ vouw</td>
<td class="verpakking">5000 velper verpakking</td>
</tr>
<!-- Repeated tr and so on -->
First check if value exist, if available then update else push into tableData
var tableData = [];
$('.aantalNumber').change(function() {
var aantalNumberVal = $(this).val()
var Productnummer = $(this).closest('tr').find('.product_number').text();
var Productnaam = $(this).closest('tr').find('.product_name').text();
var verpakking = $(this).closest('tr').find('.verpakking').text();
if (tableData.some(tableData => tableData.Productnummer === Productnummer)) {
updateTableData(Productnummer, aantalNumberVal);
} else {
tableData.push({
aantalNumber: aantalNumberVal,
Productnummer: Productnummer,
Productnaam: Productnaam,
verpakking: verpakking
});
}
console.log(tableData);
});
function updateTableData(value, aantalNumber) {
for (var i in tableData) {
if (tableData[i].Productnummer == value) {
tableData[i].aantalNumber = aantalNumber;
break; //Stop this loop, we found it!
}
}
}
Working Demo

How to pass a values from two different function to third function in javascript?

I'm trying to code an exercise in html page with javascript, to calculate the mean of a random array of 6 numbers that generated from randomArray() function.
After the first loading of the page and when i click "new problem" button this function recalled to copy the random array in a cell of table.
I write calcMean to calculate the mean of the random array which was passed from randomArray() , and i make the form stop refreshing the page when i hit Enter key when i enter a input , and return the value of input by searchm()
but the problem now is , i want to take the mean ,maxi,mini and inans , to another function to compare the real answer with the user answer and if the condition is yes , something wrote on a div .
the second problem is , i want to take the mean value from calcMean() to show it on the input if i clicked "solution" button which call solution() method, what i must pass to the last function to go write.
<div >
<form action="" method="post" name="meanForm" onsubmit='return false' id="formmine">
<table width="100%" border="0" >
<tr>
<td colspan="3" style="background-color:#06F ;color:#FFF">Answer this problem</td>
</tr>
<tr>
<td style="color:green; font-size:20px">What is the mean of these numbers </td>
<td colspan="2" id="numbers">
</td>
</tr>
<tr>
<td colspan="3"> </td>
</tr>
<tr id="answerANDpic">
<td height="62" colspan="3" align="center" > <input name="" type="text" size="15" maxlength="100" height="50" style=" border: solid #0C0 ; border-width:thin" id="answer" onkeydown="searchm(this)"/> </td>
</tr>
<tr>
<td colspan="3" ><div id ="explain" ></div></td>
</tr>
<tr>
<td> </td>
<td><input name="" type="button" id="newEx" style="background-color:green ; color:white" align ="left" value="New Problem" class="send_feed" onclick="randomArray(6,0,99)" /></td>
<td><input name="" type="button" id="solution" style="background-color:#606 ; color:#FFF " align="left" class="send_feed" value="Solution" onclick="solution()"/></td>
</tr>
</table>
</form>
</div>
but in javascript
var myNumArray = randomArray(6,0,99);
function random_number(min,max) {
return (Math.round((max-min) * Math.random() + min));
}
function randomArray(num_elements,min,max) {
var nums = new Array;
for (var element=0; element<num_elements; element++) {
nums[element] = random_number(min,max);
}
document.getElementById("numbers").innerHTML=nums;
calcMean(nums);
}
function calcMean(nums) {
var num=0;
for (var i=0;i<nums.length;i++) {
num += parseFloat( nums[i], 6 );
}
var divide=num/nums.length;
var mean=(parseInt(divide,10));
var maxi = Math.max.apply(Math,nums);
var mini = Math.min.apply(Math,nums);
return mean,maxi,mini;
}
function searchm(ele) {
if(event.keyCode == 13) {
// alert(ele.value); // i get the value and put it on alert
var inans= ele.value;
return inans;
}
}
function comparing(mean,maxi,mini,inans) {
if(inans==mean){document.getElementById("explain").innerHTML= "correct"+","+inans+"," +maxi+","+mini;
}
}
function solution() {
//some code to take the mean value(realvalue)from calcMean()
//what is parameter should i pass it when i click on solution button to pass it this function
}
Learn Objects https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
with Objects you can return any kind of data types from your functions
for example
function calcMins (nums) {
// ...
return {mean: mean, maxi: maxi, mini: mini}
var values = calcMins(nums)
var mean = values.mean // and so on
at solution() you need to read your document.getElementById("numbers").innerHTML and run
calcNums(nums) from saved numbers. After that you may compare values.mean with your input mean
Not writing full code, cause it's exercise, discover the ways how to use functions, Objects, or Arrays, seems you are familiar with arrays
return [mean, maxi, mini] will work, try it too
You can change to something like this.
As others users said, you can't return multiple values, so convert it to an object
var valuesReturned = null; // initialize variable
function randomArray(num_elements,min,max) {
var nums = new Array;
for (var element=0; element<num_elements; element++) {
nums[element] = random_number(min,max);
}
document.getElementById("numbers").innerHTML=nums;
valuesReturned = calcMean(nums);
}
function calcMean(nums) {
var num=0;
for (var i=0;i<nums.length;i++) {
num += parseFloat( nums[i], 6 );
}
var divide=num/nums.length;
var mean=(parseInt(divide,10));
var maxi = Math.max.apply(Math,nums);
var mini = Math.min.apply(Math,nums);
return {"mean":mean, "maxi": maxi, "mini": mini}; //convert to an object
}
function solution() {
if(valuesReturned) {
// make your stuff
// valuesReturned.mean
// valuesReturned.mini
// valuesReturned.maxi
}
}
EDIt
For searchm() function
function searchm() {
if(event.keyCode == 13) {
var values = calcMean();
var inans= values.mini;
return inans;
}
}
Declare a new array in calcMean function and push all mean , mini , maxi
value in new array. And get these value in solution like this :
var myNumArray = randomArray(6,0,99);
var numarr=new Array();
function random_number(min,max) {
return (Math.round((max-min) * Math.random() + min));
}
function randomArray(num_elements,min,max) {
var nums = new Array;
for (var element=0; element<num_elements; element++) {
nums[element] = random_number(min,max);
}
document.getElementById("numbers").innerHTML=nums;
numarr= calcMean(nums);
}
function calcMean(nums) {
var num=0;
for (var i=0;i<nums.length;i++) {
num += parseFloat( nums[i], 6 );
}
var divide=num/nums.length;
var arr=new Array();
var mean=(parseInt(divide,10));
var maxi = Math.max.apply(Math,nums);
var mini = Math.min.apply(Math,nums);
arr.push(mean);
arr.push(maxi);
arr.push(mini);
return arr;
}
function searchm(ele) {
if(event.keyCode == 13) {
// alert(ele.value); // i get the value and put it on alert
var inans= ele.value;
return inans;
}
}
function comparing(mean,maxi,mini,inans) {
if(inans==mean){document.getElementById("explain").innerHTML= "correct"+","+inans+"," +maxi+","+mini;
}
}
function solution() {
alert(numarr[0]); //for mean value
alert(numarr[1]); // for maxi
alert(numarr[2]); // for maxi
}

Strange behaviour with loop in Javascript

I've got a table-like structure with text inputs in which I am trying to make an entire row to be removed with all their children, but first passing the values of cells up one by one
in the rows below to keep IDs numbering structure.
The table structure is like this:
<table cellpadding=0>
<tr id="myRow1">
<td id="#R1C1">
<input class="myCell">
</td>
<td id="#R1C2">
<input class="myCell">
</td>
<td id="#R1C3">
<input class="myCell">
</td>
<td id="#R1C4">
<input class="myCell">
</td>
</tr>
<tr id="myRow2">
<td id="#R2C1">
<input class="myCell">
</td>
<td id="#R2C2">
<input class="myCell">
</td>
<td id="#R2C3">
<input class="myCell">
</td>
<td id="#R2C4">
<input class="myCell">
</td>
</tr>
<!-- ...and so on. -->
</table>
Having this table, when some event is triggered,I make this code run:
var rows = 1; // This value is updated when adding/removing a line
//This code runs from any <tr> by event keyup
if (event.altKey) { // I define here all Alt+someKey actions.
// Getting position values
var currentId = $(this).attr('id');
var row = Number(currentId.split('C')[0].substring(1));
var column = Number(currentId.split('C')[1]);
var belowVal;
if (event.which == 66) { //Case Ctrl+B
// If not the last row, start looping
if (rows > row) {
var diff = rows - row;
// Iteration over rows below
for (var i = 0; i < diff; i++) {
// Iteration over each column
for (var c = 1; c <= 4; c++) {
// here I try to get the value from column below
belowVal = $('#R'+(row+1+i).toString() +
'C'+c.toString()).val();
$('#R'+(row+i).toString()+'C' +
c.toString()).find('.myCell').val(belowVal);
}
}
}
$('#myRow'+rows.toString()).empty();
$('#myRow'+rows.toString()).remove();
rows--;
}
}
It works fine for removing the last row, but, when trying to remove an upper row, the values of current row and the ones below become blank instead of moving up. I made this code for each row below to pass it's values to the upper row, but it isn't doing what I wanted.
Why is this happening? I couldn't figure it out.
The problem seem to be, that the ids you are using to access the values are not the ids of the input elements, but rather the ids of the containing table cells.
Here an approach, which doesnt use the ids, but relies on the nodes structure instead, code not tested:
if (event.which == 66) {
var currentrow = $(this);
var currentinputs = currentrow.find('input.myCell');
while(var nextrow = currentrow.next('tr')) {
var nextinputs = nextrow.find('input.myCell');
currentinputs.each(function(index,element){
element.val(nextinputs.get(index).val());
});
currentrow = nextrow;
currentinputs = nextinputs;
}
currentrow.remove();
}
RESOLVED
Thanks to #JHoffmann, I was able to resolve my problem like this:
for (var c = 1; c <= 4; c++) {
// here I try to get the value from column below
belowVal = $('#R'+(row+1+i).toString()+'C'+c.toString())
.find('.myCell').val();
$('#R'+(row+i).toString()+'C'+c.toString())
.find('.myCell').val(belowVal);
}
In the line that assigns a value to belowVal, I forgot to call the method .find('.myCell') before calling .val(). That was the mistake that caused my code to fail, as #JHoffmann commented in his answer.

Perform Sum of Multiple Textfields in array on runtime using javascript

I have multiple textfields with same name.
When someone types a number in one of textfield. It should show sum on runtime in Sum Textfield.
Can anyone help me with that?
I have this HTML:
<table width="400" border="1" cellspacing="0">
<tr>
<td colspan="2" align="center">
SUM:
<input type="text" name="sum" id="sum" /></td>
</tr>
<tr>
<td><input type="text" name="textfield" id="field_1" /></td>
<td><input type="text" name="textfield" id="field_2" /></td>
</tr>
<tr>
<td><input type="text" name="textfield" id="field_3" /></td>
<td><input type="text" name="textfield" id="field_4" /></td>
</tr>
</table>
Here is my Fiddle:
http://jsfiddle.net/36Yhe/1/
Using vanilla JavaScript you can do it like this:
(function () {
var textFields = document.getElementsByName('textfield');
sum = function() {
var sum = 0;
for (var i = 0; i < textFields.length; i++) {
var val = textFields[i].value;
if (parseFloat(val) == val) {
sum += parseFloat(val);
}
}
document.getElementById('sum').value = sum;
};
document.getElementById('sum-table').addEventListener("keyup", sum, false);
sum();
})();
JSFiddle
Also your element IDs should be unique where as the name can be the same. I have shown this in the above fiddle.
Edited, with updated fiddle, to include changes suggested by #bfontaine
Try this :
// selects all inputs but "#sum"
var inputs = $('input:not(#sum)');
// each time the user releases a key
inputs.keyup(function () {
var sum = 0;
// loops through every inputs
inputs.each(function () {
// parses input's value into a float
// if parsing fails uses 0 instead of NaN (NaN || 0)
sum += parseFloat($(this).val()) || 0;
});
// displays the result
$('#sum').val(sum);
});
Here is a demo : http://jsfiddle.net/wared/8K24v/.
Another (twisted) solution :
var inputs = $('input:not(#sum)');
inputs.keyup(function () {
$('#sum').val(new Function('return ' + inputs.map(function () {
return parseFloat($(this).val()) || 0;
}).get().join('+') + ';')());
});
And its (twisted) demo : http://jsfiddle.net/wared/sraV3/.
Let's unroll the twisted part :
inputs.map(...).get() : Turns a jQuery list of inputs into an array of numbers.
.join('+') : Turns the array of numbers into a string. Example : [1,2].join('+') gives "1+2".
new Function('return ...;')() : Creates a new function and executes it immediately. At this point we have something like : new Function('return 1+1+1+1;')() (evaluate this code into your browser console, the output is obviously the number 4).
Finally, the result of this function is passed to $('#sum').val(...).
Additional contents :
http://api.jquery.com/map/
http://api.jquery.com/get/
MDN : Array join method
MDN : Function (constructor)
MDN : parseFloat

Getting Value from html form with the same name attribute under Loop

I have a form which displays multiple rows from database with 4 columns. From these record I need to write a new value in 4th column and update database record. But whenever I try, only First Row value can be updated/read. But not the other rows!! This can be due to the same "name=redirection" as it is given to each from "for loop". So, how can I get the values from other rows too??
for (int i=0; i<domains.size(); i++) {
domainprops = (String[]) domains.get(i);
%>
<table cellspacing="0" cellpadding="10" border="0" class="tableview" width="100%">
<td width="150"><input type="text" id="domains" name="domains" value="<%=domainprops[0]%>"></td>
<td width="160"><input type="text" name="defaulturl" value="<%=domainprops[1]%>" size="30"></td>
<td width="160"><input type="text" name="redirecturl" value="<%=domainprops[2]%>" size="30"></td>
<td width="160"> <input type="text" id="redirection" name="redirection"></td>
<td align="right"><a href="javascript:win2('recordUpdate.jsp?domains=<%=domainprops[0]%>
')">[Update]</a></td>
</tr>
</table>
<% } %>
Javascript Code :
function win2(urlPath) {
var winl = (screen.width-200)/2;
var wint = (screen.height-100)/2;
var settings = 'height=100,width=200,directories=no,resizable=no,status=no,scrollbars=no,menubar=no,location=no,top=' + wint + ',left=' + winl;
var changeurls=document.getElementById("redirection").value;
urlPath+='&rdirect='+changeurls
editWin.focus();
}
An ID in the DOM is supposed to be unique. If any element in the DOM has an ID, it should not be shared by any other element.
What I would suggest doing is appending your loop counter on to the end of the ID. This will ensure that every element you create in the DOM has its own unique ID.
for (int i=0; i<domains.size(); i++) {
domainprops = (String[]) domains.get(i);
...
<input type="text" id="domains_<%= i %>" name="domains" value="<%=domainprops[0]%>">
...
<input type="text" id="redirection_<%= i %>" name="redirection"></td>
</tr>
</table>
}
Next, pass the loop counter to the win2 function call:
<td align="right"><a href="javascript:win2('recordUpdate.jsp?domains=<%=domainprops[0]%>
', <%= i %>)">[Update]</a></td>
Finally, adjust the function itself...
function win2(urlPath, loopID) {
...
var changeurls=document.getElementById("redirection_" + loopID).value;
urlPath+='&rdirect='+changeurls
...
}
EDIT: Please read the answer referring to having multiple elements with the same ID. You should not be using multiple of the same ID.
You could use Javascript to iterate over redirection form elements.
function loopThroughRedirection(form) {
var result = "";
for (var i = 0; i < form.elements.length; i++) {
if (form.elements[i].name == 'redirection') {
// Do something to retrieve the value of redirection
result += form.elements[i].value
}
}
return result;
}

Categories