Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.0][Known Bug] Modals won't show correctly in v4 #2187

Closed
GrigoreAlexandru opened this issue Oct 31, 2019 · 13 comments
Closed

[4.0][Known Bug] Modals won't show correctly in v4 #2187

GrigoreAlexandru opened this issue Oct 31, 2019 · 13 comments

Comments

@GrigoreAlexandru
Copy link
Contributor

Bug report

What I did

Make a custom view containing the modal example from coreui:

 <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
        Launch demo modal
    </button>

    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    ...
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-primary">Save changes</button>
                </div>
            </div>
        </div>
    </div>

Make a column with said view.

What I expected to happen

Modal should work correctly.

What happened

The backdrop is on top of everything else making closing the modal impossible.

image

What I've already tried to fix it

Play with z-index

Backpack, Laravel, PHP, DB version

Backpack v4, Laravel 6, php 7.2.2

Also tried with the demo project, same problem.

This method worked in v3.

@welcome
Copy link

welcome bot commented Oct 31, 2019

Hello there! Thanks for opening your first issue on this repo!

Just a heads-up: Here at Backpack we use Github Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.

Backpack communication mediums:

  • Bug Reports, Feature Requests - Github Issues (here);
  • Quick help (How do I do X) - Gitter Chatroom;
  • Long questions (I have done X and Y and it won't do Z wtf) - Stackoverflow, using the backpack-for-laravel tag;

Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.

Thank you!

--
Justin Case
The Backpack Robot

@schiman-ms
Copy link

It's not a solution, but worked for me. I added
data-backdrop="false"
to the modal to disable the backdrop

@GregaUNK
Copy link

GregaUNK commented Nov 5, 2019

Same problem here, but I found different solution.

In your blade file place your modal code between this tags:

@push('crud_fields_scripts')
<!-- MODAL CODE GOES HERE -->
@endpush

In this case it works without disabling backdrop.

@GrigoreAlexandru
Copy link
Contributor Author

@GregaUNK This doesn't work for me, it doesn't push anything at all. What is your setup? I have a custom view for a column containing a modal and its button.

@GregaUNK
Copy link

Oh, sorry! I used that as a solution for custom fields... not columns.
Maybe you could try out placing modal between:
@section('after_scripts')

@endsection

@pxpm
Copy link
Contributor

pxpm commented Nov 15, 2019

Hello guys,

thanks @GrigoreAlexandru @schiman-ms and @GregaUNK for taking time to have a look at this.

I really hadn't yet.

I labeled this as "question" because technicaly we don't support out of the box dialogs. It's possible using core UI, but might be some edge cases where it fails. And i think we found one.

Have you been able to fix this ?

How about add a button with blade file. Have you tried it ?

Best,
Pedro

@GrigoreAlexandru
Copy link
Contributor Author

@GregaUNK same problem, the backdrop is on top of everything.

@pxpm Didn't try but that seems a bit too much, I need to create a route and controller function for every modal, and get the data from db since I don't have access to the entry. I'd rather not have a backdrop.

Also, the table header is on top of the modal too.

image

Might be because of datatables ?

@tabacitu
Copy link
Member

Ugh. I remember facing this issue too, it was so painful, so I understand what you're going through, sorry @GrigoreAlexandru for the bad experience. I agree with @GregaUNK that the scripts should be pushed to the end of the file, like it's done in the DELETE button, for example. In a regular, non-CRUD setting, that's all you need to have the modal showing above the backdrop:
Screenshot 2019-11-23 at 10 32 10

This StackOverflow issue explains the problem, and it's because of how Bootstrap 4 modals work now. You can't include the modal HTML anywhere you want, you have to have it directly in your <body> element to prevent this.

Now, if you place the modal directly inside a CRUD column, it still won't work, because the columns are loaded with AJAX. And an AJAX-loaded HTML can't push stuff to the main window that easily.

The best solution I can come up with (right now) would be to use the Backpack Widgets functionality to your advantage, which allows you to easily push content in the main page (outside the datatables). It feels a little like a hack, but it's the only solution I can think of right now. There might be a better one though, totally open to suggestions. I think we should probably have a tutorial / how-to / example on this, since I imagine more people would want to have a column or button that open a modal.

The solution would basically be to:

  • create a column as you have, that has the trigger button; that trigger button will be loaded with AJAX, and has all the information you need as data attributes; its click action would be to trigger a custom JS function, let's call that openRisksModal(); so the actual column would read something like:
<a   href="javascript:void(0)" 
	class="btn btn-sm btn-primary"
	onclick="openRisksModal(this)" 
	data-something="{{ $entry->smth }}"
	data-something-else="{{ $entry->smth_else }}" 
	>Open Risks Modal</a>
  • create a widget that you'd only use on the List operation, for this particular CRUD; that widget pushes the modal code to the after_scripts stack (which is conveniently directly inside <body> and at the end of the file, so exactly where Bootstrap 4 wants its modal code); in this widget there should also be your openRisksModal() JS function, that replaces the modal content with the one from the trigger button, and opens the modal; so it would read something like:
@push('after_scripts')
<div class="modal fade" id="risksModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                ...
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>

<script>
function openRisksModal(button) {
  var button = $(button);
  var smth = button.attr('data-smth');
  var smth_else = button.attr('data-smth-else');

  // TODO: replace smth and smth-else inside the modal
  // TODO: open the modal
}
</script>
@endpush

I took inspiration from the clone/delete button - I suggest you take a look at the clone button too.

Please let me know if this doesn't work for you either. I'm open to better ways to do this - it's such a pain that Bootstrap has changed something so crucial with little to no benefit other than code strictness. But hey ho - that's the situation we're in.

Cheers!

@mpixelz
Copy link

mpixelz commented Dec 3, 2019

same issue here.. @push('after_scripts') worked on dashboard and on views BUT not on crud pages.
I have column on my crud which triggers modal windows and load data for that entry.. i also have action buttons doing the same... but they all have stopped working because of this backdrop issue.. Its been almost 2 weeks ive been trying to upgrade from v3 to v4 but such issues keep coming up..

any one came up with some solution? :(

@mpixelz
Copy link

mpixelz commented Dec 3, 2019

i ended up creating a clone of list.blade.php from backpack for each of my crud and added the modal views and their js manually in the footer.. working for now but its a patch not a fix.

@tabacitu tabacitu changed the title Modals won't show correctly in v4 [4.0][Known Bug] Modals won't show correctly in v4 Dec 16, 2019
@timbertens
Copy link
Contributor

timbertens commented Dec 22, 2019

Another workaround I'm using shows the modal as intended in BS4 and without having to change too much code is using this jQuery code on pages with modals

    $(document).on('show.bs.modal', '.modal', function () {
        $(this).appendTo('body');
    });

@tabacitu
Copy link
Member

Excellent solution @timbertens ! Let me do a summary and we can close this.

TLDR

The source of the problem is in Bootstrap 4, not Backpack. And... "it's not a bug, it's a feature" so it's not going to get fixed. The .modal element needs to be placed directly under body. Always.

Solution 1: Use JS/Blade to push your view to a stack the before_scripts/after_scripts stack. That way your .modal will be directly under body.

Solution 2: Use JS/jQuery to push your .modal element inside .body.

Solution 3: Use JS/jQuery to always push your .modal elements under .body.

    $(document).on('show.bs.modal', '.modal', function () {
        $(this).appendTo('body');
    });

@apollosiadyr
Copy link

Hello guys,

Sorry for opening this, but I found another solution that I think it's much cleaner and can help you if you need access modal in a Js component.

I created a modal blade component with the default bootstrap 4 modal code. I added to the modal this tag: data-backdrop="false" in order to remove the default black-ish background,.I removed the open trigger from the button and the close triggers from the close and X button.

After that, I added to my modal component this div: <div class="custom-modal-backdrop"></div> and this styles:
.custom-modal-backdrop { background-color: #161c2d; height: 100vh; left: 0; position: fixed; top: 0; width: 100vw; z-index: 1040; display: none; } .custom-modal-backdrop.show { opacity: .5; }.
This is the same code from the bootstrap modal-backdrop class.

The last think I did was to add my custom show and hide logic that will do something like this:

show () {
    $(`#${this.id}`).modal('show')
    $('.custom-modal-backdrop').toggleClass('show').toggle()
},
hide() {
    $(`#${this.id}`).modal('hide')
    $('.custom-modal-backdrop').toggleClass('show').toggle()
}

In this moment we have a working modal in a CRUD operation that can be reused. I actually created a modal layout for this and I can reuse it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants