0

The point of this code is to toggle back and forth between two versions of innerHTML within the div, using the input values (or the default values) and also toggle how the button displays. It is not working. After the first click, the "new" button fails. The div is supposed to revert back to the original display with the blank input fields.

I've looked at a few other questions on the .toggle method, but it's deprecated, and it's unclear what the best fix is. There doesn't seem to be much consensus on an approach. Here are the other threads I found for reference:

Here is a jsfiddle example of what I am trying to do.

HTML Code:

<div id="case-name">Case Name:&nbsp;In the Matter of <input id="input-petitioner" type="text" placeholder="Petitioner" maxlength="50"></input> and <input id="input-respondent" type="text" placeholder="Respondent" maxlength="50">&nbsp;<button id="case-name-submit" type="button" value="none">Submit</button></div>

Script:

$(document).ready(function(){
//EVENT TRIGGERS AND ACTIONS
$('#case-name-submit').on('click', function(){
    $('#case-name').fadeOut('fast').html(
    'Case Name:&nbsp;In the Matter of ' + $('#input-petitioner').val() + ' and ' +  $('#input-respondent').val() + '&nbsp;<button id="case-name-change" type="button" value="none">Change</button>'
    ).fadeIn('fast');
});
$('#case-name-change').on('click', function(){
    $('#case-name').fadeOut('fast').html(
    'Case Name:&nbsp;In the Matter of <input id="input-petitioner" type="text" placeholder="Petitioner" maxlength="50"></input> and <input id="input-respondent" type="text" placeholder="Respondent" maxlength="50">&nbsp;<button id="case-name-submit" type="button" value="none">Submit</button>'
    ).fadeIn('fast');
});
});
2
  • 1
    you need to look at [event delegation](learn.jquery.com/events/event-delegation/) Commented Mar 21, 2014 at 3:42
  • Very cool reference. I'll definitely check it out. Commented Mar 21, 2014 at 3:45

2 Answers 2

2

Since your #case-name-submit and #case-name-change have been added dynamically to the DOM, all the events is not available to this two elements, so you need to use event delegation here to attach click event to those buttons:

Event delegation allows us to attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future.

$(document).ready(function(){
//EVENT TRIGGERS AND ACTIONS
$('#case-name').on('click', '#case-name-submit', function(){
        $('#case-name').fadeOut('fast').html(
        'Case Name:&nbsp;In the Matter of ' + $('#input-petitioner').val() + ' and ' + $('#input-respondent').val() + '&nbsp;<button id="case-name-change" type="button" value="none">Change</button>'
        ).fadeIn('fast');
    });
$('#case-name').on('click','#case-name-change', function(){
        $('#case-name').fadeOut('fast').html(
        'Case Name:&nbsp;In the Matter of <input id="input-petitioner" type="text" placeholder="Petitioner" maxlength="50"></input> and <input id="input-respondent" type="text" placeholder="Respondent" maxlength="50">&nbsp;<button id="case-name-submit" type="button" value="none">Submit</button>'
        ).fadeIn('fast');
    });
});
Sign up to request clarification or add additional context in comments.

2 Comments

This is exactly what I was trying to do. And thanks for the explanation. If I understand correctly, one of the things I was doing wrong was not including both parent and child elements. Since event delegation applies to child even if they "exist now or are added in the future," not having any children effectively negates event handling. E.g., $('#myID').on('click', function()... doesn't have any children, just the parent #myID. Is that about right?
No, it doesn't matter whether you include both parent and child elements or not. The importance here is that your element is not exist in the DOM on page load(actually it works the first time when you click the button submit because submit button is already added to the DOM). But from the second time you change the HTML so the newly added HTML element will not be able to receive any event such as click, hover,.... so event delegation will help you to solve this problem.
2

You are having dynamic elements, since you are changing the contents so use event delegation

$(document).ready(function () {
    //EVENT TRIGGERS AND ACTIONS
    $('#case-name').on('click', '#case-name-submit', function () {
        $('#case-name').fadeOut('fast', function () {
            $(this).html(
                'Case Name:&nbsp;In the Matter of ' + $('#input-petitioner').val() + ' and ' + $('#input-respondent').val() + '&nbsp;<button id="case-name-change" type="button" value="none">Change</button>').fadeIn('fast')
        });
    }).on('click', '#case-name-change', function () {
        $('#case-name').fadeOut('fast', function () {
            $(this).html(
                'Case Name:&nbsp;In the Matter of <input id="input-petitioner" type="text" placeholder="Petitioner" maxlength="50"></input> and <input id="input-respondent" type="text" placeholder="Respondent" maxlength="50">&nbsp;<button id="case-name-submit" type="button" value="none">Submit</button>').fadeIn('fast')
        });
    });
});

Also you need to update the html inside the fadeOut complete handler

Demo: Fiddle

An updated version

1 Comment

This solution is really pretty clever. I wouldn't have thought of chaining both "on" events to the same selector. Between this solution and Felix's, above, is it mostly just a stylistic difference (e.g., he uses two selectors, and this uses one). Is there anything else substantively different in the solutions? Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.