The modal component is useful for displaying content that is overlayed on the primary page content.
Modals are mostly displayed when an action is triggered, say when a button is clicked.
All BladewindUI modals are invoked via a javascript helper function bundled with the component.
showModal('name-of-modal');
. Like with all BladewindUI components,
the syntax for cooking up a modal is very simple.
<x-bladewind::button
show_close_icon="true"
onclick="showModal('tnc-agreement')">
Basic modal
</x-bladewind::button>
<x-bladewind::button
onclick="showModal('tnc-agreement-titled')">
Basic modal with a title
</x-bladewind::button>
<x-bladewind::modal
name="tnc-agreement">
Please agree to the terms and conditions of
the agreement before proceeding.
</x-bladewind::modal>
<x-bladewind::modal
name="tnc-agreement-titled"
title="Agree or Disagree">
Please agree to the terms and conditions of
the agreement before proceeding.
</x-bladewind::modal>
name
attribute.
You can have several modals on the same page but it is very important to provide unique names for each modal.
Clicking on the backdrop of the modal or on the cancel button will by default dismiss the modal. You probably guessed it. The hideModal('name-of-modal');
helper function is called to dismiss modals.
It is possible to prevent the backdrop or the cancel button from closing the modal. See the Non-dismissed modal section below.
The BladewindUI modal component comes prebuilt with some default types for the common use cases.
This can be achieved by setting the type
attribute on the modal component. The default type=""
.
All the type attribute does is append the appropriate icons that match the type of modal.
This requires that you set type="info"
on the modal component. The default icon changes to a blue info icon.
<x-bladewind::button onclick="showModal('info')">
Info Modal
</x-bladewind::button>
<x-bladewind::modal
type="info"
title="General Info"
name="info">
We really think you should buy some Bitcoin
despite it's ups and dowms. What sayeth thou?
</x-bladewind::modal>
This requires that you set type="error"
on the modal component. The default icon changes to a red exclamation mark.
<x-bladewind::button onclick="showModal('error')">
Error Modal
</x-bladewind::button>
<x-bladewind::modal
type="error"
title="Delete Not Allowed"
name="error">
You do not have permissions to delete this user.
</x-bladewind::modal>
This requires that you set type="warning"
on the modal component. The default icon changes to a yellow bell icon.
<x-bladewind::button onclick="showModal('warning')">
Warning Modal
</x-bladewind::button>
<x-bladewind::modal
type="warning"
title="First warning"
name="warning">
Hmmm...This is your first warning.
Two more warnings and you are off this platform.
</x-bladewind::modal>
This requires that you set type="success"
on the modal component. The default icon changes to a green thumbs up icon.
<x-bladewind::button onclick="showModal('success')">
Success Modal
</x-bladewind::button>
<x-bladewind::modal
type="success"
title="User Deleted"
name="success">
Yayy.. User deleted successfully
</x-bladewind::modal>
Some users prefer to have their action buttons span the entire width of the modal. To achieve this simply set stretched_action_buttons="true"
on the modal component.
<x-bladewind::button onclick="showModal('stretched')">
Success Modal
</x-bladewind::button>
<x-bladewind::modal
title="Stretched Buttons"
stretched_action_buttons="true"
name="stretched">
The action buttons in this modal have been stretched.
This means each button gets its own line. Cool right?
</x-bladewind::modal>
The backdrop can be customized to have different intensities of the blur by specifying blur_size
.
The available values are none
, small
, medium
, large
, xl
, xxl
, omg
.
<x-bladewind::button onclick="showModal('noblur')">
No Blur
</x-bladewind::button>
<x-bladewind::modal
title="See Through Me"
blur_size="none"
name="noblur">
The backdrop of this modal is not blurred.
You can see all the content behind the backdrop.
</x-bladewind::modal>
The default types use predefined icons. You may want to use your own icons in the modal component to give your context to your message.
You can set the icon
attribute to any icon name on Heroicons. This modal icon is displayed using the
BladewindUI Icon component. Note the use of the icon_css
attribute as well. That is how to apply extra styling to the custom icon.
<x-bladewind::button onclick="showModal('iconic')">
Custom Icon Modal
</x-bladewind::button>
<x-bladewind::modal
icon="folder-arrow-down"
icon_css="bg-gray-500 text-white p-2.5 rounded-full"
title="Large File Size"
name="info">
The file you are trying to download is very big.
Do you still want to continue with the download?
</x-bladewind::modal>
You may want to use a custom icon but with one of the predefined states. For example, you may want to display a success modal but you don't like the default check-circle icon used.
It is possible to use a custom icon with any of the predefined states. Simply set both the type
and icon
attributes.
<x-bladewind::button
onclick="showModal('iconic-info')">
Info
</x-bladewind::button>
<x-bladewind::modal
title="Large File Size"
type="warning"
name="iconic-warning"
icon="folder-arrow-down">
The file you are trying to download is very big.
Do you still want to continue with the download?
</x-bladewind::modal>
You could tell the above modals looked quite squashed. The BladewindUI modal component comes with a size option that allows your content to breath in the modals.
This can be achieved by setting the size
attribute on the modal component. The default size="small"
.
Below are all the available sizes. All sizes are the same on mobile.
This requires that you set size="tiny"
on the modal component.
<x-bladewind::button onclick="showModal('tiny-modal')">
Tiny Modal
</x-bladewind::button>
<x-bladewind::modal
size="tiny"
title="Tiny Modal"
name="tiny-modal">
I am the tiniest in the modal family. Don't hate.
</x-bladewind::modal>
This requires that you set size="small"
on the modal component.
<x-bladewind::button onclick="showModal('small-modal')">
Small Modal
</x-bladewind::button>
<x-bladewind::modal
size="small"
title="Small Modal"
name="small-modal">
I am the smallest in the modal family. Don't hate.
</x-bladewind::modal>
This requires that you set size="medium"
on the modal component.
This is the default so it is not really necessary to set the attribute on the component if you want to use the medium modal size.
<x-bladewind::button onclick="showModal('medium-modal')">
Medium Modal
</x-bladewind::button>
<x-bladewind::modal
title="Medium Modal"
size="modal"
name="medium-modal">
I am the medium sized modal.
Also the default if you do not set a size.
</x-bladewind::modal>
This requires that you set size="big"
on the modal component.
<x-bladewind::button onclick="showModal('big-modal')">
Big Modal
</x-bladewind::button>
<x-bladewind::modal
size="big"
title="Big Modal"
name="big-modal">
English can be quite confusing.
How is big different from large? You be the judge!
</x-bladewind::modal>
This requires that you set size="large"
on the modal component.
<x-bladewind::button onclick="showModal('large-modal')">
Large Modal
</x-bladewind::button>
<x-bladewind::modal
size="large"
title="Large Modal"
name="large-modal">
I am the large modal. If I am not large enough to contain
your needs, check out my xl brother.
</x-bladewind::modal>
This requires that you set size="xl"
on the modal component.
<x-bladewind::button onclick="showModal('xl-modal')">
Xl Modal
</x-bladewind::button>
<x-bladewind::modal
size="xl"
title="XL Modal"
name="xl-modal">
I am the extra large modal. How do you like my size now.
You could fill me up with some much needed content.
</x-bladewind::modal>
This requires that you set size="omg"
on the modal component.
<x-bladewind::button onclick="showModal('omg-modal')">
OMG Modal
</x-bladewind::button>
<x-bladewind::modal
size="omg"
title="Full Width Modal"
name="omg-modal">
I am the full width modal. My nickname is OMG.
I take up the entire screen. I do not know why
you will need a modal like this but well, like they say,
it is better to have and not use that need and not have.
</x-bladewind::modal>
The modal component by default shows a Cancel
and Okay
button.
Both buttons by default close the modal when clicked. It is possible to show either of the buttons or even none of the buttons.
If you don't want your buttons to say Cancel and Okay, set the cancel_button_label
and
ok_button_label
attributes to whatever text you want the buttons to display.
To hide the cancel
button, simply set cancel_button_label=""
. When the button label is blank, the button won't be displayed.
In the same way, to hide the primary button, the okay button in this case, simply set ok_button_label=""
. When the button label is blank, the button won't be displayed.
<x-bladewind::button onclick="showModal('no-cancel')">
No cancel button
</x-bladewind::button>
<x-bladewind::modal
title="No Cancel Button"
name="no-cancel"
cancel_button_label="">
I have no cancel button. Just okay and that is fine.
</x-bladewind::modal>
<x-bladewind::button onclick="showModal('no-okay')">
No okay button
</x-bladewind::button>
<x-bladewind::modal
title="No Okay Button"
name="no-okay"
ok_button_label="">
I have no okay button.
Just cancel this thing and let's all go home.
</x-bladewind::modal>
Your guess is right. To hide both the okay and cancel buttons you can set
cancel_button_label=""
and ok_button_label=""
. However, there is a shorter way to achieve this.
Instead, set the show_action_buttons="false"
attribute. This will hide both action buttons.
A no-action-buttons modal can be useful if you want to have a form in a modal with its own button that submits the form.
<x-bladewind::button onclick="showModal('no-action-buttons')">
No action buttons
</x-bladewind::button>
<x-bladewind::modal
title="No Action Buttons"
name="no-action-buttons"
show_action_buttons="false">
I have no action buttons. Only the backdrop can close me now.
</x-bladewind::modal>
By default both action buttons close the modal. It is possible to change these default actions. To achieve this you will need to
set the cancel_button_action
and ok_button_action
attributes.
The default values are cancel_button_action="close"
and ok_button_action="close"
.
The attributes expect javascript functions as the values.
<x-bladewind::button onclick="showModal('custom-actions')">
CLick me for custom actions
</x-bladewind::button>
<x-bladewind::modal
size="big"
type="warning"
title="Confirm User Deletion"
ok_button_action="alert('as you wish')"
cancel_button_action="alert('good choice')"
close_after_action="false"
name="custom-actions"
ok_button_label="Yes, delete"
cancel_button_label="don't delete">
Are you sure you want to delete this user? This action cannot be undone.
</x-bladewind::modal>
You will notice from the custom actions example above that we introduced the attribute close_after_action="false"
.
By default, the modal is dismissed after clicking any of the action buttons. Setting this attribute to false
will ensure the modal stays open after clicking any of the action buttons.
Closing of the modal is delegated mostly to the Cancel or Close button in the footer of the modal. It is, however, possible to close modals using a close icon placed in the top right of the modal.
To enable this, you will need to set show_close_icon="true"
. Here is an example.
By default the action buttons are right aligned but left aligned if the modal size="tiny"
. To change the alignment of the action buttons, set the align_buttons
attribute to either left, center or right.
By default the modal component can be closed using the backdrop or any of the action buttons. There are cases when you really don't want the user to dismiss the modal until a choice has been made or an action has been performed.
Getting this result is simple. Just set backdrop_can_close="false"
. If you are using the modals with the action buttons you will also need to set the actions of each button. See Action Buttons above.
In this example, we assume your app is very data sensitive and you want users to be able to lock their screens when stepping away from their computers.
<x-bladewind::button onclick="showModal('lock-screen')">
<svg>...</svg> lock the screen
</x-bladewind::button>
<x-bladewind::modal
show_action_buttons="false"
backdrop_can_close="false"
name="lock-screen">
<div class="flex mx-auto justify-center my-2">
<x-bladewind.avatar class="" image="/path/to/the/image/file" />
</div>
<div class="my-4">
You will need to unlock the screen to continue using this application.
</div>
<x-bladewind.input
placeholder="Enter your password to unlock"
type="password" />
<x-bladewind::button class="w-full">Check password</x-bladewind::button>
</x-bladewind::modal>
There may be instances where you want to load a form in a modal and only submit the form when the user clicks on the Okay or Save action button. Submitting the form should also happen ONLY if all validations have passed. The modal component itself does not provide a magical way of achieving this but the code below implements the logic we just described.
// the modal and its form
<x-bladewind::modal
backdrop_can_close="false"
name="form-mode"
ok_button_action="saveProfile()"
ok_button_label="Update"
close_after_action="false"
>
<form method="post" action="" class="profile-form">
@csrf
<b class="mt-0">Edit Your Profile</b>
<div class="grid grid-cols-2 gap-4 mt-6">
<x-bladewind::input required="true" name="first_name"
error_message="Please enter your first name" label="First name" />
<x-bladewind::input required="true" name="last_name"
error_message="Please enter your last name" label="Last name" />
</div>
<x-bladewind::input required="true" name="email"
error_message="Please enter your email" label="Email address" />
<x-bladewind::input numeric="true" name="mobile" label="Mobile" />
</form>
</x-bladewind::modal>
// the script called by the Update button
saveProfile = () => {
if(validateForm('.profile-form')){
domEl('.profile-form').submit();
} else {
return false;
}
}
The "Update" button from the modal above calls a saveProfile()
Javascript function when it is clicked on
ok_button_action="saveProfile()"
. In the Javascript function, we validate the profile form
class="profile-form"
using the
validateForm()
helper function available in BladewindUI. We then submit the form if all required fields are not empty.
The form above uses method="get"
so you can see the form fields passed as query strings in the URL.
By default BladewindUI modals close when either of the action buttons are clicked. To prevent our modal from closing when the user clicks on the Update button, we
set the close_after_action="false"
attribute.
In the next example our form is submitted via Ajax. The example makes use of the Process Indicator component to show progress.
// the modal and its form.
// take note of the processing and process-complete components
<x-bladewind::modal
backdrop_can_close="false"
name="form-mode-ajax"
ok_button_action="saveProfileAjax()"
ok_button_label="Update"
close_after_action="false">
<form method="get" action="" class="profile-form-ajax">
@csrf
<b>Edit Your Profile</b>
<div class="grid grid-cols-2 gap-4 mt-6">
<x-bladewind::input required="true" name="first_name2"
label="First name" error_message="Please enter your first name" />
<x-bladewind::input required="true" name="last_name2"
label="Last name" error_message="Please enter your last name" />
</div>
<x-bladewind::input required="true" name="email2"
label="Email address" error_message="Please enter your email" />
<x-bladewind::input numeric="true" name="mobile2" label="Mobile" />
</form>
<x-bladewind::processing
name="profile-updating"
message="Updating your profile." />
<x-bladewind::process-complete
name="profile-update-yes"
process_completed_as="passed"
button_label="Done"
button_action="hideModal('form-mode-ajax')"
message="Profile updated successfully." />
</x-bladewind::modal>
// the script called by the Update button
saveProfileAjax = () => {
if(validateForm('.profile-form-ajax')){
// show process indicator while you make your ajax call
unhide('.profile-updating');
hide('.profile-form-ajax');
hideModalActionButtons('form-mode-ajax');
// make the call
makeAjaxCall(serialize('.profile-form-ajax'));
} else {
return false;
}
}
makeAjaxCall = (formData) => {
// this is a dummy function but your real function
// will make a call and post all the data
setTimeout(() => {
// do these when your ajax call is done saving your data
hide('.profile-updating');
unhide('.profile-update-yes')
}, 5000);
}
The example above follows the same principle as the first, except we submit the form via Ajax.
When the Update button is clicked the saveProfileAjax()
function is called.
This validates the form and hides the action buttons of the modal if validation passes.
We don't want the user canceling the form submission or clicking the Update button a second time.
The form is also hidden while the process indicator is displayed. Lastly, the form data is passed to the makeAjaxCall()
function.
You will need to flesh out the makeAjaxCall() function yourself to make the actual ajax call. The idea however is, once the ajax call returns
a status, we hide the process indicator and display the process-complete component. The Done button on the process-complete
component closes the modal when clicked on (button_action="hideModal('form-mode-ajax')"
).
This example used only one process-complete component. Normally you will have two process-complete components. One to show if the process failed and the other to show if the process succeeded.
hide()
, unhide()
, hideModalActionButtons()
, serialize()
and validateForm()
are all helper functions available in BladewindUI.
The third and final option is to hide the Okay button of the modal and let the submit button sit in the form itself. The modal will only have a cancel button to close the form if needed.
// the modal and its form.
<x-bladewind::modal
backdrop_can_close="false"
name="form-mode-simple"
ok_button_label=""
>
<form method="get" action="" class="profile-form-simple"
onsubmit="return saveProfileSimple()">
@csrf
<b>Edit Your Profile</b>
<div class="grid grid-cols-2 gap-4 mt-6">
<x-bladewind::input required="true" name="first_name3"
label="First name" error_message="Please enter your first name" />
<x-bladewind::input required="true" name="last_name3"
label="Last name" error_message="Please enter your last name" />
</div>
<x-bladewind::input required="true" name="email3"
label="Email address" error_message="Please enter your email" />
<x-bladewind::input numeric="true" name="mobile3"
label="Mobile" />
<x-bladewind::button can_submit="true" class="w-full mt-2">
Update Profile
</x-bladewind::button>
</form>
</x-bladewind::modal>
// the script called by the Update button
saveProfileSimple = () => {
if(validateForm('.profile-form-simple')){
return domEl('.profile-form-simple').submit();
}
return false;
}
The example above sets ok_button_label=""
to hide the Okay button.
We then set the onsubmit
attribute of the form to call a Javascript function when the form is submitted. onsubmit="return saveProfileSimple()"
.
Take note of the return
keyword. Without this, the form will submit when clicked on, even if validation fails.
To make the button submittable we added the can_submit="true"
attribute to the button component. The Javascript
function returns false when validation fails or true if otherwise. That is really all we need to do in this case. One of these three options should hopefully serve your use-case.
The table below shows a comprehensive list of all the attributes available for the Modal component.
Option | Default | Available Values |
---|---|---|
type | blank | info error warning success |
title | blank | String. Defines the title of the modal. |
name | 'bw-modal-'.uniqid() | Uniquely identifies a modal. This attribute is very important if you want to prevent erratic behaviour of modals. |
ok_button_label | okay | Specify the label to be displayed on the primary action button. |
cancel_button_label | cancel | Specify the label to be displayed on the secondary action button. |
ok_button_action | close | Expects a javascript function that will be called when the primary action button is clicked. |
cancel_button_action | close | Expects a javascript function that will be called when the secondary action button is clicked. |
close_after_action | true | Specify whether the modal stays open after any of the action buttons are clicked.true false |
backdrop_can_close | true | Specify whether clicking on the modal backdrop should close the modal.true false |
blur_size | medium | Specify the intensity of the backdrop blur.none small
medium large
xl xxl
omg
|
show_action_buttons | true | Specify whether the action buttons should be displayed.true false |
align_buttons | right | Specify how the action buttons should be aligned in the modal footer.left center right |
stretch_action_buttons | false | Specify whether the action buttons should stretch the entire width of the modal. Each button will be on its own line.true false |
size | big | Defines the size of the modal. Arranged from smallest to largest. tiny small medium
big large xl omg |
show_close_icon | false | Display a close icon in the top right corner of the modal window. Clicking on this will close the modal or behave the same as the Cancel button if it exists in the modal footer.
true false |
body_css | blank | Any extra css classes to add to the modal body. |
footer_css | blank | Any extra css classes to add to the modal footer. |
<x-bladewind::modal
type="warning"
title="Modal with all features"
name="full-modal"
ok_button_label="yes"
cancel_button_label="no"
close_after_action="false"
ok_button_action="alert('say ok')"
cancel_button_action="alert('say nay')"
backdrop_can_close="false"
show_action_buttons="false"
show_close_icon="true"
blur_size="xxl"
size="medium"
class="shadow-sm">
...
</x-bladewind::modal>
resources > views > components > bladewind > modal.blade.php
and
resources > views > components > bladewind > modal-icons.blade.php