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');
});
});
Community
  • 1
  • 1
ChrisBuck
  • 102
  • 3
  • 16

2 Answers2

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

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • 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. – ChrisBuck Mar 21 '14 at 03:59
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');
    });
});
Felix
  • 37,892
  • 8
  • 43
  • 55
  • 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? – ChrisBuck Mar 21 '14 at 03:56
  • 1
    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. – Felix Mar 21 '14 at 04:01