-19

I have a table of data that used to use a jQuery call to display a hidden div containing an additional text input field only if one specific option was picked on a select. It looked like this - in the head of the page:

jQuery(function ($) {
    $('#newSubStatus').change(function () {
        $('#showhide').toggle(this.value == 'Option B');
    }).change(); // To set the initial state
})

And in the body:

<select id="newSubStatus" name="newSubStatus">
    <option value="Option A">Option A</option>
    <option value="Option B">Option B</option>
    <option value="Option C">Option C</option>
    <option value="Option D">Option D</option>
    <option value="Option E">Option E</option>
    <option value="remove">Remove Sub-status</option>
</select><br>
<div id="showhide" style="display: none;">
    <input type="text" style="width: 120px; margin-left: 40px;" name="newSubStatusExtra" value="" placeholder="Enter amount">
</div>

It worked fine. Now I am redoing this page so that the data in the table is editable using Jeditable which works perfectly with this one exception in that I cannot get it to display the hidden div by any means possible. My current code looks like this - in the head:

jQuery(function ($) {
    $('#newSubStatus').change(function () {
        $('#showhide').toggle(this.value == 'Option B');
    }).change(); // To set the initial state
})

$(function() {
    $(".edselect_subStatus").editable("./update.php?x=jiwjOijoJoihYfytfjhhiuh", {
        data        : '{"Option A":"Option A","Option B":"Option B","Option C":"Option C","Option D":"Option D","Option E":"Option E","REMOVE":"Remove Sub-status"}',
        callback    : function() {
            location.reload();
        },
        type        : 'select',
        event       : 'dblclick',
        placeholder : '',
        onblur      : 'ignore',
        indicator   : 'Saving...',
        cssclass    : 'editable',
        submit      : 'Save',
        cancel      : 'Cancel',
    });
});

And in the body:

 <tr>
     <td>Status:</td>
     <td class="edselect_status" id="status"><?=$status?></td>
     <td style="padding-left: 10px;">Sub-status:</td>
     <td class="edselect_subStatus" id="subStatus"><?=$subStatus?>
     <div id="showhide" style="display: none;"><br>
         <input type="text" style="width: 120px; margin-left: 40px;" name="newSubStatusExtra" value="" placeholder="Enter amount">
     </div></td>
 </tr>

I understand that there is nothing to connect #newSubStatus to the select anymore to trigger it. I have tried ways to connect it to the td id it sits in, without success. I have found many other ways to make a text field to appear, but they all rely on having an id element from the originating select. Is there a way to make this work or is it too much of a JavaScript mismatch to function together?

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Cassandra
  • 261
  • 4
  • 18
  • What's de the HTML output of Jeditable? What does it creates? – azeós Jul 02 '18 at 06:44
  • It creates a `select` with the options listed in the `data` line. It does not seem to produce a `select` that I can place an `id` on. I have tried this even by tweaking the jquery.jeditable.mini.js file. – Cassandra Jul 02 '18 at 06:49
  • Obviously the value entered into `newSubStatusExtra` actually needs to be posted with the `select` data in some practically useful way otherwise it's not working correctly. – Cassandra Jul 05 '18 at 14:04
  • 16
    If that's a requirement, it needs to be part of the question. Hard to fault answerers for not including it if you don't actually tell them your full requirements. We can't read your mind. – fbueckert Jul 05 '18 at 15:14
  • Possible duplicate of [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Heretic Monkey Jul 05 '18 at 22:36
  • You probably want this: [Submitting to function instead of URL](https://appelsiini.net/projects/jeditable/). Redirect To Function Method. – Tibrogargan Jul 06 '18 at 06:55

1 Answers1

6

How to trigger a JS function from a select element when the select element no longer exists in a normal manner?

You are assigning a handler to a Jeditable element that is not rendered yet, and that won't work as to be able to assign a handler to an element it need to exist in the DOM.

In such situations you can use event delegation, in this case jQuery's .on(), where the handler is attached to a parent, and then set to pick up the event from the select (2nd parameter) e.g.

jQuery(function ($) {
    $('#subStatus').on('change', 'select', function (event) {
        $('#showhide').toggle(this.value == 'Option B');
    })
})

Stack snippet

jQuery(function ($) {
    $('#subStatus').on('change', 'select', function (event) {
        $('#showhide').toggle(this.value == 'Option B');
    })
})
/* for the purpose of this demo */
td {
  vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td>Status:</td>
    <td class="edselect_status" id="status">
      <?=$status?>
    </td>
    <td style="padding-left: 10px;">Sub-status:</td>
    <td class="edselect_subStatus" id="subStatus">

      <select>
        <option value="Option A">Option A</option>
        <option value="Option B">Option B</option>
        <option value="Option C">Option C</option>
        <option value="Option D">Option D</option>
        <option value="Option E">Option E</option>
        <option value="remove">Remove Sub-status</option>
      </select>

      <div id="showhide" style="display: none;">
        <input type="text" style="width: 120px; margin-left: 40px;" name="newSubStatusExtra" value="" placeholder="Enter amount">
      </div>
    </td>
  </tr>
</table>

And for anyone who want a deeper explanation what event delegation is, here is a great answer with several links to concrete code examples:


Updated based on a comment, saying that the hidden div still doesn't shows/hides.

With the Codepen demo I were able to figure out what was the issue.

The td with class edselect_subStatus, where the Jeditable generates, it replace all content in that td, your div/input as well, so to solve that, I added an extra div and moved the edselect_subStatus class to it.

A less important note, in your 2nd sample in the Codepen, the id for your div with the input is showhide_B, not the initial showhide, and with that fixed it all now works just fine, showing/hiding the hidden div properly.

Stack snippet - and an updated version of your Codepen sample

<html>
<head>
<title>Demo</title>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="http://www.appelsiini.net/download/jquery.jeditable.mini.js"></script>
<script>
//<![CDATA[
jQuery(function ($) {
    $("#newSubStatus_A").change(function () {
        $("#showhide_A").toggle(this.value == 'Option B');
    }).change(); //to set the initial state
})

jQuery(function ($) {
    $('#subStatus').on('change', 'select', function (event) {
      $('#showhide_B').toggle(this.value == 'Option B');
    })
})

jQuery(function ($) {
    $('#subStatus').on('click', 'button', function (event) {
        $('#showhide_B').hide();
    })
})
function jeditableReset(settings, original) {
    $('#showhide_B').hide();
}
  
$(function() {
 $(".edselect_appStatus").editable("./ADMIN.UPDATER.php?key=demo", {
  data  : '{"Stat A":"Stat A","Stat B":"Stat B","Stat C":"Stat C","Stat D":"Stat D","Stat E":"Stat E"}',
  callback : function() {
   location.reload();
  },
  type   : 'select',
  event  : 'dblclick',
  placeholder : '',
  onblur  : 'ignore',
  indicator : 'Saving...',
  cssclass : 'editable',
  submit  : 'Save',
  cancel  : 'Cancel',
 });

 $(".edselect_subStatus").editable("./ADMIN.UPDATER.php?key=demo", {
  data         : '{"Option A":"Option A","Option B":"Option B","Option C":"Option C","Option D":"Option D","Option E":"Option E","REMOVE":"Remove Sub-status"}',
  callback : function() {
   location.reload();
  },
    onreset: jeditableReset,
    type   : 'select',
  event  : 'dblclick',
  placeholder : '',
  onblur  : 'ignore',
  indicator : 'Saving...',
  cssclass : 'editable',
  submit  : 'Save',
  cancel  : 'Cancel',
 });
});
//]]>
</script>
</head>

<body style="bgcolor: #fff;">

<h1>Original method</h1>

<p>To see effect, choose &quot;Option B&quot; in Sub-Status</p>

    <table style="width: 800px; margin-bottom: 0;" border="1">
     <tbody><tr>
      <td style="width: 17%;">Status:</td>
      <td style="bgcolor: #f6f6f6; width: 33%;">
    <select id="newStatus_A" name="newStatus_A" style="width: 270px;">
       <option value="">Choose...</option>
       <option value="Stat A">Stat A</option>
       <option value="Stat B">Stat B</option>
       <option value="Stat C">Stat C</option>
       <option value="Stat D">Stat D</option>
       <option value="Stat E">Stat E</option>
      </select></td>
      <td style="width: 17%; padding-left: 10px;">Sub-status:</td>
      <td style="bgcolor: #f6f6f6; width: 33%;">
    <select id="newSubStatus_A" name="newSubStatus_A" style="width: 270px;">
       <option value="">Choose...</option>
       <option value="Option A">Option A</option>
       <option value="Option B">Option B</option>
       <option value="Option C">Option C</option>
       <option value="Option D">Option D</option>
       <option value="Option E">Option E</option>
       <option value="REMOVE">Remove Sub-status</option>
      </select><br>
      <div id="showhide_A" style="display: none;">
       <input type="text" style="width: 120px; margin-left: 40px;" name="newSubStatusExtra_A" value="" placeholder="Enter amount">
      </div></td>
     </tr></tbody>
    </table>

<br><br>

<h1>New method (using Jeditable)</h1>

<p>Double click in on the &quot;Select...&quot; fields. Choosing &quot;Option B&quot; in Sub-Status field is supposed to reveal the additional field as above</p>

    <table style="width: 800px; margin-bottom: 0;" border="1">
     <tbody><tr>
      <td style="width: 17%;">Status:</td>
      <td style="bgcolor: #f6f6f6; width: 33%;" class="edselect_appStatus" id="appStatus">Select...</td>
      <td style="width: 17%; padding-left: 10px;">Sub-status:</td>
      <td style="bgcolor: #f6f6f6; width: 33%;" id="subStatus"><div class="edselect_subStatus">Select...</div>
        
      <div id="showhide_B" style="display: none;"><br>
       <input type="text" style="width: 120px; margin-left: 40px;" name="newSubStatusValue" maxlength="12" value="" placeholder="Enter amount">
      </div></td>
     </tr></tbody>
    </table>

</body>
</html>
Asons
  • 81,773
  • 12
  • 93
  • 144