Traverse a table using jQuery, XML, JSON, JS

Sorry for the misleading title but I'm unsure how else to write it.

I have the below table...

在这里输入图像描述

I want to produce a simple calculator that compares all data in a row from 2 given parameters.

I will ask my users to select a country first, and then select a value in that column. After doing this you can submit the form and it would output the correct values from that given row...

I've made a fiddle to try and show what I mean...

http://jsfiddle.net/SLCaN/2/

What is the best way to do this? The only way I am aware of is by having a huge if/else statement which will take me forever to write.

$('.country').on('change', function(){
// If USA show corrent dropdown
if( $(this).val() == 'usa'){
    $('.hiddenGrade').hide();
    $('.iniValusa').show();
} else if( $(this).val() == 'gb'){
    $('.hiddenGrade').hide();
    $('.iniValgb').show();
} else {
    $('.hiddenGrade').hide();
    $('.iniValfr').show();
}
});

$('input[type="submit"]').on('click', function(e){
    e.preventDefault();
    $('p').text('Values output here');
});

If you select French and 5a+ you would get 5.8 and V-Diff in the output...


There are definitely different ways to do this, but it seems to me that it comes down to the data structure. My personal take is to go with a data structure that has an array of countries with grades. The grades would then actually be pairs (display value/actual value) to account for the gaps in the data. The trick here is that we don't want to display empty display values in the select, but we do need data (in actual value) for conversion. After that, the jQuery stuff is pretty easy.

Data like this:

var countryGrades = [
    { country : "France", grades : [ 
        ["4", "4"], 
        ["", "4"], 
        ["5a", "5a"], 
        ["5a+", "5a+"], 
        ["5b", "5b"],
        ["5b+", "5b+"], 
        ["5c", "5c"],
        ["5c+", "5c+"],
        ["6a", "6a"],
        ["6a+", "6a+"],
        ["6b", "6b"] 
    ]},
    { country : "USA", grades : [ 
        ["5.6", "5.6"], 
        ["", "5.6"], 
        ["5.7", "5.7"], 
        ["", "5.7"], 
        ["5.8", "5.8"], 
        ["", "5.8"], 
        ["5.9", "5.9"], 
        ["5.10a", "5.10a"], 
        ["5.10b", "5.10b"], 
        ["5.10c", "5.10c"], 
        ["5.10d", "5.10d"]
    ]},
    { country : "UK", grades : [ 
        ["", ""], 
        ["Mod", "Mod"], 
        ["Diff", "Diff"], 
        ["V-Diff", "V-Diff"], 
        ["4a", "4a"], 
        ["4b", "4b"], 
        ["4b VS", "4b VS"], 
        ["4c HVS", "4c HVS"], 
        ["5a E1", "5a E1"], 
        ["", ""], 
        ["", ""]
    ]}
];

Event handling, etc. like this:

function loadGrades(countryGradesIndex) {
    var gradeSelect = $("#grade");
    gradeSelect.empty();        
    $.each(countryGrades[countryGradesIndex].grades, function(index, grade) {
        if (grade[0] != "") {
            gradeSelect.append($("<option></option>").attr("value", index).text(grade[0]));
        }           
    });
}

$.each(countryGrades, function(index, countryGrade) {       
    $("#country").append($("<option></option>").attr("value", index).text(countryGrade.country));
});

$("#country").on("change", function() {
    loadGrades($("#country").val());
});

loadGrades(0);

$("#convert").on("click", function() {
    var gradeIndex = $("#grade").val();
    var gradeConversion = "";
    $.each(countryGrades, function(countryGradesIndex) {
        gradeConversion += countryGrades[countryGradesIndex].country + ": " + countryGrades[countryGradesIndex].grades[gradeIndex][1] + "<br>";
    });

    $("#conversions").html(gradeConversion);
});

Check out a working JSFiddle here: http://jsfiddle.net/tetonraven/SVj63/


Iserni's Answer is really close to what you need, I think they missed the output portion though unless I'm reading/understanding the code incorrectly.

To adapt that answer a bit I would change the data structure to be:

var grades = [
{'fr': "4", 'usa': "5.6",'gb': ""},
{'fr': "4", 'usa': "5.6",'gb': "Mod"},
{'fr': "5a",    'usa': "5.7",'gb': "Diff"},
{'fr': "5a+",   'usa': "5.7",'gb': "V-Diff"},
{'fr': "5b",    'usa': "5.8",'gb': "4a"},
{'fr': "5b+",   'usa': "5.8",'gb': "4b"},
{'fr': "5c",    'usa': "5.9",'gb': "4b VS"},
{'fr': "5c+",   'usa': "5.10a",'gb': "4c HVS"},
{'fr': "6a",    'usa': "5.10b",'gb': "5a E1"},
{'fr': "6a+",   'usa': "5.10c",'gb': ""},
{'fr': "6b",    'usa': "5.10d",'gb': ""}];

Then in your click event something like this will get you to translated values (you will need to adapt it a bit)

$('input[type="submit"]').on('click', function(e){
   e.preventDefault();
   var matches = $.grep(grades,function(e) {
     return e[$(".country").val()] == $('.iniValusa').val()
   });

   if(matches.length == 1)
   {
     $('p').text('USA: ' + matches[0].usa + ' GB: ' + matches[0].gb + 'FR: ' + matches[0].fr);
   } 
});

crush's solution seems to me the most practical. You define the data in a single variable, then use it to populate both SELECTs. However, consider that Michael's solution can be adapted to degrade better: my take on crush's solution, if Javascript were disabled, would get you an empty page.

You keep all the data in a Javascript object, and the values are indexed so that equal grades have equal indexes (the row numbers in your table):

 4: "quatrième valeur pour les français",
 ...
 4: "Fourth value for UK",

This approach allows to "translate" more easily (I believe) one array into the other, ie you select France, get grade 5b, change France to US: the value stays the same, which means that the displayed grade changes to the corresponding value in the new country.

Also, you keep all your data in a single place.

For large country arrays, I'd suggest to convert the grades[countryCode] into an AJAX call to fetch that particular country from the server. You'd also need another AJAX call to only fetch the codes from the server.

  var grades = {
    fr: {
        name: 'France',
        values: {
            0: "4",
            1: "4",
            2: "5a",
            3: "5a+",
            4: "5b",
            5: "5b+",
            6: "5c",
            7: "5c+",
            8: "6a",
            9: "6a+",
           10: "6b"
        }
     },
 us:    {
        name: 'USA',
        values: {
            0: "5.6",
            1: "5.6",
            2: "5.7",
            3: "5.7",
            4: "5.8",
            5: "5.8",
            6: "5.9",
            7: "5.10a",
            8: "5.10b",
            9: "5.10c",
           10: "5.10d"
        }
    },
'gb': {
        name: 'UK',
        values: {
            0: "",
            1: "Mod",
            2: "Diff",
            3: "V-Diff",
            4: "4a",
            5: "4b",
            6: "4b VS",
            7: "4c HVS",
            8: "5a E1",
            9: "",
           10: ""
        }
  }
}


  function setSelectTo(country) {
      // TODO: verify that country is indeed in grades
      var data = grades[country].values;
      var $el = $("#gradeSelect");
      $cur = $el.val();
      $el.empty();
      $.each(data, function(value, text) {
          $el
             .append($("<option></option>")
             .attr("value", value)
             .text(text));
      });
      // Restore value
      $el.val($cur);
  }
  function populateCountrySelect() {
      var $el = $("#countrySelect");
      $el.empty();

      $.each(grades, function(code, data) {
          $el
             .append($("<option></option>")
             .attr("value", code)
             .text(data.name));
      });
  }

  $('#countrySelect').on('change', function(){
      setSelectTo($(this).val());
  });

  populateCountrySelect();
  $('#countrySelect').val('us');
  setSelectTo('us');
  $('#gradeSelect').val(2);

This is an updated sample fiddle - sorry, the first URL was wrong - and the HTML is very minimal:

Choose your country: <select id="countrySelect"></select>
<br />
Choose your grade: <select id="gradeSelect"></select>            
链接地址: http://www.djcxy.com/p/19170.html

上一篇: 什么是好的浏览器

下一篇: 使用jQuery,XML,JSON,JS遍历一个表