SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Member
    Join Date
    Aug 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Help with jquery show/hide function - how to toggle button text

    I'm using JQuery to hide a map on the page and then insert a show/hide text link that, when clicked will reveal the <span> that contains the map. I want to toggle the text between show and hide depending on whether the map section is visible or not.

    I've got the show/hide function working and the text is initially set to show when the map is hidden. Clicking on the text will show the map and change the text to hide.

    I'm having problems changing the text back to 'show' if the user clicks on the hide map link.

    The example is on this page:
    http://www.sutherlandshire.nsw.gov.a...event_-_martin

    here is the html of the section in question

    Code HTML4Strict:
    <p class="event-where">
        <span class="where">Where:</span> Sutherland Library<br> 
        30-36 Belmont Street, Sutherland NSW 2232 
        <span class="event-map">
    	<iframe width="440" scrolling="no" height="300" src="http://maps.google.com/maps?..." ></iframe>
        </span><!-- event-map -->
    </p>


    Here is the JQuery code I've written so far.

    Code JavaScript:
    //hide the map by default
      $('.event-map').hide();
     
      //Add the button to toggle the map
      $('<span id="toggle-map">Show Map</span>').insertBefore('.event-map');
     
      //toggle the display by clicking on button
      $('#toggle-map').click(function () {
        $('.event-map').slideToggle('fast');
        if ($('#toggle-map').is(':visible')) {
          $(this).text('Hide Map');
        } else {
          $(this).text('Show Map');
        }
      });

    I'm not sure why this doesn't work. Any suggestions as to how I can get the text to change back on the second click or an explanation of why this code doesn't work?

    thanks,
    Martin

  2. #2
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,191
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Hi boycetrus and welcome to SitePoint,

    The reason as to why your above code isn't working correctly is due to how you have setup the element for the toggle event, instead of targeting specific elements by their class name or ID you really should be using some built into jQuery methods which help with situations like this. See the below for a version of the above code that should work fine.

    Code JavaScript:
    $('.event-map').each(function() {
        // Hide the map by default
        $(this).hide();
     
        // Add a button before the map to toggle it
        $('<span />', {
            'class' : 'toggle-map',
            html    : 'Show Map'
        }).on('click', function() {
            // Cache the jQuery object for the map
            var $map = $(this).next('.event-map');
     
            // Toggle the map
            $map.slideToggle();
     
            // Change the text on the toggle button
            $(this).text(($map.is(':visible') ? 'Show' : 'Hide') + ' Map');
        }).insertBefore(this);
    });

  3. #3
    SitePoint Member
    Join Date
    Aug 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by chris.upjohn View Post
    Hi boycetrus and welcome to SitePoint,

    The reason as to why your above code isn't working correctly is due to how you have setup the element for the toggle event, instead of targeting specific elements by their class name or ID you really should be using some built into jQuery methods which help with situations like this. See the below for a version of the above code that should work fine.

    Code JavaScript:
    $('.event-map').each(function() {
        // Hide the map by default
        $(this).hide();
     
        // Add a button before the map to toggle it
        $('<span />', {
            'class' : 'toggle-map',
            html    : 'Show Map'
        }).on('click', function() {
            // Cache the jQuery object for the map
            var $map = $(this).next('.event-map');
     
            // Toggle the map
            $map.slideToggle();
     
            // Change the text on the toggle button
            $(this).text(($map.is(':visible') ? 'Show' : 'Hide') + ' Map');
        }).insertBefore(this);
    });
    Thanks for that Chris.
    I'm relatively new to jquery (and fairly useless at javascript), however I've worked my way through most of your code above and, although there are a couple of new bits to me in there, I understand what's going on for the most part.

    I am having a bit of trouble deciphering what's actually happening with the line that swaps the text of the button based on the visibility of the $map object, ie.
    Code JavaScript:
    $(this).text(($map.is(':visible') ? 'Show' : 'Hide') + ' Map');

    I can see that $(this).text(...) is setting the text of the button
    I gather that ...'Show' : 'Hide') + ' Map') is concatenating show or hide with map to create the text string.

    I'm just not sure how the test for whether $map (.event-map) is visible works. That is, this bit ($map.is(':visible') ? 'Show' : 'Hide')

    If anyone can explain exactly what's happening in this snippet of code I would be very grateful.

    cheers,
    Martin

  4. #4
    SitePoint Member
    Join Date
    Aug 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi again,
    Never mind about the follow up. I just went digging around a bit more and I think I've worked it out.

    The ? is a conditional operator so if $map.is(':visible') returns true then use Show, otherwise use Hide. I can see how the conditional operator can be used as an alternative to if/else.

    thanks for your help.
    Martin

  5. #5
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,191
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    That's correct, for future reference just so you know it's called a ternary operator which you can call a conditional operator but that would get confusing as if/else statements also have conditional operators aka && (and) and || (or).

  6. #6
    SitePoint Member
    Join Date
    Aug 2012
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by chris.upjohn View Post
    That's correct, for future reference just so you know it's called a ternary operator which you can call a conditional operator but that would get confusing as if/else statements also have conditional operators aka && (and) and || (or).
    Got it!
    Thanks Chris.

    Martin

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,702
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by chris.upjohn View Post
    That's correct, for future reference just so you know it's called a ternary operator which you can call a conditional operator but that would get confusing as if/else statements also have conditional operators aka && (and) and || (or).
    Here's how they break down.

    The following code is an example of what the ternary operator deals with:

    Code javascript:
    if (member === true) {
        fee = 2;
    } else {
        fee = 10;
    }

    With the ternary operator, you can handle the above situation as a single line, without losing the ability to easily understand what is going on.

    Code javascript:
    fee = (member === true) ? 2 : 10;

    The && operator is the AND operator; also called a guard condition. If the first part is falsy (null, undefined, 0, empty string, false, etc...) then the test fails, and the next part isn't even processed. This means that you can use it to protect against situations that may cause a syntax error.

    Normally code to do that would be:

    Code javascript:
    if (element) {
        if (element.nodeType === 1) {
            if (element.nodeName === 'A') {
                // do stuff with the anchor element
            }
        }
    }

    Whereas by making good use of the && operator, the above can be done just as easily with:

    Code javascript:
    if (element && element.nodeType === 1 && element.nodeName === 'A') {
        // do stuff with the anchor element
    }

    You commonly see the guard condition being used when dealing with objects, so that you don't inadvertently attempt to access a property or a method that may not exist.

    The || operator is the OR operator, which is also be used as a default operator. If the first part is truthy, JavaScript doesn't carry on to process the rest of the statement.

    So you might set a default value for something as:

    Code javascript:
    var amount = 0;
    if (parseFloat(total)) {
        amount = parseFloat(total);
    }

    By making good use of the default operator, we can easily assign the parsed value, and default to a certain value if it doesn't parse to a meaningful value.

    Code javascript:
    var amount = parseFloat(total) || 0;

    You commonly see the default operator being used when something may not exist, so that you can provide a default meaningful value for it instead.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Tags for this Thread

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
  •