0

I had ten rows which each rows contain 4 column, now I want to get the value which I had import using localStorage. I find a way to put all these value independently but the code is all the repeat one. These will cause to redundancy of code. I wonder if there are a way to shorten the code using loop?

Here is my code

 var res = {};
    $(function(){
     $('#subbtn').click(function() {
      console.log($('#tab').find('tr'))
      $('tr').each(function(){
          var tmp = [];
          var cl ;
          $(this).find('select').each(function(){
            cl = $(this).attr('class');
            //console.log(cl);
            tmp.push($(this).val());
          })

          res[cl] = tmp
      })
        console.log(res);
       localStorage.setItem("testingvalue",JSON.stringify(res));
       document.getElementById("results__display").innerHTML = (localStorage.getItem("testingvalue"));
     })

    })
    $( document ).ready(function(){
   var res = {};
   try { 
    console.log('existed');
      res = JSON.parse(localStorage.getItem("testingvalue"));

   //alert(res.r1[2]);
   document.getElementsByClassName("r1")[0].selectedIndex=res.r1[0];
   document.getElementsByClassName("r1")[1].selectedIndex=res.r1[1];
   document.getElementsByClassName("r1")[2].selectedIndex=res.r1[2];
   document.getElementsByClassName("r1")[3].selectedIndex=res.r1[3];

   document.getElementsByClassName("r2")[0].selectedIndex=res.r2[0];
   document.getElementsByClassName("r2")[1].selectedIndex=res.r2[1];
   document.getElementsByClassName("r2")[2].selectedIndex=res.r2[2];
   document.getElementsByClassName("r2")[3].selectedIndex=res.r2[3];

   document.getElementsByClassName("r3")[0].selectedIndex=res.r3[0];
   document.getElementsByClassName("r3")[1].selectedIndex=res.r3[1];
   document.getElementsByClassName("r3")[2].selectedIndex=res.r3[2];
   document.getElementsByClassName("r3")[3].selectedIndex=res.r3[3];

   document.getElementsByClassName("r4")[0].selectedIndex=res.r4[0];
   document.getElementsByClassName("r4")[1].selectedIndex=res.r4[1];
   document.getElementsByClassName("r4")[2].selectedIndex=res.r4[2];
   document.getElementsByClassName("r4")[3].selectedIndex=res.r4[3];

   document.getElementsByClassName("r5")[0].selectedIndex=res.r5[0];
   document.getElementsByClassName("r5")[1].selectedIndex=res.r5[1];
   document.getElementsByClassName("r5")[2].selectedIndex=res.r5[2];
   document.getElementsByClassName("r5")[3].selectedIndex=res.r5[3];

   document.getElementsByClassName("r6")[0].selectedIndex=res.r6[0];
   document.getElementsByClassName("r6")[1].selectedIndex=res.r6[1];
   document.getElementsByClassName("r6")[2].selectedIndex=res.r6[2];
   document.getElementsByClassName("r6")[3].selectedIndex=res.r6[3];

   document.getElementsByClassName("r7")[0].selectedIndex=res.r7[0];
   document.getElementsByClassName("r7")[1].selectedIndex=res.r7[1];
   document.getElementsByClassName("r7")[2].selectedIndex=res.r7[2];
   document.getElementsByClassName("r7")[3].selectedIndex=res.r7[3];

   document.getElementsByClassName("r8")[0].selectedIndex=res.r8[0];
   document.getElementsByClassName("r8")[1].selectedIndex=res.r8[1];
   document.getElementsByClassName("r8")[2].selectedIndex=res.r8[2];
   document.getElementsByClassName("r8")[3].selectedIndex=res.r8[3];

   document.getElementsByClassName("r9")[0].selectedIndex=res.r9[0];
   document.getElementsByClassName("r9")[1].selectedIndex=res.r9[1];
   document.getElementsByClassName("r9")[2].selectedIndex=res.r9[2];
   document.getElementsByClassName("r9")[3].selectedIndex=res.r9[3];

   document.getElementsByClassName("r10")[0].selectedIndex=res.r10[0];
   document.getElementsByClassName("r10")[1].selectedIndex=res.r10[1];
   document.getElementsByClassName("r10")[2].selectedIndex=res.r10[2];
   document.getElementsByClassName("r10")[3].selectedIndex=res.r10[3];

    } 

    catch (error){
       console.log(error.message);
   }


});
4
  • 1
    Use the fors, Loop Commented May 19, 2017 at 3:18
  • I don't know how to get the length of getElementsByClassName and the length inside getElementsByClassName . I means I had 10 row, and each row had 4 column. How do I get the column size so that I could use the for looop. Commented May 19, 2017 at 3:20
  • You can set them just like you've extracted them. Looping through all the rows and then all the select elements on those rows. In the select elements loop you could do something like this $(this).val(res[cl][$(this).index()]) Commented May 19, 2017 at 3:22
  • @Titus I was more understanding JavaScript than Jquery. Anyway thanks ya! I know they actually the same, but it just hard for me to understand Jquery :( Commented May 19, 2017 at 3:25

3 Answers 3

1

Looking at this repeated line:

document.getElementsByClassName("r1")[0].selectedIndex=res.r1[0];

...a simple first pass improvement would be to just use a nested for loop with variables instead of "r1" and 0:

for (var r = 1; r <= 10; r++) {
  for (var i = 0; i < 4; i++) {
    document.getElementsByClassName("r" + r)[i].selectedIndex = res["r" + r][i];
  }
}

Notice, though, that this means the .getElementsByClassName("r" + r) call happens four time for each value of r, which is not very efficient - it would be better to move that into the outer loop:

var els;
for (var r = 1; r <= 10; r++) {
  els = document.getElementsByClassName("r" + r);
  for (var i = 0; i < 4; i++) {
    els[i].selectedIndex = res["r" + r][i];
  }
}

In the second version the inner loop could say i < els.length rather than i < 4, although note that either way you need to be sure you match the number of HTML elements to the number of items in your res object.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm just going to edit to remove the repeated calls to .getElementsByClassName().
0

You've seem to have the jQuery library loaded. Using jQuery makes this much easier.

Here is an example:

var res = JSON.parse(localStorage.getItem("testingvalue"));
$("tr select").each(function(){
   $(this).val(res[$(this).attr("class")][$(this).index()]);
});

Of course, this will only work if the select elements have only one class name and the res object contains values for all the select elements that are inside tr elements. Based on the jQuery code in your question that seems to be the case.

And this is a safer approach

Object.keys(res).forEach(function(key){
    res[key].forEach(function(val, index){
        $("tr select." + key).eq(index).val(val);
    });
});

2 Comments

But what if I got 2 name in a class? Because I just get my updated code, and my class name was become two.
@Beginner You could use the second approach but I guess you will also have to change the jQuery code that creates the object you store in local storage. That code generates the object using $(this).attr("class") (all the class names) as a property.
0

Code below will work regardless the size of your data in storage:

res = JSON.parse(localStorage.getItem("testingvalue"));
  // Let's start with checking 'res' type.
  // - if it's an Array, get the the length from .length
  // - if it's Object, get the the length from Object.keys().length
  var resLength = Array.isArray(res) ? res.length : typeof res === 'object' ? Object.keys(res).length : 0;
  // loop throw the rows.
  for (var i = 0; i < resLength; i++) {
    // Do the same as above: get type of the row and calculate it length for the loop.
    var rowLength = Array.isArray(res[i]) ? res.length : typeof res[i] === 'object' ? Object.keys(res[i]).length : 0;
    // loop throw the columns on the row.
    for (var j = 0; j < rowLength; j++) {
      document.getElementsByClassName('r'+i)[j].selectedIndex=res['r'+i][j];
    }
}

5 Comments

At first I was planing to write like this also, but what I write can't get me the correct input. Thanks, but I try your code, it didn't work for me :(
res is an object not an array, the first loop's condition should be i < Object.keys(res).length and the second loop's condition j < res["r" + i].length
Ermm, still can't. But the Object.keys(res[i]).length) which the keys is I can put whatever name I like or is the default one?
@Beginner res is an object you need to call Object.keys only on res because res[...] is an array you can simply do this res[...].length no need for Object.keys(res[...]).
@Beginner, I missed j++ in the inner loop. I think it should work for you now (i've updated code). Also I refactored the approach how I calculate the length. But checking type of result you get (either Object or Array) and apply different approach to calculate the length. I think you can make it work from here...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.