Search code examples
jquerydatatablelaravel-8

Why is Jquery not opening dialog from subsequent datable pages?


I have a list of over 3000 items populated into a table and paginated

       @foreach ($programs as $program)
                                        <tr>
                                            <td>{{ $program->id }}</td>
                                            <td>
                                                @if ($program->module == 'dmodule')
                                                    Direct Training Module
                                                @elseif ($program->module == 'emodule')
                                                    Equivalence Module
                                                @elseif ($program->module == 'gmodule')
                                                    Generalization Module
                                                @else
                                                    Transformation Module
                                                @endif
                                            </td>
                                            <td>
                                                {{ $program->title }}
                                            </td>
                                            <td>
                                                <div class="col-md-6">
                                                    <button type="button" class="btn btn-md programDetails"
                                                        data-id="{{ $program->id }}">
                                                        <i class="fa fa-file" aria-hidden="true"></i>
                                                    </button>
                                                </div>
                                            </td>
                                            <td>
                                                <div class="col-md-6">
                                                    <a href="{{ $program->video_link }}" class="btn btn-md"><i
                                                            class="fa fa-video" aria-hidden="true"></i></a>
                                                </div>
                                            </td>
                                            <td>
                                                <div class="col-md-6">
                                                    <a href="{{ route('program.print', $program->id) }}"
                                                        class="btn btn-md"><i class="fa fa-print"
                                                            aria-hidden="true"></i></a>
                                                </div>
                                            </td>
                                            <td>
                                                <div class="row">
                                                    <div class="col-md-4">
                                                        @if ($client->hasProgram($program->id))
                                                        @else
                                                        <button type="button" class="btn btn-xs btn-success programAttachment"
                                                        data-id="{{ $program->id }}" data-filter="{{ $client->id }}" >
                                                        <i class="fa fa-plus" aria-hidden="true"></i>
                                                    </button>
                                                        @endif
                                                    </div>
                                                    <div class="col-md-4">
                                                        <a href="{{ route('programs.edit', $program->id) }}"
                                                            class="btn btn-xs btn-warning" data-toggle="tooltip"
                                                            data-placement="top" title="Edit"><i class="fa fa-pen"
                                                                aria-hidden="true"></i></a>
                                                    </div>
                                                    <div class="col-md-4">
                                                        <form action="{{ route('programs.destroy', $program->id) }}"
                                                            method="POST" class="form-inline">
                                                            <button class="btn-danger btn-xs" data-toggle="tooltip"
                                                                data-placement="top" title="Delete"><i
                                                                    class="fa fa-trash"></i></button>
                                                            {{ method_field('DELETE') }}
                                                            {{ csrf_field() }}
                                                        </form>
                                                    </div>
                                                </div>

                                            </td>
                                        </tr>
                                    @endforeach

In the table I have button that is used to show a dialog with more information about the programs. This buttons event is handled by javascript code as follows

       $(document).ready(function() {

        $('.programDetails').on('click',function() {

            var progid = $(this).data('id');
            var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
            // AJAX request
            $.ajax({
                url: '/carriculumbank/program',
                type: 'post',
                data: {
                    _token: CSRF_TOKEN,
                    progid: progid
                },
                success: function(response) {
                    // Add response in Modal body
                    $('.modal-content').html(response);
                    $(".modal-dialog").css("width", "90%");
                    // Display Modal
                    $('#programModal').modal('show');
                }
            });
        });
    })

Now my problem is that this works only on the first page but not for any of the subsequent pages. What could be the issue and how can I solve it?


Solution

  • The

        $(document).ready(function() {
    
            $('.programDetails').on('click',function() {
                // Your code
            });
        })
    

    code waits for ready to be executed, which happens when the document is loaded and then creates a click event for all elements that have a programDetails class. This is why this works for the elements that already exist at the time when the document is loaded. However, the newer elements that are to be displayed when you click on the more button, did not exist when ready has been triggered and thus, even though they have a programDetails class at the time when they are generated, they did not have that class at document load because they did not exist then.

    Solution 1

    You can create an onclick handler when you generate your code

           @foreach ($programs as $program)
                                            <tr>
                                                <td>{{ $program->id }}</td>
                                                <td>
                                                    @if ($program->module == 'dmodule')
                                                        Direct Training Module
                                                    @elseif ($program->module == 'emodule')
                                                        Equivalence Module
                                                    @elseif ($program->module == 'gmodule')
                                                        Generalization Module
                                                    @else
                                                        Transformation Module
                                                    @endif
                                                </td>
                                                <td>
                                                    {{ $program->title }}
                                                </td>
                                                <td>
                                                    <div class="col-md-6">
                                                        <button type="button" class="btn btn-md programDetails" onclick="programDetailClick(this)"
                                                            data-id="{{ $program->id }}">
                                                            <i class="fa fa-file" aria-hidden="true"></i>
                                                        </button>
                                                    </div>
                                                </td>
                                                <td>
                                                    <div class="col-md-6">
                                                        <a href="{{ $program->video_link }}" class="btn btn-md"><i
                                                                class="fa fa-video" aria-hidden="true"></i></a>
                                                    </div>
                                                </td>
                                                <td>
                                                    <div class="col-md-6">
                                                        <a href="{{ route('program.print', $program->id) }}"
                                                            class="btn btn-md"><i class="fa fa-print"
                                                                aria-hidden="true"></i></a>
                                                    </div>
                                                </td>
                                                <td>
                                                    <div class="row">
                                                        <div class="col-md-4">
                                                            @if ($client->hasProgram($program->id))
                                                            @else
                                                            <button type="button" class="btn btn-xs btn-success programAttachment"
                                                            data-id="{{ $program->id }}" data-filter="{{ $client->id }}" >
                                                            <i class="fa fa-plus" aria-hidden="true"></i>
                                                        </button>
                                                            @endif
                                                        </div>
                                                        <div class="col-md-4">
                                                            <a href="{{ route('programs.edit', $program->id) }}"
                                                                class="btn btn-xs btn-warning" data-toggle="tooltip"
                                                                data-placement="top" title="Edit"><i class="fa fa-pen"
                                                                    aria-hidden="true"></i></a>
                                                        </div>
                                                        <div class="col-md-4">
                                                            <form action="{{ route('programs.destroy', $program->id) }}"
                                                                method="POST" class="form-inline">
                                                                <button class="btn-danger btn-xs" data-toggle="tooltip"
                                                                    data-placement="top" title="Delete"><i
                                                                        class="fa fa-trash"></i></button>
                                                                {{ method_field('DELETE') }}
                                                                {{ csrf_field() }}
                                                            </form>
                                                        </div>
                                                    </div>
    
                                                </td>
                                            </tr>
                                        @endforeach
    

    Note that in the above I have made only a small change. Accordingly, let's define the function:

        function programDetailClick(item) {
    
            var progid = $(item).data('id');
            var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
            // AJAX request
            $.ajax({
                url: '/carriculumbank/program',
                type: 'post',
                data: {
                    _token: CSRF_TOKEN,
                    progid: progid
                },
                success: function(response) {
                    // Add response in Modal body
                    $('.modal-content').html(response);
                    $(".modal-dialog").css("width", "90%");
                    // Display Modal
                    $('#programModal').modal('show');
                }
            });
        };
    

    The idea is that you create the click handler at the time you generate your stuff.

    Solution 2

    You can call .on() on an element that exists when the document is loaded and will contain all the elements for whom you intend to create a click event:

           $(document).ready(function() {
    
            $('body').on('click', '.programDetails',function() {
    
                var progid = $(this).data('id');
                var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
                // AJAX request
                $.ajax({
                    url: '/carriculumbank/program',
                    type: 'post',
                    data: {
                        _token: CSRF_TOKEN,
                        progid: progid
                    },
                    success: function(response) {
                        // Add response in Modal body
                        $('.modal-content').html(response);
                        $(".modal-dialog").css("width", "90%");
                        // Display Modal
                        $('#programModal').modal('show');
                    }
                });
            });
        })
    

    Note that I have used body as the outer selector, because I do not know enough about your structure, but it is advisable to choose a more specific outer selector, something that exists at document load, will contain all the tags that you want to create your click handler for, but that contains not much more. The more specific your selector is, the better.

    This approach will create the click handler for future tags as well, matching the inner selector once they are created with that class or that class is assigned to them.