Hello all!

I have a little problem with a form. I'm searching for a way to make a dropdown change the value of either another dropdown or text field when selecting a value in the first dropdown.

But it's not just taking the value from 1 to 2. Here's what I need.

I have a dropdown with a long list of countries. All these countries can be selected from a MySQL database. In the very same table in the database is a field called Suffix which contains phone suffix for the country. For example Denmark will have +45 as Suffix. Sweden has +46. Norway +47. Germany +49. The United States +1 and so on.

I would like the 2nd dropdown (or field) to give me the suffix for the chosen country in the 1st dropdown.

How do I do that?

    This is one way of doing it, probably not the best as my JavaScript skills are minimal to say the least.

    <script type="text/javascript">
    // Funtion to create text display area
    function codeDisplay(){
    	if(para=='p'){
    		para.removeChild(txt);
    	}
    	var code = 'Country Code is: ';
    	code = code + document.getElementById("country").value;
    	var para = document.createElement("p");
    	var codeDiv = document.getElementById("codeDisplay");
    	codeDiv.appendChild(para);
    	var txt = document.createTextNode(code);
    	para.appendChild(txt);
    
    }
    // Function to remove text area, needed or codeDisplay() will just append more areas until page is refreshed
    function removeChildNodes(ctrl)
    {
      while (ctrl.childNodes[0])
      {
        ctrl.removeChild(ctrl.childNodes[0]);
      }
    }
    function removeElement() {
    	var ctrl;
    	ctrl = document.getElementById('codeDisplay');
    	removeChildNodes(ctrl);
    
    }
    </script>
    
    <?php
    define(LINE, "\n");
    /* Create array for countries and codes*/
    $country = array('Select'=>'','Denmark' => 45, 'Sweden' =>46, 'Norway' =>47, 'Germany'=> 49,'USA' =>1);
    
    /*Create dynamic dropdown select box*/
    $dd = '<select id="country" name="country" onchange="removeElement()">'.LINE;
    foreach ($country as $key => $value) {
    
    $dd .= '<option value="'.$value.'">'.$key.'</option>'.LINE;
    
    }
    
    $dd .= '</select>';
    
    /* Print out dropdown box and surrounding form elements*/
    print '<form name="codeChange">';
    echo $dd;
    print '<input type="button" name="button" value="Get Dialling Code" onclick="codeDisplay()">';
    print '</form>';
    ?>
    
    <!-- div for displaying code-->
    <div id="codeDisplay"></div>
    

      Or, if you go with two select boxes

      <select id="country" onchange="setIndex(this, 'prefix')">
      	<option>Denmark</option>
      	<option>Sweden</option>
      </select>
      <select id="prefix" onchange="setIndex(this, 'country')">
      	<option>45</option>
      	<option>46</option>
      </select>
      function setIndex(o, id) {
      	document.getElementById(id).selectedIndex = o.selectedIndex;
      }
      

        johanafm: It seems to work very fine with your solution. Although I have one little problem.

        In the MySQL database - I have some countries that doesn't have a prefix at all. I can, of course, easily exclude those from ever being shown as they are very unlikely to ever be used.
        BUT USA and Canada has the same prefix (+1) which will be a little problem if the user wants to select the prefix on his own. Then I would have the same value in the dropdown twice which doesn't look good.

        Is there a way to show the prefix the same way you just did but also put the prefix value in a hidden text field which can be sent to the form? That way I can disable the dropdown from ever being edited and the user will get the output, he needs when chosing the country.

          Show it "the same way I did"? Do you mean in a disabled select box? If so, then sure you can.

          function showPrefix(o) {
          	var d = document;
          	var sPref = d.getElementById('prefix');
          	sPref.selectedIndex = o.selectedIndex;
          
          d.getElementById('hiddenPrefix').value = sPref.value;
          }
          

          But having a disabled control that can't ever be enabled seems counterintuitive to me. I'd go with rincewind's suggestion on how to display the prefix. If you don't like his approach of having <option value="[prefix]">[country]</option>, you can of course combine the code in this post with his.

          If you don't like the extra button click

          '<select id="country" name="country" onchange="codeDisplay()">'
          var codeDiv = document.getElementById("codeDisplay");
          removeChildNodes(codeDiv);			// Add this line here
          codeDiv.appendChild(para); 
          

          And then you can also remove the function removeElement.

          Furthermore, this piece of code always evaluates to false, so it can be removed

           if(para=='p'){
                  para.removeChild(txt);
              }

          And finally, to avoid "Country code is: " (when "Select" is selected)

          var codeDiv = document.getElementById("codeDisplay");
          removeChildNodes(codeDiv);
          
          if (document.getElementById('country').selectedIndex == 0)
          	return;
          
          codeDiv.appendChild(para);

            I have nothing against using the <option value="[prefix]">[country]</option> in the code. I can easily get the right country in the database anyway.

            I just want the most easy way to have the 'country' select add the value (prefix) in the second select.

            I tried combining the codes you mentioned, but it doesn't work. It seems that the function "codeDisplay" doesn't say anywhere that it needs to take the value from the 'country' select and put it in the 'prefix' select.

            Is that a minor addition, you think?

              Well, if you can use the value field for prefix, there is no need for the other select at all, since you won't let users select a prefix if I've understood you correctly. And that's why I recommended you go with rincewind's code, which does not use a second select, but rather creates an ordinary text node.
              Also, if you keep the prefix value in the select, this is what will be sent to the server. What you'd need a hidden field for would be the country name, since you can't lookup country name by prefix.

                6 days later

                Alright - I decided to drop the select dropdown and go with the solution rincewind made. I also went with your suggestions to avoid the button. Everything seems to work fine.

                There is one more thing though that I need!

                I need the <div class="codeDisplay();"></div> to be shown 2 times on the page.

                1. Next to the phone number
                2. Next to the fax number

                I'm no javascript wizard, so I don't know what needs to be added for this to work. Can you help with that?

                  Just add another div

                  <script type="text/javascript">
                  // Funtion to create text display area
                  function codeDisplay(){
                      if(para=='p'){
                          para.removeChild(txt);
                      }
                      var code = 'Country Code is: ';
                      code = code + document.getElementById("country").value;
                      var para = document.createElement("p");
                      var phoneDiv = document.getElementById("phoneDisplay");
                      removeChildNodes(phoneDiv);
                      phoneDiv.appendChild(para);
                      var txt = document.createTextNode(code);
                      para.appendChild(txt);
                      var faxDiv = document.getElementById("faxDisplay");
                      removeChildNodes(faxDiv);
                      faxDiv.appendChild(para);
                      var txt = document.createTextNode(code);
                      para.appendChild(txt);
                  
                  }
                  // Function to remove text area, needed or codeDisplay() will just append more areas until page is refreshed
                  function removeChildNodes(ctrl)
                  {
                    while (ctrl.childNodes[0])
                    {
                      ctrl.removeChild(ctrl.childNodes[0]);
                    }
                  }
                  </script>
                  
                  <?php
                  define(LINE, "\n");
                  /* Create array for countries and codes*/
                  $country = array('Select'=>'','Denmark' => 45, 'Sweden' =>46, 'Norway' =>47, 'Germany'=> 49,'USA' =>1);
                  
                  /*Create dynamic dropdown select box*/
                  $dd = '<select id="country" name="country" onchange="codeDisplay()">'.LINE;
                  foreach ($country as $key => $value) {
                  
                  $dd .= '<option value="'.$value.'">'.$key.'</option>'.LINE;
                  
                  }
                  
                  $dd .= '</select>';
                  
                  /* Print out dropdown box and surrounding form elements*/
                  print '<form name="codeChange">';
                  echo $dd;
                  
                  print '</form>';
                  ?>
                  
                  <!-- div for displaying code-->
                  <div id="phoneDisplay"></div>
                  
                  <div id="faxDisplay"></div>

                    Hello rincewind

                    That seems to do the trick. One problem though ... the script creates 2 displays, but they end up right beside eachother like this:

                    Country Code is: +45Country Code is: +45

                    I would have loved it if I could have possible to have the 2 different displays like this:

                    +45 phone number text field

                    +45 fax number text field

                    which will be inside a <table>

                      para.appendChild(txt);
                      para.appendChild(document.createElement('br'));
                      var faxDiv = document.getElementById("faxDisplay");
                      

                        Oh - I would just have thought that since there were two different <div>'s that I could just put the <div class="phoneDisplay"></div> one place and the <div class="faxDisplay"></div> another place ... but it seems that both values end up in the <div class="faxDisplay"></div> ... and no value in the phoneDisplay at all.

                        Here's the HTML/PHP that I have:

                        <tr>
                          <td style="padding-top: 4px;" class="sm_txt">&nbsp;<b>Country</b>:</td>
                          <td style="padding-top: 4px;" class="sm_txt"><select class="form" name="supplierCountry" style="width: 300px;" onchange="codeDisplay()">
                          <option value="">- Country -</option>
                          <?
                          $query = "select * from lande where prefix <> '' order by name_uk asc";
                          $result = mysql_query($query) or die("".mysql_errno()." Error: ".mysql_error());
                        
                          if ($result && mysql_num_rows($result) > 0)
                          {
                            while($row = mysql_fetch_array($result))
                            {
                              $name_uk = $row['name_uk'];
                              $prefix = $row['prefix'];
                          ?>
                          <option <? if($supplierCountry == $prefix) { echo "SELECTED "; } ?> value="<?= $prefix ?>"><?= $name_uk ?></option>
                          <?
                          }
                        }
                        ?>
                          </select> &nbsp;<span class="red">*</span></td>
                        </tr>
                        <tr>
                          <td style="padding-top: 4px;" class="sm_txt">&nbsp;<b>Telephone No.</b>:</td>
                          <td style="padding-top: 4px;" class="sm_txt">
                            <table width="100%" cellspacing="0" cellpadding="0" border="0">
                              <tr>
                                <td valign="top" width="48" class="sm_txt"><div id="phoneDisplay"></div></td>
                                <td valign="top" width="362" class="sm_txt"><input type="text" name="supplierPhone" value="<?= $supplierPhone ?>" style="width: 252px;" class="form"> &nbsp;<span class="red">*</span></td>
                              </tr>
                            </table>
                          </td>
                        </tr>
                        <tr>
                          <td style="padding-top: 4px;" class="sm_txt">&nbsp;<b>Fax No.</b>:</td>
                          <td style="padding-top: 4px;" class="sm_txt">
                            <table width="100%" cellspacing="0" cellpadding="0" border="0">
                              <tr>
                                <td valign="top" width="48" class="sm_txt"><div id="faxDisplay"></div></td>
                                <td valign="top" width="362"><input type="text" name="supplierFax" value="<?= $supplierFax ?>" style="width: 252px;" class="form"></td>
                              </tr>
                            </table>
                          </td>
                        </tr>

                          Just replace the javascript codeDisplay() function with this one

                          function codeDisplay(){
                              if(para=='p'){
                                  para.removeChild(txt);
                              }
                              var code = 'Country Code is: ';
                              code = code + document.getElementById("country").value;
                              var para = document.createElement("p");
                              var phoneDiv = document.getElementById("phoneDisplay");
                              removeChildNodes(phoneDiv);
                              phoneDiv.appendChild(para);
                              var txt = document.createTextNode(code);
                              para.appendChild(txt);
                              para.appendChild(document.createElement('br'));
                              para.appendChild(document.createElement('br'));
                              var faxDiv = document.getElementById("faxDisplay");
                              removeChildNodes(faxDiv);
                              faxDiv.appendChild(para);
                              var txt = document.createTextNode(code);
                              para.appendChild(txt);
                          
                          }
                          

                            Well - it actually just puts in a few breaks between the two values and doesn't really take into consideration how I set up my <table>

                            But if that's the only solution there is, I guess I just have to find another way to set up the Phone and Fax text fields and such, so the form will both look good and have the right functionality that it requires.

                            Thanks anyway - both of you - it has helped a lot!

                              Without checking too deeply, but the way I set it up in the first place was so that you had a div that could be placed anywhere you wanted in the page, I haven't got time today to check if the latest version does the same but in theory it should.

                              So you could place phone div in one table cell and fax div in another, as I said I'm no Javascript expert, but I'm fairly sure that if you want to play around with the script you could have the value appear in a td cell as long as it is named correctly.

                                The problem is that the same p element is inserted in two different places

                                // first time
                                phoneDiv.appendChild(para);
                                
                                // para = document.createElement('p') here should solve this
                                
                                var txt = document.createTextNode(code);
                                para.appendChild(txt);
                                para.appendChild(document.createElement('br'));
                                para.appendChild(document.createElement('br'));
                                var faxDiv = document.getElementById("faxDisplay");
                                removeChildNodes(faxDiv);
                                
                                // second time, using the same element.
                                faxDiv.appendChild(para);
                                

                                As for where in your page the info appears is entirely up to you. If you get a td node and use appendChild on it, that td node will get the content. And wether you wrap the fax or phone info in a p element or not doesn't matter. You could just

                                var d = document;
                                var td = d.getElementById('some_td');	// or some other way of finding a td...
                                
                                td.appendChild(d.createTextNode(code));
                                

                                  The problem is that the same p element is inserted in two different places

                                  Why is that a problem when he wants the same data to appear in two places?

                                    I must say that I really appreciate the effort the both of you put into this. I really do.

                                    Yesterday afternoon I got to talking with my best friend who happens to be a really good programmer, and I slipped the issue to him hoping he might know how to solve the problem. He gave me this short javascript code:

                                    <script type="text/javascript"> 
                                    function codeDisplay(which) {
                                        document.getElementById('phoneDisplay').innerHTML = document.getElementById('faxDisplay').innerHTML = which.value;
                                    }
                                    </script>

                                    In the select I then made an - onchange="codeDisplay(this)"

                                    phoneDisplay and faxDisplay was then just inserted in the <td> like this:

                                    <td id="phoneDisplay">
                                    <td id="faxDisplay">

                                    That works perfect and just how I want it to work. I just thought you'd all like to know that.

                                    Thank you again for your efforts! I really appreciate it.

                                      rincewind456;10930267 wrote:

                                      Why is that a problem when he wants the same data to appear in two places?

                                      I thought he wanted phone in one place and fax in the other. But it's still a problem since a node will only exist in one place. Before appending the paragraph a second time yYou'd need

                                      var para2 = para.cloneNode(true);
                                      faxDiv.appendChild(para2);

                                      As for innerHTML, I generally stay as far away from it as possible. It doesn't work for a lot of things.

                                        johanafm;10930308 wrote:

                                        I thought he wanted phone in one place and fax in the other. But it's still a problem since a node will only exist in one place. Before appending the paragraph a second time yYou'd need

                                        var para2 = para.cloneNode(true);
                                        faxDiv.appendChild(para2);

                                        Sorry but that's incorrect as the code I gave did write to two different places, it may not be the right way, and if that's what you had said I wouldn't dispute it, but it does work.

                                        As for innerHTML, I generally stay as far away from it as possible. It doesn't work for a lot of things

                                        I agree with you here as by using innerhtml, which is not supported by all browsers, you risk cutting off a good proportion of the browsers out there. I think the OP should think twice about doing that.