SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2014
    Posts
    52
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Additional option in select list

    Hi everyone,

    I have the following code in my form:

    Code:
                <tr>
                    <td><label for="Title">Title</label><br />
                    <select name="Title" id="Title" class="cat_dropdown_smaller">
                    <option value="913142">DR</option>
                    <option value="913141">MISS</option>
                    <option value="913138" selected="selected">MR</option>
                    <option value="913139">MRS</option>
                    <option value="913140">MS</option>
                    </select></td>
                </tr>
    I'd like to add another value that says "Other" so that when that option is chosen, an input field appears so they can type in their own title.

    I just wondered if anyone could tell me if this could be done with css or whether I need to use jQuery?

    Thanks in advance.

  2. #2
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,481
    Mentioned
    182 Post(s)
    Tagged
    6 Thread(s)
    Hi,

    You would need js or jquery to do this.

    My Js/jquery is very basic but I guess something like this might work:

    Code:
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Untitled Document</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    </head>
    
    <body>
    <form id="formtest">
    		<select name="Title" id="Title" class="cat_dropdown_smaller">
    				<option value="913142">DR</option>
    				<option value="913141">MISS</option>
    				<option value="913138" selected="selected">MR</option>
    				<option value="913139">MRS</option>
    				<option value="913140">MS</option>
    				<option value="other">Other</option>
    		</select>
    </form>
    <script>
    
    $('#Title').click(function() {
    	$('#other').remove();
      if ($(this).val() ==="other"){
    		$(this).after("<span id='other'><label for='other-choice'> Other title : </label><input type='text' name='other-choice' id='other-choice'></span>")
    	}	
    });
    $( "#formtest" ).on( "blur", "input", function(e) {
    	if( $(this).val() ) {
    	 var selText= $(this).val();
    	 $('#Title option:selected').text(selText);
    	}
    	 $('#other').remove();
    });	
    </script>
    </body>
    </html>
    However, I'll move this to the js forum for a better answer as I am sure there are holes in my approach

  3. #3
    SitePoint Enthusiast
    Join Date
    May 2014
    Posts
    52
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the help.

    If anyone has any alternate code that is a bit more compact, I'd be grateful.

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by gwnh View Post
    Thanks for the help.

    If anyone has any alternate code that is a bit more compact, I'd be grateful.
    The best way is one that doesn't require scripting to be available. When scripting is available we can then use that to make the experience a bit nicer for the user.

    Start by having an input field just below the select one, to accept any other input:

    HTML Code:
    <select name="Title" id="Title" class="cat_dropdown_smaller">
        <option value="913142">DR</option>
        <option value="913141">MISS</option>
        <option value="913138" selected="selected">MR</option>
        <option value="913139">MRS</option>
        <option value="913140">MS</option>
        <option value="other">Other</option>
    </select>
    <input name="otherTitle">
    The above code is all ready to be used now. The server-side script that accepts the form can check if the other option is selected, and if it is then it can pay attention to the input field instead.

    Notice how the input field is called otherTitle. If we have another select field called Relationship, that might have an other option too with a text field called otherRelationship.
    By using the same consistent pattern for naming the other input field, we can easily use the same scripting code to handle different situations.

    jQuery is not mandatory for doing this sort of work either - basic JavaScript can be used to easily do what we want to achieve.

    When you hide the other input field, it's best to use CSS to do that:

    Code css:
    .hidden {
        display: none;
    }

    What we want to do with the scripting is quite easy to explain. When a select element is changed, we want to check if the selected option is the "other" one. If it is, reveal the other input field - otherwise leave it hidden.

    An important aspect is to place the scripting at the end of the body, which will make it easier to interact with elements on the page while it's loading.

    We can use the onchange event to trigger the work we want to get done.

    Code javascript:
    document.querySelector('select[name="Title"]').onchange = function () {
        ...
    };

    We can now create a small function, that will be run whenever the onchange event occurs, that checks if the other field needs to be shown.

    Code javascript:
    var otherFieldHandler = function() {
      var otherInput = document.querySelector('[name="other' + this.name + '"]');
     
      if (this.options[this.selectedIndex].value === 'other') {
        otherInput.classList.remove('hidden');
      } else {
        otherInput.classList.add('hidden');
      }
    };
    document.querySelector('select[name="Title"]').onchange = otherFieldHandler;

    You can see the above in action at http://codepen.io/pmw57/pen/xBdeA

    and lastly we can trigger that event too, which will cause the other input to initially be hidden.

    Code javascript:
    var selectTitle = document.querySelector('select[name="Title"]');
    selectTitle.onchange = otherFieldHandler;
    selectTitle.onchange();

    We can even search the page for all select fields, and attach the otherFieldHandler on to each of them.

    Code javascript:
    var otherFieldHandler = function() {
      var otherInput = document.querySelector('[name="other' + this.name + '"]');
     
      if (this.options[this.selectedIndex].value !== 'other') {
        otherInput.classList.add('hidden');
      } else {
        otherInput.classList.remove('hidden');
      }
    },
        selects = document.querySelectorAll('select'),
        i;
     
    for (i = 0; i < selects.length; i += 1) {
      selects[i].onchange = otherFieldHandler;
      selects[i].onchange();
    }

    You can see the above code in action at http://codepen.io/pmw57/pen/xBdeA/
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    How would this be done using jQuery? Something like this would do:

    Code javascript:
    var otherFieldHandler = function() {
      var $otherInput = $('[name="other' + this.name + '"]'),
          hideField = $(this).val() !== 'other';
     
      $otherInput.toggleClass('hidden', hideField);
    };
    $('select').each(function () {
      $(this)
        .on('change', otherFieldHandler)
        .trigger('change');
    });

    The above can be seen at http://codepen.io/pmw57/pen/hqCpL/

    In fact, the above code wouldn't be used by many people. They would instead deeply nest things, resulting in a higher level of confusion when it comes to trying to understand things.

    Code javascript:
    $('select').each(function () {
      $(this).on('change', function() {
        $('[name="other' + this.name + '"]').toggleClass('hidden', $(this).val() !== 'other');
      }).trigger('change');
    });

    which tends to be more difficult to understand than the other code above.

    Either way though, using jQuery to do this means that your page also needs to load a large amount of code for the jQuery library, weighing in at 100 kilobytes, most of which will be wasted for such a small task. Is it worth it? That's up to you to decide.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    SitePoint Enthusiast
    Join Date
    May 2014
    Posts
    52
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for such a detailed response,

    I just have a couple of questions if that's ok. Your html uses the following for the other option value:

    <option value="other">Other</option>

    The problem with that is that I'm using a CMS that automatically creates the value so it would look more like the following:

    Code:
    <select name="Title" id="Title" class="cat_dropdown_smaller">
        <option value="913142">DR</option>
        <option value="913141">MISS</option>
        <option value="913138" selected="selected">MR</option>
        <option value="913139">MRS</option>
        <option value="913140">MS</option>
        <option value="913141">Other</option>
    </select>
    <input name="otherTitle">
    That is, it would have a specific number for the value instead of saying "other",

    Would the code still work in this case?

    Also, with regard to the jQuery, I already have the code listed at the bottom of this reply, in the head of my document and it looks like I'm loading two libraries:

    Code:
    <script type="text/javascript" src="http://code.jquery.com/jquery-git.js"></script>
    
    <script src="/_assets/js/jquery-1.10.2.min.js"></script>
    Sorry my jQuery and JS skill is very low so this may sound like an odd question but are they both jQuery libraries that I'm loading? If yes, are they both needed and if I'm already loading a jQuery library for other code on the page then I guess it makes sense to use it for this example also.

    Could you advise me on this?


    Code:
    <script type="text/javascript">
    $(function () {
        // redirect to non-secure version of page
        $("a").each(function (idx) {
            var href = $(this).attr("href");
            if (href.indexOf("http") == -1 && href.indexOf("https") == -1) {
                href = '{module_webapps,0,i,17464 template="/_settings/site-url"}' + href;
                $(this).attr("href", href);
            }
        });
    });
    </script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-git.js"></script>
    <script>
    var guests = 0;
    function calc() {
      var numberOfGuests = 0;
      $(".guestrow").each(function() {
        numberOfGuests+= $(this).find(".cat_textbox").val()!="";
      });    
      var price = $('#event-price').text();
      var participants = numberOfGuests+1;// add the organiser
      var total = participants*price;
      $("#BookingAllocation").val(participants);
      $("#booked").toggle(numberOfGuests>0); // only show booked if guests
      $("#Amount").val(total.toFixed(2));
    }
    
    
    $(function () {
        calc();
        $(".cat_textbox").on("keyup",function() { calc(); /* handle removal of gues*/});
        $("#catwebformbutton").on("click", function () {
            guests++;
            if (guests <= 10) {
                $(".guestrow").eq(guests-1).show();
            }
            $("#removeGuest").toggle(guests>0);
            calc();
        });
        $("#removeGuest").on("click",function(e) {
            guests--;
            $(this).toggle(guests>0);
            var $row = $(".guestrow").eq(guests);
            $row.find(".cat_textbox").val("");
            $row.hide();
            calc();
        });
        $('form[name="catwebformform81201"]').on("submit", function (e) {
            calc();
            if (checkWholeForm81201(this)) {
                // ...
            }
            else {
              e.preventDefault(); // cancel submit
            } 
        });
    });
    </script>
    <script src="/_assets/js/jquery-1.10.2.min.js"></script>
    <script type="text/javascript">
    $(function() {
        $('#Title).append(
                $("<option></option>").attr("value","").text("")
        ); 
    })
    </script>
    <script>
    $(document).ready(function() {
    $('#creditCardType , #payOffline').hide();
    $('.creditCard').click(function() {
    $('#creditCardType').toggle();
    $('#payOffline').hide();
    });
    $('.payPal').click(function() {
    $('#creditCardType').hide();
    $('#payOffline').hide();
    });
        $('.payOffline').click(function() {
    $('#payOffline').toggle();
    $('#creditCardType').hide();
    });
    });
    </script>
    <script type="text/javascript">
    $(function(){
    var pfull = $(".meter").data("pfull");
    $(".meter").css("width",pfull)
    });
    </script>

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by gwnh View Post
    Thanks for such a detailed response,

    I just have a couple of questions if that's ok. Your html uses the following for the other option value:

    <option value="other">Other</option>

    The problem with that is that I'm using a CMS that automatically creates the value so it would look more like the following:

    Code:
    <select name="Title" id="Title" class="cat_dropdown_smaller">
        <option value="913142">DR</option>
        <option value="913141">MISS</option>
        <option value="913138" selected="selected">MR</option>
        <option value="913139">MRS</option>
        <option value="913140">MS</option>
        <option value="913141">Other</option>
    </select>
    <input name="otherTitle">
    That is, it would have a specific number for the value instead of saying "other",

    Would the code still work in this case?
    It can still work with a minor adjustment, so that the HTML of the selected option is compared with "Other" instead.

    Code javascript:
      var hideField = ($(':selected', this).html() !== 'Other'),
          $otherInput = $('[name="other' + this.name + '"]');

    That was the jQuery version.

    The basic JavaScript version of the code has an even smaller change that's needed, just changing .value to .innerHTML:

    Code javascript:
    if (this.options[this.selectedIndex].innerHTML !== 'Other') {

    Quote Originally Posted by gwnh View Post
    Also, with regard to the jQuery, I already have the code listed at the bottom of this reply, in the head of my document and it looks like I'm loading two libraries:

    Sorry my jQuery and JS skill is very low so this may sound like an odd question but are they both jQuery libraries that I'm loading? If yes, are they both needed and if I'm already loading a jQuery library for other code on the page then I guess it makes sense to use it for this example also.
    The git version of jQuery is constantly updating with the most recent version of jQuery, which is not a good idea for production websites as future changes can be incompatible with existing techniques you're using on the site.

    Normally only one library is needed. When a second one is loaded it overwrites the previous version. You already have the one in your assets area so that's a good one to use.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  8. #8
    SitePoint Enthusiast
    Join Date
    May 2014
    Posts
    52
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for clarifying things. I'll see if I can get this working …


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •