Sunday, April 15, 2012

Solution to Chapter 5 Exercises of Learning jQuery 3rd Edition




  
Free Lessons for Chruch Pianists:
Free lessons, tips and downloads for church pianists

DVD Courses (Reharmonization, Play by Ear!, Arranging, Accompanying, Theory for Church Pianists, etc.):
Over 30 hours of DVD instruction for church pianists
 



My solutions to Learning jQuery 3rd Edition Chapter 5 Exercises:

1. Alter the code that introduces the back to top links so that the links only appear beginning after the fourth paragraph.

jQuery(document).ready(function ($) { 
    $('<a href="#top">back to top</a>').insertAfter('div.chapter p:gt(2)');
});



2. When a back to top link is clicked, add a new paragraph after the link, containing the message You were here. Ensure that the link still works.

jQuery(document).ready(function ($) { 
    $('a').click(function () {
        $('p:contains("You were here.")').remove();
        $(this).after('<p style=\"color: blue\">You were here.</p>');
    });
});



3. When the author's name is clicked, turn it bold (by adding a tag, rather than manipulating classes or CSS attributes).

jQuery(document).ready(function ($) { 
        $('#f-author').click(function () {
            $(this).wrapAll('<b></b>');
        });
});


4. Challenge: On a subsequent click of the bolded author's name, remove the <b> element that was added (thereby toggling between bold and normal text).

jQuery(document).ready(function ($) { 
    $('#f-author').toggle(
        function () {
            $(this).wrapAll('<b></b>');
        },
        function () {
            $(this).unwrap()
        }
    );
});



5. Challenge: Add a class of inhabitants to each of the chapter's paragraphs, without calling .addClass(). Make sure to preserve any existing classes.

jQuery(document).ready(function ($) { 
    var $chapter_p = $('.chapter p');
    var chapter_p_class = $chapter_p.attr('class')
    $chapter_p.attr({ class: chapter_p_class + ' inhabitants' });
});


13 comments:

  1. this is actually chapter 5..;)) you should change the title...My solutions to Learning jQuery 3rd Edition Chapter 4

    ReplyDelete
  2. wellcome..nice job...really helped me!! God Bless your work!!
    from Romania

    ReplyDelete
  3. My solution to #2:
    $('a[href*="#top"]').click(function() {
    $('p You were here /p').insertAfter(this);
    }); /*had to remove brackets around p - the warning box refused to accept it*/
    Could have been like yours - the after() with reversal of object positions.

    Q: Wouldn't your solution insert these after all anchors? And why did you need remove?

    Thanks,
    Elena

    ReplyDelete
  4. #4 fr Elena :-)
    $('#f-author').click(function() {
    var htmlStr = $(this).text();
    if ($(this).find('strong').length > 0)
    {
    $(this).text(htmlStr);
    }
    else
    {
    $(this).wrapInner('');
    }
    });

    ReplyDelete
  5. Oops, your editor stripped out my strong tag inside the wrapInner function. This will not run until whoever tries it manually adds that back.
    Have a great day,
    Elena

    ReplyDelete
  6. In #2 I used
    ...one('click', function()... to add only one paragraph per link

    Can't show the whole solution - some tags are not liked by this page content checker

    Tom

    ReplyDelete
  7. #4

    @Jeremiah: your use of toggle() is deprecated and doesn't seem to work in the latest JQ.

    My change:
    $('div#f-author').click(function() {
    if ($(this).parent().is('b')) {
    //$(this).parent().after($(this)).remove();
    $(this).unwrap();
    } else {
    $(this).wrap('');
    }
    });

    Tom

    ReplyDelete
  8. #5

    $('div.chapter p').each(function(index, el) {
    var classes = $.trim(el.className + ' ' + 'inhabitants');
    $(el).prop('className', classes);
    });
    Tom

    ReplyDelete
  9. Hey Jeremiah,

    I was thinking about #3 and how clicking it multiple times can result in several strong tags, so I added an unbind() method to the chain:

    jQuery(document).ready(function ($) {
    $('#f-author').click(function () {
    $(this).wrapAll('').unbind();
    });
    });

    ReplyDelete
  10. My b tags got stripped, but you get the idea :)

    ReplyDelete
  11. #3 and #4
    My solution for getting around .toggle() being dropped in jQuery 1.9:

    $('div#f-author').click(function() {
    if($(this).html() == 'by Edwin A. Abbott') {
    $(this).html('by Edwin A. Abbott');
    }
    else ($(this).html('by Edwin A. Abbott'))
    });

    Seems like there should be a way to consolidate more, but it does work.

    #5
    I first added the following code to css stylesheet to make sure classes were kept:

    .square {background-color: #FF0;}
    .nobility{background-color:blue;margin-left:20px;}

    With this added the first paragraph has a yellow background and the second paragraph has a blue background and is indented an extra 20px. When I tried Jeremiah's code it didn't work. The wide border was on the left but all the paragraphs now had a yellow background, so it saves the first paragraph's classes and applies to all the others. After looking up .attr() on jQuery site I came up with this:

    $('div.chapter p').attr('class', function(i, val) {
    return val + ' inhabitants'
    });

    This works. If I understand it correctly, the 'i' var is the index number for the particular paragraph and 'val' is that paragraph's value for it's class. The function then concatenates the current value and ' inhabitants' and returns the result. NOTE the extra space after the first quote, ' inhabitants', that has to be there or it won't work.

    ReplyDelete
  12. Hmmm, it removed the b tags on #3 and #4 solution and just made the type bold

    ReplyDelete