Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

javascript - dynamically change contents of dropdown list

Options
  • 21-01-2007 3:21pm
    #1
    Closed Accounts Posts: 975 ✭✭✭


    My limited javascript savvy is letting me down. Having browsed through "teach yourself javascript in 24 hours" (it took an hour in case anybody's interested....) I'm still no closer to a solution.

    I have a site where I populate a dropdown list with countries and regions from mysql database with php. The countries are optgroups and the regions are options within the select tags. As you can imagine, the dropdown list is pretty big.

    I was hoping to pass the countries and regions to javascript, and have it dynamically populate a regions list when I selected a country from the country list. I think I'm okay with getting the data from php to javascript, but having dynamic content in the second dropdown list is the part that is confusing me.

    Anybody got a code snippet or know where I could find one I could adapt? Or maybe there's a better way - just don't say ASP...


Comments

  • Registered Users Posts: 32,136 ✭✭✭✭is_that_so


    http://www.plus2net.com/javascript_tutorial/dropdown-list.php.
    Plenty of other links out there. Search for "two drop down lists javascript".


  • Closed Accounts Posts: 975 ✭✭✭squibs


    At a glance that looks perfect. Thanks - I wasn't having much success with google.


  • Closed Accounts Posts: 1,200 ✭✭✭louie


    a better option is to use AJAX to populate the second menu. It doesn't put so much code in the page source as javascript.


  • Closed Accounts Posts: 18,163 ✭✭✭✭Liam Byrne


    Have a look at jQuery - it gives you an interface to AJAX without having to do all the work yourself.

    Explanation/tutorial:
    http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/

    Demo:
    http://remysharp.com/wp-content/uploads/2007/01/select.html


  • Closed Accounts Posts: 975 ✭✭✭squibs


    Sweet - thanks lads.


  • Advertisement
  • Registered Users Posts: 568 ✭✭✭phil


    Just to give my vote of support for JQuery - it's great!

    You really need to have a reasonable grip of javascript already though, the docs kinda assume a familiarity with the DOM.


  • Closed Accounts Posts: 975 ✭✭✭squibs


    I ended up going with the pure javacript solution - one step at a time and all that. So php pulls the countries and regions from the database and sends the info to the javascript which dynamically populates the region based on the country selected. And it worked.

    Then I got cocky....

    The search form appears on the search results page for the user to refine their search if they get too many results. I pass all the search parameters from page to page, but I needed to add to the javascript to remember what country/region was selected.

    I added a boolean value for selected to the addoption function. Here's the relevant bits of what I tried (which didnt work). There's no javascript errors but the addoption doesn't process the selected bit, I'm displaying the browser source as including the php code that generated much of it would confuse matters. I'm still getting to grips with client side stuff, so I'm not sure if it should work:

    Add a country:
    addOption(document.drop_list.Country, "France","France","",true);
    

    Add regions for the country:
    if(document.drop_list.Country.value == 'France')
    {
    addOption(document.drop_list.Region,"Alsace","Alsace",false);
    .
    .
    }
    

    The addOption function:
    function addOption(selectbox, value, text, selec )
    {    
    var optn = document.createElement("OPTION");    
    optn.text = text;    
    optn.value = value;       
    optn.selected=selec;    
    selectbox.options.add(optn);
    }
    

    All suggestions gratefully received...


  • Closed Accounts Posts: 18,163 ✭✭✭✭Liam Byrne


    phil wrote:
    Just to give my vote of support for JQuery - it's great!

    You really need to have a reasonable grip of javascript already though, the docs kinda assume a familiarity with the DOM.

    Not for something like this, though......just stick a div on the page that you can load the results into.

    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
    function loadAjaxOption(t) {
    t=t.options[t.selectedIndex].text;
    $("#resultsDiv").load("getresults.php?country="+t);
    }
    </script>
    <form action="process_the_form.php" method=".....">
    :
    :
    <div style="float:left">
    <select name="selectCountry" id="selectCountry" onchange="loadViaAjax(this)"><option>.....</option></select>
    </div>
    <div id="resultsDiv" style="float:left">
    <select name="selectRegion" id="selectRegion"><option>Please select a country first</option></select>
    </div>
    :
    ANY OTHER FORM ELEMENTS
    </form>

    Then create getresults.php that uses the country parameter to display the second listbox, outputting something similar to

    <select name="selectRegion" id="selectRegion">option>......</option></select>

    The php page can then do pretty much anything with the results subset, server-side, including pagination or whatever, accessing $HTTP_GET_VARS["country"] wherever required, without resorting to JavaScript to "remember" anything.

    The only thing to remember is that getresults.php is completely independent of process_the_form.php


  • Closed Accounts Posts: 975 ✭✭✭squibs


    Thanks Liam - I'd really rather stick with non-Ajax right now, as it will take me a while to get to grips with that. I've already spent some time just integrating php, mysql and the javascript from the earlier poster, and I'd really love to see it through to completion. I'm just curious as to why the javascript

    optn.selected=true

    doesn't result in the option being selected when the page finishes loading. Could I manually set the value of SelectedIndex to get the result I need?

    Thanks.


  • Registered Users Posts: 1,127 ✭✭✭smcelhinney


    Is there any possibility that multiple items have the selected value set as true? What is actually being set as selected?

    Also, just noticed
    addOption(document.drop_list.Country, "France","France","",true);
    

    has 5 parameters, (the "" an empty string?) yet the addOption function you declared
    function addOption(selectbox, value, text, selec )
    {    
    var optn = document.createElement("OPTION");    
    optn.text = text;    
    optn.value = value;       
    optn.selected=selec;    
    selectbox.options.add(optn);
    }
    

    only accepts 4 parameters. But why are you not getting any errors then.. hmm.. strange one. Try doing
    addOption(document.drop_list.Country, "France","France",true);
    

    and let me know if that works.

    HTH,
    Stephen


  • Advertisement
  • Closed Accounts Posts: 22,479 ✭✭✭✭philologos


    squibs wrote:
    My limited javascript savvy is letting me down. Having browsed through "teach yourself javascript in 24 hours" (it took an hour in case anybody's interested....) I'm still no closer to a solution.

    I have a site where I populate a dropdown list with countries and regions from mysql database with php. The countries are optgroups and the regions are options within the select tags. As you can imagine, the dropdown list is pretty big.

    I was hoping to pass the countries and regions to javascript, and have it dynamically populate a regions list when I selected a country from the country list. I think I'm okay with getting the data from php to javascript, but having dynamic content in the second dropdown list is the part that is confusing me.

    Anybody got a code snippet or know where I could find one I could adapt? Or maybe there's a better way - just don't say ASP...

    Theres a great way using AJAX and PHP in Learning Javascript (O'Reilly), although haven't looked into it much i'm getting the basics down so I can complement my PHP skills :)


  • Closed Accounts Posts: 975 ✭✭✭squibs


    Also, just noticed
    Code:
    addOption(document.drop_list.Country, "France","France","",true);


    has 5 parameters
    Missed that - thanks. Now it remembers the country when the form is submitted, but doesn't populate the regions list for the selected country because the SelectSubCat() function is never called.

    Sigh.


  • Moderators, Science, Health & Environment Moderators Posts: 8,959 Mod ✭✭✭✭mewso


    There are some simple practices when it comes to javascript that people should get into the habit of doing.

    First of all I always use an externally linked script file with a function to initialise my page:-
    function AddLoadEvent(func) {
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = func;
        } else {
            window.onload = function() {
                oldonload();
                func();
            }
        }
    }
    AddLoadEvent(Init);
    

    This kind of code helps to ensure you don't do anyhting until the page has fully loaded. The next step would be to setup the onchange event for the countries dropdownlist in the Init function:-
    function Init()   {
       var countrysel = $("Country");
       if (countrysel)  {
           addOption(countrysel, "France","France",true);
           etc.
           countrysel.onchange = CountrySelected;
       }
    }
    

    I use the prototype library(one single js file) which has some nifty shorthanded methods including easy AJAX stuff too. The $("drop_list.Country") is the same as document.getElementById("drop_list.Country") so change it to that if you don't want to use prototype. Now we have to write the function to be called when a country is selected:-
    function CountrySelected()   {
       var countrysel = $("Country");
       var regionsel = $("Region");
       regionsel.options.length=0; //clears the region list
       if (countrysel.options[countrysel.selectedIndex].text=='France)   {
       addOption(regionsel,"Alsace","Alsace",false);
       etc...
    }
    }
    

    Coupled with your functions this should work. Put it all in a js file and link your web page to it.


  • Registered Users Posts: 1,127 ✭✭✭smcelhinney


    musician

    While the window.onload init function is indeed a given for all js event driven pages, I do understand why squibs wants to do pure javascript.

    squibs, I agree with what you say. Try to steer away from "prepared" scripts, and particularily ajax, until you are 100% comfortable with pure javascript. There's no point taking this stuff, as you end up not learning the concepts of js itself.

    Can you post the full page with the js inline so that I can see? Dont worry about the PHP, I've become immune to it at this stage :) I am, afterall, a Java head...

    Rgds
    Stephen


  • Closed Accounts Posts: 975 ✭✭✭squibs


    Thanks Musician. I take on board your best practices suggestions. I'm just trying to get this solved for now. I can make it elegant later.

    Thanks for your proposed solutions. I'll look into it once the coffee kicks in.


  • Closed Accounts Posts: 975 ✭✭✭squibs


    Yup - I can post the lot.
    Dont worry about the PHP

    You mean you want to see the php or you don't? It's probably best to post it without the php, as the source file runs to 500 lines - error checking, preparing sql statements from contents of form, session handling, etc. I'll post what the browser sees later (I need to revert it to the state it was in as I've been noodling with it). Thanks for the help.


  • Moderators, Science, Health & Environment Moderators Posts: 8,959 Mod ✭✭✭✭mewso


    While the window.onload init function is indeed a given for all js event driven pages, I do understand why squibs wants to do pure javascript.

    Eh. This is pure javascript??? I am not using AJAX. I'm using prototype to do document.getElementById in shorthand which I indicated and thats it.
    wrote:
    Thanks Musician. I take on board your best practices suggestions. I'm just trying to get this solved for now. I can make it elegant later.

    I think people build walls in their mind subconsciously or something. The example I have given is simple and can be done as quickly as doing it inline within a web page. In fact it's easier in it's own file because you can concentrate on what you are doing. Seriously think about it. All you are doing is writing your code in a seperate file instead of with script tags in the html page. I actually posted that code because to me it simplifies the whole process.


  • Closed Accounts Posts: 975 ✭✭✭squibs


    Musician - I'm sure your solution is simple, but it's different and that means spending some time getting my little php-only pea-brain around it. I always try to understand a snippet of code before I incorporate it. I fully intend to sit down and study the code you were good enough to post, but time is catching me right now and I've decided to allow the search form to forget it's previous state for the moment and return to it a little later.

    I greatly appreciate all the help on this from everyone, and will resurrect the thread soon, if nobody objects. It is not only helping me but it seemed to be provoking some interesting posts on best practices, etc.


  • Registered Users Posts: 1,127 ✭✭✭smcelhinney


    musician wrote:
    Eh. This is pure javascript??? I am not using AJAX. I'm using prototype to do document.getElementById in shorthand which I indicated and thats it.

    Apologies, you misunderstood. I wasnt saying that window.onload wasnt pure javascript, I am agreeing with you.

    But do you not agree that using shortcuts (like the shorthand prototyping that you suggested) can hinder the learning of the topic at hand itself? Im trying to think of a practical real life example of this, but essentially, this removes the necessity of learning the code, and goes straight to the "optimisation" phase.

    Would like to hear other peoples opinions on this too? Or is this just me being a little over-idealistic.


  • Moderators, Science, Health & Environment Moderators Posts: 8,959 Mod ✭✭✭✭mewso


    Apologies, you misunderstood. I wasnt saying that window.onload wasnt pure javascript, I am agreeing with you.

    But do you not agree that using shortcuts (like the shorthand prototyping that you suggested) can hinder the learning of the topic at hand itself? Im trying to think of a practical real life example of this, but essentially, this removes the necessity of learning the code, and goes straight to the "optimisation" phase.

    I agree with you. I'm just not sure why you saw the need to address me about it as I was not telling anyone to use it. I had pasted some code I have to show a way of doing it and explained why the $ was being used and specified what should be used in it's place. I was not advocating that people should begin by using the prototype library. I should have just replaced it before pasting the code I suppose.


  • Advertisement
  • Closed Accounts Posts: 975 ✭✭✭squibs


    Dredging this up again. I'm way over my head. Can anybody recommend a good javascript book (with AJAX) for somebody with a php background?

    My code is now as follows:

    <SCRIPT LANGUAGE="JavaScript">
    function AddLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
    window.onload = func;
    } else {
    window.onload = function() {
    oldonload();
    func();
    }
    }
    }
    AddLoadEvent(Init);
    <!-- Begin
    image1 = new Image();
    image1.src = "/images/homeb.jpg";
    image2 = new Image();
    image2.src = "/images/servicesb.jpg";
    image3 = new Image();
    image3.src = "/images/contactb.jpg";
    image4 = new Image();
    image4.src = "/images/aboutb.jpg";
    image5 = new Image();
    image5.src = "/images/advertiseb.jpg";
    function Init(){ 
    var countrysel = document.getElementById("drop_list.Country") ;
    if (countrysel) {
    // this function is used to fill the category list on load
    addOption(countrysel, "Bulgaria","Bulgaria",false);
    .
    .
    .
    countrysel.onchange = SelectSubCat();
    }
    }
    function SelectSubCat(){
    // ON selection of category this function will work
    removeAllOptions(document.drop_list.Region);
    var countrysel = document.getElementById("drop_list.Country");
    var regionsel = document.getElementById("drop_list.Region");
    regionsel.options.length=0; //clears the region list
    addOption(document.drop_list.Region, "", "Region", "");
     
    if(countrysel.options[countrysel.selectedIndex].text=='Bulgaria'){
    addOption(regionsel,"Bansko","Bansko");
    addOption(regionsel,"Burgas","Burgas");
    addOption(regionsel,"Sandaski","Sandaski");
    addOption(regionsel,"Sofia","Sofia");
    addOption(regionsel,"Sunny Beach","Sunny Beach");
    addOption(regionsel,"Varna","Varna");
    addOption(regionsel,"Yambol","Yambol");
    }
    .
    .
    .
     
    function removeAllOptions(selectbox)
    {
    var i;
    for(i=selectbox.options.length-1;i>=0;i--)
    {
    //selectbox.options.remove(i);
    selectbox.remove(i);
    }
    }
     
    function addOption(selectbox, value, text)
    {
    var optn = document.createElement("OPTION");
    optn.text = text;
    optn.value = value;
    // optn.selected=selec;
    selectbox.options.add(optn);
    }
     
    // End -->
    </script>
     
    

    I didn't use proptotype and was pretty much copying and pasting without a full understanding. A bad starting point I know - but I need to get this working.

    The addloadevent and the call to it are in an external file, the rest is included in my main file. I pulled the onload from the body tag, as this is now handled by the init function. Needless to say it doesn't work. Javascript console in firefox comes up clean, but the dropdowns are not even getting populated let alone remembering settings.As I don't fully understand the code, I don't know what I am doing wrong. Can I take advantage of your help one more time please?


  • Moderators, Science, Health & Environment Moderators Posts: 8,959 Mod ✭✭✭✭mewso


    There seem to be a few problems. Firstly you may as well put the image creation code in the init as well if you are using it.

    - "var countrysel = document.getElementById("drop_list.Country") ;"
    Are you sure drop_list.Country is the id of this select element?

    - "countrysel.onchange = SelectSubCat();"
    Should read countrysel.onchange = SelectSubCat;

    Check the other getElementById areas that the id is correct.

    Also heres a site with a good article on doing this using the ideal unobtrusive method - http://www.bobbyvandersluis.com/articles/unobtrusivedynamicselect.php

    Finally I'll recommend you get a good javascript editor. I mention it because I went looking for a good free editor and found one, namely Aptana. Well worth using as it will highlight errors, has intellisense and allows you to collapse functions for easy navigation of your code.

    Oh yeah and a book. My favorite web dev books these days all seem to come from sitepoint.com and they have the best Javascript/AJax book I have read. It's a great explanation of AJax and good javascript programming practices.


  • Closed Accounts Posts: 1,200 ✭✭✭louie


    http://www.dynamicdrive.com/dynamicindex16/chainedselects/index.htm

    check this out, might be what you are looking for.


  • Closed Accounts Posts: 975 ✭✭✭squibs


    Many thanks guys - give me a little while to process, digest and implement. I'll let you know what happens.


  • Closed Accounts Posts: 975 ✭✭✭squibs


    I ended up buying JavaScript the Definitive Guide" by David Flanagan published by O'Reilly. 1018 pages :eek: . I'm not sure how much AJAX is in there, but I'd like to understand javascript thoroughly anyway. Hopefully I can leave you in peace for a while when that arrives.


Advertisement