2008-10-07 3 views
23

En utilisant les réponses à this question, j'ai pu remplir une zone de sélection en fonction de la sélection d'une autre zone de sélection. (I posted my answer here) Extraction des données d'une structure de tableau construite côté serveur, stockée dans un fichier .js et référencée dans la page html.Utilisation de javascript et de jquery pour remplir les zones de sélection associées avec la structure de tableau

Maintenant, je voudrais ajouter une troisième boîte de sélection. Si j'avais 3 ensembles de données (modèle, la marque, options) quelque chose comme ceci (code de pseudo):

cars : [Honda[Accord[Lx, Dx]], [Civic[2dr, Hatchback]], 
    [Toyota[Camry[Blk, Red]], [Prius[2dr,4dr]] 

Ex: Si Honda ont été sélectionnés, la prochaine zone de sélection aurait [Accord civique] et si Accord étaient sélectionné la prochaine boîte de sélection aurait [Lx Dx]

Comment puis-je

1) créer une structure de tableau pour contenir les données? de telle sorte que

2) Je peux utiliser la valeur d'une boîte de sélection pour référencer les valeurs nécessaires pour la prochaine boîte de sélection

Merci

EDIT

Je peux créer ce qui suit, mais ne peut pas trouver les références d'une manière qui aiderait à remplir une boîte de sélection

var cars = [ 
{"makes" : "Honda", 
    "models" : [ 
    {'Accord' : ["2dr","4dr"]} , 
    {'CRV' : ["2dr","Hatchback"]} , 
    {'Pilot': ["base","superDuper"] } ] 
}, 
{"makes" :"Toyota", 
    "models" : [ 
    {'Prius' : ["green","reallyGreen"]} , 
    {'Camry' : ["sporty","square"]} , 
    {'Corolla' : ["cheap","superFly"] } ] 
} ] ;    

alert(cars[0].models[0].Accord[0]); ---> 2dr 

Répondre

45

Je préfère la structure de données comme ceci:

var carMakers = [ 
    { name: 'Honda', models: [ 
      { name: 'Accord', features: ['2dr', '4dr'] }, 
      { name: 'CRV', features: ['2dr', 'Hatchback'] }, 
      { name: 'Pilot', features: ['base', 'superDuper'] } 
     ]}, 

    { name: 'Toyota', models: [ 
      { name: 'Prius', features: ['green', 'superGreen'] }, 
      { name: 'Camry', features: ['sporty', 'square'] }, 
      { name: 'Corolla', features: ['cheap', 'superFly'] } 
     ]} 
]; 

Étant donné les trois listes de sélection avec id: « maker », « modèle » et « caractéristiques », vous pouvez les manipuler avec cela (je crois que c'est assez explication):

// returns array of elements whose 'prop' property is 'value' 
function filterByProperty(arr, prop, value) { 
    return $.grep(arr, function (item) { return item[prop] == value }); 
} 

// populates select list from array of items given as objects: { name: 'text', value: 'value' } 
function populateSelect(el, items) { 
    el.options.length = 0; 
    if (items.length > 0) 
     el.options[0] = new Option('please select', ''); 

    $.each(items, function() { 
     el.options[el.options.length] = new Option(this.name, this.value); 
    }); 
} 

// initialization 
$(document).ready(function() { 
    // populating 1st select list 
    populateSelect($('#maker').get(0), $.map(carMakers, function(maker) { return { name: maker.name, value: maker.name} })); 

    // populating 2nd select list 
    $('#maker').bind('change', function() { 
     var makerName = this.value, 
      carMaker = filterByProperty(carMakers, 'name', makerName), 
      models = []; 

     if (carMaker.length > 0) 
      models = $.map(carMaker[0].models, function(model) { return { name: model.name, value: makerName + '.' + model.name} }); 

     populateSelect($('#model').get(0), models); 
     $('#model').trigger('change'); 
    }); 

    // populating 3rd select list 
    $('#model').bind('change', function() { 
     var nameAndModel = this.value.split('.'), 
      features = []; 

     if (2 == nameAndModel.length) { 
      var makerName = nameAndModel[0], 
       carModel = nameAndModel[1], 
       carMaker = filterByProperty(carMakers, 'name', makerName); 

      if (carMaker.length > 0) { 
       var model = filterByProperty(carMaker[0].models, 'name', carModel) 

       if (model.length > 0) 
        features = $.map(model[0].features, function(feature) { return { name: feature, value: makerName + '.' + carModel + '.' + feature} }) 
      } 
     } 

     populateSelect($('#feature').get(0), features); 
    }) 

    // alerting value on 3rd select list change 
    $('#feature').bind('change', function() { 
     if (this.value.length > 0) 
      alert(this.value); 
    }) 
}); 
+0

Merci pour l'effort que vous avez mis dans votre réponse. J'ai essayé votre code et cela a fonctionné, mais je n'ai pas le temps en ce moment pour savoir exactement comment cela fonctionne ... va y revenir later..but J'utilise la structure du tableau ... et je pense maintenant comprendre comment créer ces tableaux. Merci encore –

+0

La structure de données est en fait un objet Javascript. Vous trouverez ici un tutoriel JSON décent: http://www.hunlock.com/blogs/Mastering_JSON_%28_JavaScript_Object_Notation_%29 – BalusC

+1

aide .grep $ et .map $ pour c'est juste la course des maîtres. Solution fantastique, je l'ai juste utilisé comme base pour quelque chose de similaire et me sens comme un meilleur programmeur pour cela. solution Impressionnant. – hendrixski

1

Regarder here pour la manipulation de boîtes de sélection. Pour ce que vous voulez, je pense que JSON fera le bon travail pour vous. De toute façon, si j'étais vous, je ferai de cette façon: Lorsque je change d'abord sélectionner, je fais une requête ajax. Avec la réponse ajax, je remplirai la deuxième case. Idem pour la deuxième boîte et là vous avez la troisième boîte remplie avec des données correctes.

3

Merci à la réponse de @Marko Dunic, j'ai pu construire une structure tableau (données) qui peut être référencé pour remplir 3 boîtes de sélection. Je n'ai pas utilisé le code d'implémentation seulement parce que je ne l'ai pas complètement compris ... ça fonctionne comme posté. Je reviendrai sur ce code plus tard quand j'apprendrai jQuery. Mon code est affiché ci-dessous (évidemment, votre référence à jQuery peut être différent)

<html><head> 
<script language="Javascript" src="javascript/jquery-1.2.6.min.js"></script> 
<script type="text/JavaScript"> 
var cars = [ 
{ name: 'Honda', models: [ 
{ name: 'Accord', features: ['2dr', '4dr'] }, 
{ name: 'CRV', features: ['2dr', 'Hatchback'] }, 
{ name: 'Pilot', features: ['base', 'superDuper'] } 
    ]}, 
{ name: 'Toyota', models: [ 
{ name: 'Prius', features: ['green', 'superGreen'] }, 
{ name: 'Camry', features: ['sporty', 'square'] }, 
{ name: 'Corolla', features: ['cheap', 'superFly'] } 
    ] 
} 
]; 
$(function() { 
var options = '' ; 
for (var i = 0; i < cars.length; i++) { 
    var opt = cars[i].name ; 
    if (i == 0){ options += '<option selected value="' + opt + '">' + opt + '</option>'; } 
    else {options += '<option value="' + opt + '">' + opt + '</option>'; } 
} 
$("#maker").html(options); // populate select box with array 

var options = '' ; 
for (var i=0; i < cars[0].models.length; i++) { 
    var opt = cars[0].models[0].name ; 
    if (i==0){options += '<option selected value="' + opt + '">' + opt + '</option>';} 
    else {options += '<option value="' + opt + '">' + opt + '</option>';} 
} 
$("#model").html(options); // populate select box with array 

var options = '' ; 
for (var i=0; i < cars[0].models[0].features.length; i++) { 
    var opt = cars[0].models[0].features[i] ; 
    if (i==0){options += '<option selected value="' + opt + '">' + opt + '</option>';} 
    else {options += '<option value="' + opt + '">' + opt + '</option>';} 
} 
$("#feature").html(options); // populate select box with array 

$("#maker").bind("click", 
    function() { 
     $("#model").children().remove() ;  // clear select box 
     for(var i=0; i<cars.length; i++) { 
      if (cars[i].name == this.value) { 
       var options = '' ; 
       for (var j=0; j < cars[i].models.length; j++) { 
        var opt= cars[i].models[j].name ; 
        if (j==0) {options += '<option selected value="' + opt + '">' + opt + '</option>';} 
        else {options += '<option value="' + opt + '">' + opt + '</option>';} 
       } 
       break; 
      } 
     } 
     $("#model").html(options); // populate select box with array 

     $("#feature").children().remove() ;  // clear select box 
     for(var i=0; i<cars.length; i++) { 
      for(var j=0; j<cars[i].models.length; j++) { 
       if(cars[i].models[j].name == $("#model").val()) { 
        var options = '' ; 
        for (var k=0; k < cars[i].models[j].features.length; k++) { 
         var opt = cars[i].models[j].features[k] ; 
         if (k==0){options += '<option selected value="' + opt + '">' + opt + '</option>';} 
         else {options += '<option value="' + opt + '">' + opt + '</option>';} 
        } 
        break; 
       } 
      } 
     } 
     $("#feature").html(options); // populate select box with array 
    }); 

    $("#model").bind("click", 
     function() { 
      $("#feature").children().remove() ;  // clear select box 
      for(var i=0; i<cars.length; i++) { 
       for(var j=0; j<cars[i].models.length; j++) { 
        if(cars[i].models[j].name == this.value) { 
         var options = '' ; 
         for (var k=0; k < cars[i].models[j].features.length; k++) { 
          var opt = cars[i].models[j].features[k] ; 
          if (k==0){options += '<option selected value="' + opt + '">' + opt + '</option>';} 
          else {options += '<option value="' + opt + '">' + opt + '</option>';} 
         } 
         break ; 
        } 
       } 
      } 
      $("#feature").html(options); // populate select box with array 
    }); 
}); 
</script> 
</head> <body> 
<div id="selection"> 
<select id="maker"size="10" style="{width=75px}"></select> 
<select id="model" size="10" style="{width=75px}"></select> 
<select id="feature" size="10"style="{width=75px}"></select> 
</div></body></html> 
+0

+1 pour remplir un trou béant dans ma connaissance jQuery + JSON. Je vous remercie :) – Zoe

2

J'ai vraiment aimé la solution par @Marko Dunic, mais il n'a pas répondu à mes besoins pour fixer les ID des options. Une fois que j'ai joint les identifiants, j'ai réalisé que je pourrais rendre le code JS encore plus petit et plus simple. Ma solution est conçue lorsque les données proviennent d'une base de données relationnelle et que les données d'entrée JSON conservent la structure relationnelle avec les clés primaires/étrangères. Voici les données JSON:

<html lang="en"> 
    <head> 
    <title>Populate a select dropdown list with jQuery - WebDev Ingredients</title> 
    <script type="text/javascript" src="js/jquery-1.4.2.js"></script> 
    <script type="text/javascript"> 
     var types = [ 
      { typeID: 1, name: 'Domestic'}, 
      { typeID: 2, name: 'Import'}, 
      { typeID: 3, name: 'Boat'} 
     ] 
     var makes = [ 
      { typeID: 1, makeID: 1, name: 'Chevy'}, 
      { typeID: 1, makeID: 2, name: 'Ford'}, 
      { typeID: 1, makeID: 3, name: 'Delorean'}, 
      { typeID: 2, makeID: 4, name: 'Honda'}, 
      { typeID: 2, makeID: 5, name: 'Toyota'}, 
      { typeID: 2, makeID: 6, name: 'Saab'} 
     ]  
     var model = [ 
      { makeID: 1, modelID: 1, name: 'Camaro'}, 
      { makeID: 1, modelID: 2, name: 'Chevelle'}, 
      { makeID: 1, modelID: 3, name: 'Nova'}, 
      { makeID: 2, modelID: 4, name: 'Focus'}, 
      { makeID: 2, modelID: 5, name: 'Galaxie'}, 
      { makeID: 2, modelID: 6, name: 'Mustang'}, 
      { makeID: 4, modelID: 7, name: 'Accord'}, 
      { makeID: 4, modelID: 8, name: 'Civic'}, 
      { makeID: 4, modelID: 9, name: 'Odyssey'}, 
      { makeID: 5, modelID: 10, name: 'Camry'}, 
      { makeID: 5, modelID: 11, name: 'Corolla'} 
     ] 
     // 
     // Put this in a stand alone .js file 
     // 
     // returns array of elements whose 'prop' property is 'value' 
     function filterByProperty(arr, prop, value) { 
      return $.grep(arr, function (item) { return item[prop] == value }); 
     } 
     // populates select list from array of items given as objects: { name: 'text', value: 'value' } 
     function populateSelect(el, items) { 
      el.options.length = 0; 
      if (items.length > 0) 
       el.options[0] = new Option('please select', ''); 
      $.each(items, function() { 
       el.options[el.options.length] = new Option(this.name, this.value); 
      }); 
     } 
     // initialization 
     $(document).ready(function() { 
      // populating 1st select list 
      populateSelect($('#sType').get(0), $.map(types, function(type) { return { name: type.name, value: type.typeID} }));  
      // populating 2nd select list 
      $('#sType').bind('change', function() { 
       var theModels = filterByProperty(makes, 'typeID', this.value); 
       populateSelect($('#sMake').get(0), $.map(theModels, function(make) { return { name: make.name, value: make.makeID} })); 
       $('#sMake').trigger('change'); 
      }); 
      // populating 3nd select list 
      $('#sMake').bind('change', function() { 
       var theSeries = filterByProperty(model, 'makeID', this.value); 
       populateSelect($('#sModel').get(0), $.map(theSeries, function(model) { return { name: model.name, value: model.modelID} })); 
      }); 
     }); 
    </script> 
    </head> 
    <body> 
    Enter values, click submit, and look at the post parameters 
    <form method="get" action="index.php"> 
      <div id="selection"> 
       <select id="sType" name="type_id" style="{width=75px}"></select> 
       <select id="sMake" name="make_id" style="{width=75px}"></select> 
       <select id="sModel" name="model_id" style="{width=75px}"></select> 
      </div> 
      <input type="submit"> 
    </form> 
    </body> 
</html> 

Notez que ma solution déplace la fonctionnalité de sorte que Make-modèle sont les 2e et 3e zones de texte, et le type (national, importation, bateau, etc.) sont le 1er niveau.J'ai réduit la JS à 23 lignes (moins de commentaires) tout en conservant un bon formatage.

Les données JSON est très facile de rendre des requêtes SQL, qui sont mises en cache en Java sur les listes d'initialisation parce que le type Make-modèle changent rarement. Je ne pas utiliser AJAX dynamique, car cela complique l'architecture, et j'ai une liste relativement faible des valeurs disponibles, donc je viens de l'envoyer à la demande de page.

"Les solutions devraient être aussi simples que possible, mais pas plus simples" - A. Einstein

Questions connexes