1

I have this array which is named options_hotel, it has 2 arrays (but can have more depending on how many registries are fetched from DB)

both arrays have elements inside, such as ID, NOM & ADRESSE :

 Array(2)
0: {ID: "1", NOM: "Le messager", ADRESSE: "30 rue du messager"}
1: {ID: "2", NOM: "hydrargyre", ADRESSE: "12 avenue hydrargyre"}

I have a select where options will be created dynamically,

<h2 class="list-titre">Hôtels</h2>
<select id="new_hotel"><!-- --></select> 

Those options are created dynamically with javascript (& JQUERY), by getting NOM & ID from each hotel.

for(i=0; i<options_hotel.length; i++){
    $("#new_hotel").append(new Option(options_hotel[i]['NOM'],options_hotel[i]['ID'] ));
}

Finally I have an input for adresses:

<h2 class="list-titre">Adresse</h2>
<input id="new_adresse" type="text" name="new_adresse" required>

So i want #new_adresse element to have the value of ADRESSE (which is stored in options_hotel) corresponding to the value of #new_hotel.

For instance : if the value inside #new_hotel is 1 (and the text is Le messager), then i want inside #new_adresse : 30 rue du messager.

Thank you

4
  • What part of this are you having trouble with? Getting the selecte value of the dropdown? Searching for that in the ID properties of the array? Copying the ADRESSE property to #new_adresse? Commented Apr 17, 2021 at 16:22
  • See stackoverflow.com/questions/20195958/… for finding an object by property value Commented Apr 17, 2021 at 16:23
  • @Barmar its copying the ADRESS property to #new_adresse which is the problem Commented Apr 17, 2021 at 16:25
  • $("#new_adresse").val(obj.ADRESSE) where obj is the found object. Commented Apr 17, 2021 at 16:27

1 Answer 1

1

I actually transformed your original array into an object (using .reduce()), as this will make it easier to find the corresponding sub-object with the .ADRESSE attribute.

I also took the liberty of slightly rewriting your select-filling part and combining it with the change-event handling function. The repeated .append() operation is replaced by a single .html() call that applies some prepared HTML code to the select element. In this little example it will not make the slightest difference, but, generally speaking, repeated .append() operations can slow down the user experience, as each one of them requires a rebuild of the DOM in the browser.

const options_hotel=[
 {ID: "1", NOM: "Le messager", ADRESSE: "30 rue du messager"},
 {ID: "2", NOM: "hydrargyre", ADRESSE: "12 avenue hydrargyre"},
 {ID: "5", NOM: "The Four Seasons", ADRESSE: "5 avenue du président"}]
 .reduce((a,c)=>(a[c.ID]=c,a),{} );
 
 const options3=[
 {ID: "8", NOM: "Le foudroyant", ADRESSE: "76 rue de Zeus"},
 {ID: "9", NOM: "Leclair", ADRESSE: "23 rue de Zeus"},
 {ID: "14", NOM: "The Five Seasons", ADRESSE: "15 avenue de la nation"}] 
 .reduce((a,c)=>(a[c.ID]=c,a),{} );

$.fn.hotelAdresse=function(opts,inpSel){ // made a plugin to avoid repetition ...
 this  // this is the jQuery element referencing a single <select> element
  .html(Object.values(opts).map(h=>new Option(h.NOM,h.ID).outerHTML).join(""))
  .change(function(){$(inpSel).val(opts[this.value].ADRESSE)})
  .change();  // show the ADRESSE for the initially chosen option ...
}
$("#new_hotel").hotelAdresse(options_hotel,"#new_adresse");
$("#newer_hotel").hotelAdresse(options_hotel,"#newer_adresse");
$("#hotel3").hotelAdresse(options3,"#adresse3");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2 class="list-titre">Hôtels 1</h2>
<select id="new_hotel"></select> Adresse 
<input id="new_adresse" type="text" name="new_adresse" required>
<h2 class="list-titre">Hôtels 2 (same data as Hôtels 1)</h2>
<select id="newer_hotel"></select> Adresse 
<input id="newer_adresse" type="text" name="newer_adresse" required>
<h2 class="list-titre">Hôtels 3 (different data object)</h2>
<select id="hotel3"></select> Adresse 
<input id="adresse3" type="text" name="adresse3" required>

Instead of applying the .reduce() function to an array you can of course start out with an object like

options_hotel=
{
  "1": {
    "ID": "1",
    "NOM": "Le messager",
    "ADRESSE": "30 rue du messager"
  },
  "2": {
    "ID": "2",
    "NOM": "hydrargyre",
    "ADRESSE": "12 avenue hydrargyre"
  },
  "5": {
    "ID": "5",
    "NOM": "The Four Seasons",
    "ADRESSE": "5 avenue du président"
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

this is exactly what i need, but i don't understand what is happening, for instance why are you applying .reduce to the array?
With .reduce I create an object (or "hash") in which I can directly search a particular sub-object with a key (ID) . In my example code I added another select element with ID=5. This can be found directly in the object without having to loop through it. The lookup happens in the change function: options_hotel[this.value].ADRESSE.
However, this does not work if i have multiple options_hotel containing different values in them (Script.js:162 Uncaught TypeError: Cannot read property 'ADRESSE' of undefined. Because whenever i change the options_hotel the reduce works but the text inside #new_adresse does not change
Could you add the case to your question please? I have not yet understood exactly whether you are talking about multiple select elements or multiple options_hotel objects and in which situation exactly you encounter the error you wrote about.
Yes it's about muliple options_hotel for instance : Array(2) 0: {ID: "8", NOM: "Le foudroyant", ADRESSE: "76 rue de Zeus"} 1: {ID: "9", NOM: "Leclair", ADRESSE: "23 rue de Zeus"}
|

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.