0

Note: I've tried the various solutions found online for my issue, but none of them have worked.

I am trying to pass content from a table where each row has its own button to edit the content in that row. The button opens a Twitter Bootstrap dropdown, which has two buttons, one being the "Edit" button. The edit button opens a modal which has a text-area input. I want the text-area to have the current text present in the table for editing. I am using PHP with Symfony for the forms and Twig for the page rendering.

the button that triggers the modal

<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
   <button class="btn btn-sm dropdown-item edit-button" data-toggle="modal" data-target="#announcementEditModal" data-id="{{ announcement.id }}" data-content="{{ announcement.content }}" type="button">
       <div class="announcement-actions">
          <span class="fas fa-pencil-alt"></span> Edit announcement
       </div>
  </button>

The modal

<div class="modal fade" id="announcementEditModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header announcement-header">
                <h5 class="modal-title" id="exampleModalLabel"><span class="fas fa-edit"></span> Edit new announcement</h5>
            </div>
            <div class="announcement-card-header card m-3 border-0">
                <div class="announcement-card-header card-body border-0 p-1">
                    <span class="fa fa-info-circle fa-lg header-icon"></span>
                    <h5 class="align-header">ANNOUNCEMENT TEXT</h5>
                </div>
                <div class="announcement-card-body modal-body card border-0">
                    {{ form_start(editForm) }}
                    <div class="announcement-card-body">
                        <label for="exampleInputEmail1">ANNOUNCEMENT (SUPPORTS MARKDOWN)</label>
                        <textarea class="form-control" id="announcementText" rows="5" name="content"></textarea>
                    </div>
                </div>
            </div>
            <div class="card-footer border-0 bg-white pt-0">
                <div>
                    {{ form_widget(editForm.edit, {'left_icon': 'fas fa-check'}) }}
                    <button type="button" class="btn btn-light" data-dismiss="modal" aria-label="Close">
                        Cancel
                    </button>
                </div>
            </div>
            {{ form_end(editForm) }}
        </div>
    </div>
</div>

The JavaScript

<script type="text/javascript">
    $(".edit-button").click(function(){
        var content = $(this).data("content");
        alert(content);
    });

    $('#announcementEditModal').on('shown.bs.modal', function () {
        alert("modal open");
        document.getElementById("#announcementText").val(content);
    })
</script>

The alert("modal open") does not fire.I have tried'shown.bs.modal'and'show.bs.modal'`. I'm using Bootstrap 4.12

EDIT: Solution: Once I moved the JS to an announcements.js file where I was doing some stuff with my forms the trigger works.

d1596
  • 1,187
  • 3
  • 11
  • 25
  • 2
    Possible duplicate of [bootstrap jquery show.bs.modal event won't fire](https://stackoverflow.com/questions/19279629/bootstrap-jquery-show-bs-modal-event-wont-fire) – danilo Feb 20 '19 at 21:59

1 Answers1

1

It appears you either have an incomplete html code or have not shared it all with us.

  • dropdown-menu does not have a closing div.
  • wrap dropdown-menu inside dropdown or btn-group.
  • var content will not be available inside your shown.bs.modal function, so declare it globally, not a very good advice but for simplicity sake.

Fix Javascript error, since you are using jQuery, use it.

    document.getElementById("#announcementText").val(content); // val is not function

Replace with

document.getElementById("#announcementText").value = content;  
$("#announcementText").val(content); // or jQuery way

And here is the fiddle: https://jsfiddle.net/7onyuw9f/1/

Attempt 2

Below is an example of revealing module pattern to show how you can avoid global variables and also a lot cleaner. You can read more about this pattern here

 // Revealing Module Pattern
  var MyProject = MyProject || {}; // Your global object
  MyProject.Modal = function() { // Namespacing to Modal

    var content = ""; // now content is local to this function;

    var onEditClick = function() {
      $(".edit-button").click(function() {
        content = $(this).data("content");
        alert(content);
      });
    };

    var onModalShow = function() {
      $('#announcementEditModal').on('shown.bs.modal', function() {
        alert("modal open");
        // $("#announcementText").val(content); <-- jQuery way
        document.getElementById("announcementText").value = content;
      });
    };

    var init = function() {
      onEditClick();
      onModalShow();
    };

    return {
      init: init // expose this for other functions to call
    }

  }();

  $(document).ready(function() {
     MyProject.Modal.init();

 });

And the fiddle https://jsfiddle.net/x28s3uc9/1/

Hasta Tamang
  • 2,205
  • 1
  • 18
  • 17
  • The code should be complete I just omitted a lot to save space – d1596 Feb 20 '19 at 23:53
  • thanks for the response, sorry for the delay. So having it open up on button click works, but how can I pass it into the modal without using global variables? Also, I copy pasted your code at the bottom of my twig document and the alert doesnt fire when the modal (the one you created) opens. I changed the id of the modal you made – d1596 Feb 21 '19 at 17:56
  • You could wrap your whole code in a closure to avoid global's. Is your code wrapped inside $(document).ready(function(){ }); ? – Hasta Tamang Feb 21 '19 at 20:21
  • it is not I will add that. the alert for the modal opening trigger still isn't firing however – d1596 Feb 21 '19 at 20:27
  • do you get any console errors? your code works actually, i suspect there is something else that is wrong – Hasta Tamang Feb 21 '19 at 20:46
  • no console errors. must be something else. my code works on your end? – d1596 Feb 21 '19 at 20:49
  • Welp figured it out, I had a suspicion about this too. Once I moved the JS to an announcements.js file where I was doing some stuff with my forms the trigger works. Still unsure why... thanks for the hlep – d1596 Feb 21 '19 at 20:53
  • yes without the template code it works check the first fiddle, it is working right – Hasta Tamang Feb 21 '19 at 20:53