0

Working on building a approval/edit process for company site. I have it set-up so that a jquery datatable displays scheduled events for the logged in user and displays the trip like this

results = await response.json();
var tr = $(this).closest('tr');
var id = tr.children('td:eq(0)').text()
tbl = $('#example').DataTable( {
                dom: 'lBfrtip',
                lengthMenu: [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
                pageLength: 50,
                data: results,
                columns: [
                    { 
                        title: "Arrived",
                        data: "id" ,
                        width: "10%",
                        className: "text-center",
                        render: function (data, type, full, meta){
                        return '<input type="checkbox" name="id[]" value="' + $('<div/>').text(data).html() + '">';
                        }
                    },
                    { 
                        title: "Employee Name",
                        data: "Employee",
                        width: "20%"                                  
                    },
                    { 
                        title: "Destination",
                        data: "Destination"
                    },
                    {
                        title: "Modify",
                        render: function(data, type, row, meta)
                        {
                            return '<button id="btnModify" data-id="' + row.id + '" data-bs-toggle="modal" data-bs-target="#modifyVisit" class="btn btn-success" type="button">Modify Visit</button>'; 
                        }
                    }
                ]

            });

}
}

this part works excellent - now I am trying to modify this a bit and add the Modify button in the jquery datatable - that piece is done the button is there, YAY!

The issue that when the Modify button is pressed a modal is displayed that gives the user the option to either Reschedule Or Cancel. Here is the html for that

<div id="modifyVisit" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modify Visit</h5>
<button class="close" type="button" data-dismiss="modal"> × </button></div>
<div class="modal-body">
<h2>Select The Modification Type</h2>
<div class="wrap">
<div class="row">
<div class="col-xs-6 col-xl-6 item"><button id="btnReschedule" class="btn btn-primary" type="button" data-bs-whatever="reschedule">Reschedule Visit</button></div>
<div class="col-xs-6 col-xl-6 item"><button id="btnCancel" class="btn btn-primary" type="button" data-bs-whatever="cancel">Cancel Visit</button></div>
</div>
<div class="modal-footer"><button class="btn btn-secondary" type="button" data-dismiss="modal">Close</button></div>
</div>
</div>
</div>
</div>

my issue is that I need to capture which button was pressed (so I know which data points to display) and also the id of the row that the user clicked the modify button on.

I tried to capture it like this

var modifyVisit = document.getElementById('#btnModify')
  modifyVisit.addEventListener('show.bs.modal', function (event) {
    //row id of clicked button
    var id = $(this).attr("data-id");
    // Button that triggered the modal
    var button = event.relatedTarget
    // Extract info from data-bs-* attributes
    var buttonClicked = button.getAttribute('data-bs-whatever')
    console.log(id);
    console.log(buttonClicked);
  });

but I get a console error, I assume because I'm trying to add an event listener to an element that is not displayed on the page when the page loads...


  caught TypeError: Cannot read properties of null (reading 'addEventListener')
    at HTMLDocument.<anonymous>

I know I can use var id = $(this).attr("data-id"); to get the id of the row where the button was pressed, but what have I set-up incorrectly here?

EDIT
I edited the click to use jquery like this

  $(document).on("click", "#btnModifyVisit", function(e) {
    console.log('modify button clicked');
    //row id of clicked button
    var id = $(this).attr("data-id");
    // Button that triggered the modal
    var button = e.relatedTarget
    // Extract info from data-bs-* attributes
    var buttonClicked = e.getAttribute('data-bs-whatever')
    console.log(id);
    console.log(buttonClicked);
  });

and now it is giving me an error on click of

caught TypeError: e.getAttribute is not a function
HotTomales
  • 544
  • 2
  • 6
  • 13
  • What @cytek04 said - but specifically look at jQuery [delegated event handlers](http://api.jquery.com/on/). You attach the event handler to an element which _is_ available, and tell that handler which (not yet available) element the event is for. "_Delegated event handlers have the advantage that they can process events from descendant elements that are added to the document at a later time._" I have not tried this with modals, but I don't see why it would not work. – andrewJames May 20 '23 at 23:11

1 Answers1

0

You are exactly right. It can't listen to an element that does not exist when the page loads. jQuery has a very good solution for this that I use for everything - .on().

Also I think the show.bs.modal event happens on the modal element.

Try the below code.

  $(document).on('show.bs.modal', '.modal', function (event) {
    //row id of clicked button
    var id = $(this).attr("data-id");
    // Button that triggered the modal
    var button = event.relatedTarget
    // Extract info from data-bs-* attributes
    var buttonClicked = button.getAttribute('data-bs-whatever')
    console.log(id);
    console.log(buttonClicked);
  });

This essentially works behind the scenes to attach the listener to the document and check to see if the target equals the second parameter (in this case #btnModify). It allows you to have listeners for dynamically added content, which is exactly what you need.

cytek04
  • 472
  • 5
  • 17
  • i get an error of `caught SyntaxError: missing ) after argument list` and this is the line `$(document).on('show.bs.modal', '.modal' function (event) {` – HotTomales May 20 '23 at 23:23
  • There is a comma missing between `'.modal'` and `function (event)` - probably just a typo, but check the [documentation](http://api.jquery.com/on/) for delegated event handlers: `$(document).on('show.bs.modal', '.modal', function (event) {`. Is that necessary? Yes. Is it sufficient? I don't know. – andrewJames May 20 '23 at 23:49
  • Sorry missed the comma. Fixed. – cytek04 May 20 '23 at 23:49
  • okay - for my two `log` I get `undefined` and `null` – HotTomales May 21 '23 at 00:04
  • Now you encountered the age old problem with bs modals. `event` does not include any reference to the button that triggered the `show.bs.modal` event. Bootstrap has methods to programmatically open the modal, such as when a click event occurs on a button. At which point you would have access to the click event target. Here is a helpful link. https://stackoverflow.com/a/32058932/14199515 – cytek04 May 21 '23 at 00:51