How to use the bootstrap modal component to customize alert,confirm and modal dialogs _javascript tips

Source: Internet
Author: User
Tags button type call back commit

This article I will introduce the pop-up window component modal in bootstrap, this component is simple and easy to use, the effect atmosphere is beautiful and very practical!

Many items Customize dialog box components because of the poor experience of the alert and confirm boxes provided by browsers and the fact that browsers do not provide a standard bullet box function that displays custom HTML in a dialog box. This article describes their own modal components based on bootstrap in the project, custom alert,confirm and modal dialog box experience, relatively simple and practical, hope to have reference value for you.

1. Example Show

Detailed code can be downloaded from the previous download link download source to understand that the code is not large, these three components add up to only 200 more lines

If you have JavaScript component development experience, my code at this level believes you can see it all at once. The source code I also gave a demo, this demo simulation of a more close to the reality of the needs of a scene:

1 Users click on a button on the interface, open a previously defined modal box:

2 users in the Open modal box to fill out some forms, click OK, will trigger some check:

When no email is filled in:

After filling in the email:

These two hints are actually confirm to demonstrate the effects of alert and the effect, and may not actually be so awkward.

3 When prompted password is empty, the careful person will find that the OK button is in a disabled state, this consideration is because the determination button will ultimately complete a number of asynchronous tasks, before the asynchronous task successfully completes, I hope the modal components do not close, And can control the clicked button can not be repeated clicks;

4 I used settimeout to simulate an asynchronous task that, after clicking the OK button, the 3s would not be recalled, and:

When the email input admin@admin, will give a prompt for the success of the submission, after the confirmation will be closed all the bomb frame:

When the email input is worth the time, it will give a prompt to submit the failure, and the modal box will still appear there:

In the component definition, especially the registration button, I added some AOP programming, while using jquery delay object to implement the asynchronous programming I need, please read the source code, there are questions can be exchanged in the comments area.

2. Component Requirements

Sometimes in order to write a useful component, it is necessary to have its approximate prototype and the interface provided externally to determine the most important work of this component has been completed, although the code has not yet started. For these components to be written in this article, the prototype and invocation forms of the components I want are as follows:

1) Custom Alert box

The prototype is:

The call requires a maximum of two parameters, one msg is used to pass the hint to display, and a OnOK is used to handle the callback when the button is clicked, in the form of the following 2 types:

1
Alert (' The order status you selected does not match the current operation condition, please refresh the list to display the latest data before continuing! ');
2
Alert ({
msg: ') The order status you selected does not match the current operation condition, please refresh the list to display the latest data before continuing! ',
onok:function () {
}

The first is a situation where there is no callback, then the direct delivery of MSG, the second is a callback case, the options object to pass the MSG and Onoks callback these two parameters. Regardless of the OnOK callback, turn off the frame when you click the button.

2) Custom Confirm box

The prototype of this box is only one button to the alert box:

There is only one form of invocation:

Confirm ({
msg: ' The order status you selected does not match the condition of the current operation, please confirm whether you want to continue the operation! ',
onok:function () {
},
oncancel:function () {
}

OnCancel is the callback when you click the Cancel button. Regardless of OnOK and OnCancel callback, turn off the frame when you click the button. OnCancel callbacks can be without.

3) Custom Modal box

Prototype:

Call form:

var modal = new modal ({
title: ',
content: ',
width:600,
buttons: [
{
html: ' <button type= "Button" class= "btn btn-sm btn-primary btn-ok" > OK </button> ',
selector: '. Btn-ok ',
callback: function () {
//Click the callback for the OK button
}
},
{
html: ' <button type= ' button ' class= ' btn btn-sm Btn-default Btn-cancel "> Cancellation </button>",
selector: '. Btn-cancel ',
callback:function () {
// Click the Cancel button's
callback
}
],
oncontentready:function () {
///When modal is added to the DOM and the initialization is complete, the event callback Each modal instance this callback will only be triggered once
},
oncontentchange:function () {
//event callback when a similar method of invoking Modal.setcontent changes the modal content
},
onmodalshow:function () {
///Modal.open event callback} that fires whenever a similar method is invoked
to display modal,
onmodalhide: function () {
//the event callback} that fires whenever a similar method is invoked to hide the modal modal.hide
);
$ (' #btn-audit '). Click (function () {
modal.open ();

Unlike alert and confirm, only one instance of alert and confirm is needed on a page, but multiple instances of modal may be required, so each modal object needs to be new individually. Because each modal is not the same thing to accomplish, so:

Need a title parameter to set the name, to express what this modal is dealing with;

The content parameter represents the HTML contents of the modal;

Width parameter to set modal, modal height to keep auto;

The buttons parameter is used to configure the button above the modal, in general modal components only need two buttons (OK and cancel) is enough, but there are a few cases require multiple buttons, so the button to make configuration of a relatively flexible way, each button with three parameters to configure, HTML represents the HTML structure of the button, selector to facilitate the registration callback by way of event delegate, callback configuration button click Callback;

Oncontentready This event callback, you can take the initiative to initialize some components of the modal internal HTML when the modal is initialized, because the component initialization is usually only once, so it is appropriate to put it in the callback.

Oncontentchange callbacks are useful when a modal needs to be used as a different scenario to display different HTML content, but it's not very useful, and the logic is slightly more complicated to handle, if a modal instance does just one thing, Oncontentchange This callback will not be used;

Onmodalshow this callback in each display modal, the use of a lot of scenes, such as a modal used to fill out some form content, the next time you need to fill out the form to be used for users, this processing in the callback inside the processing is more appropriate;

Onmodalhide This callback is useful, but there are not many scenarios to use, which is a reserved interface.

4) Other requirements

All types of frames are made into virtual mode, and a mask is added to the display box.

All boxes do not need to support drag and resize;

The caption of the alert and dialog boxes, the number of buttons, the button position, and the button text are fixed.

As a matter of fact:

Mask this effect, the bootstrap of the modal component itself has been supported;

Drag and resize, this feature is icing on the cake, but for the software itself, and there must be a number of additional benefits, so I choose not to do this redundant processing;

Alert and dialog do not need to be too personalized, to be able to unify style, to change the browser's original frame experience.

5 Demo to invoke the instance

Next, I'll show you how to invoke these components in actual use after I've completed these three component developments:

 var modal = new Modal ({title: ' Test Modal ', Content: $ (' #modal-tpl '). html (), width:500, OnO K:function () {var $form = this. $modal. Find (' form '); var data = $form. Serializearray (); var postdata = {}; Data.foreach (fu
Nction (obj) {postdata[obj.name] = obj.value;}); if (!postdata.email) {Alert (' Please enter email! '); return false;} var deferred = $.
Deferred (); if (!postdata.password) {Confirm ({msg: ' Password is empty, do you want to continue?)
', Onok:function () {_post ();}, Oncancel:function () {deferred.reject ();}})
else {_post ();} return $.when (deferred); function _post () {//Simulate asynchronous Task settimeout (function () {if (Postdata.email = = ' Admin@admin ') {Alert ({msg: ' Commit successful!)
', Onok:function () {deferred.resolve ();}}); ' Else {Alert ({msg: ' Commit failed!
', Onok:function () {deferred.reject ();}});
}},3000);
}, Onmodalshow:function () {var $form = this. $modal. Find (' form '); $form [0].reset ();}}); $ (' #btn-modal '). Click (function () {Modal.open ();}); 

3. Implementation Essentials

1 The most basic point, to the bootstrap of the modal component source have some understanding:

Initialization mode: $modal. Modal ()

Open: $modal. Modal (' show ')

Off: $modal. Modal (hide)

Events: Bootstrap Most of the components with transition effects are in pairs, and one is now, and one is complete, the modal component defines 2 pairs:

Show.bs.modal and Shown.bs.modal,hide.bs.modal and Hidden.bs.modal.

These two pairs of events are triggered before and after the open and closed transition effects are performed. From the component requirements that I want to define, I need show.bs.modal and hidden.bs.modal to define the components, distributing the events of the components that you define when you listen to the bootstrap modal component distributing these two events:

Modalshow and Modalhide.

Options:

Backdrop: Whether to show the mask;
Keyboard: Whether the keyboard callback is supported;
Show: is displayed immediately after initialization is completed.

All three options are true by default, but when I define a component, I configure it to false and the keyboard callback feature is not considered for the moment, so it is configured to true;

Call bootstrap modal initialization of course can not immediately display the frame, so also can not be configured for True;backdrop configured to False for the reason of the next introduction.

2) Mask Processing

If you enable the bootstrap mask, you will find that when you click on the Mask section, the frame will automatically turn off, this is not the virtual mode effect I expected, so the backdrop must be configured to False. However, when you configure this option to false, a new problem is raised, that is, the component does not have a mask effect, so in order to accommodate both problems, you can write a simple mask:

var $body = $ (document.body),
backdrop = (function () {
var $backDrop,
count = 0,
create = function () {
    $backDrop = $ (' <div class= ' modal-backdrop fade in ' ></div> '). Appendto ($body);
return {
show:function () {
! $backDrop && Create ();
$backDrop [0].style.display = ' block ';
count++;
},
hide:function () {
count--;
if (!count) {
$backDrop. Remove ();
$backDrop = undefined}}}

The reason for the introduction of the count variable in this code is that backdrop is a global singleton object that invokes the backdrop Show method when invoking the open method of multiple modal instances, in order to ensure that when the backdrop hide method is invoked, To ensure that all modal instances are closed and then hidden backdrop, a count variable is added to record how many times the backdrop Show method was invoked, and only if Count is 0, Calling the backdrop Hide method will actually hide the backdrop.

3 The default value definition of the option for the component

Modaldialog.defaults = {
title: ',
content: ',
width:600,
buttons: [
{
html: ' <button Type= "button" class= "btn btn-sm btn-primary btn-ok" > OK </button> ',
selector: '. Btn-ok ',
callback: Getdefaultbtncallbackproxy (' OnOK ')
},
{
html: ' <button type= ' button ' class= ' btn btn-sm btn-default Btn-cancel "> Cancellation </button>",
selector: '. Btn-cancel ',
callback:getdefaultbtncallbackproxy (' OnCancel ')
}
],
OnOK: $.noop,
oncancel: $.noop, Oncontentready
: $.noop,
Oncontentchange: $.noop,//content callback after replacement
Onmodalshow: $.noop,
onmodalhide: callback after $.noop//modal shutdown

Configure the two default buttons via buttons, OK and cancel, then in order to simplify the callback configuration of the two default buttons, extend the interface of these two buttons further to the previous level, OnOK and OnCancel will be called at the time of Click OK and Cancel, these two options are completely function callback, Unlike Oncontentready, this belongs to the event callback. Getdefaultbtncallbackproxy is used to assist in registering OnOK and OnCancel:

var getdefaultbtncallbackproxy = function (callbackname) {return
function () {
var opts = this.options,
call back = Opts[callbackname] && typeof opts[callbackname] = = ' function '? Opts[callbackname]: ';
Return callback && callback.apply (this, arguments);
}

This will be bound to the modal instance.

4 constructor:

function Modaldialog (options) {
this.options = this.getoptions (options);
this. $modal = undefined;
this. $modalTitle = undefined;
this. $modalBody = undefined;
this. $modalFooter = undefined;
this.state = undefined;
}

This is mainly a declaration of the use of some of the instance variables.

5 key prototyping methods and functions

Open:function (state) {
this.state = state;
! this. $modal && Initmodal (this, this.options);
Backdrop.show ();
this. $modal. Modal (' show ');
}

This is a prototype method, and the initialization of the component is also performed at the time of this method invocation (deferred initialization).

Initmodal = function (that is, opts) {
var $modal = Createmodal (that);
That.settitle (opts.title);
That.setcontent (opts.content);
That.addbuttons (opts.buttons);
That.setwidth (opts.width);
Bindhandler (that, opts);
$modal. Modal ()///Call Bootstrap modal component
$modal. Trigger (' Contentready ');

This is a function to initialize the component. which

Settitle is a prototype method used to set the title of the modal;

SetContent is a prototype method used to set the HTML content of the modal;

AddButtons is a prototype method used to register a button;

SetWidth is a prototype method used to set the width of the modal;

Bindhandler is a function that registers the events of the modal;

The penultimate step calls $modal.modal () to initialize the modal component of the bootstrap;

The last step triggers the Contentready event.

Bindhandler Source:

Bindhandler = function (that is, opts) {
var $modal = that. $modal;
typeof Opts.oncontentchange = = ' function ' && $modal. On (' Contentchange ', $.proxy (Opts.oncontentchange, that)) ;
typeof Opts.oncontentready = = ' function ' && $modal. On (' Contentready ', $.proxy (Opts.oncontentready, that));
typeof opts.onmodalshow = = ' function ' && $modal. On (' Modalshow ', $.proxy (Opts.onmodalshow, that));
typeof opts.onmodalhide = = ' function ' && $modal. On (' Modalhide ', $.proxy (Opts.onmodalhide, that));
$modal. On (' Show.bs.modal ', function () {
$modal. Trigger (' modalshow ');
});
$modal. On (' Hidden.bs.modal ', function () {
$modal. Trigger (' modalhide ');
}

For ease of use, I bind the context of the Oncontentchange these callbacks to the current modal instance. The last two event listening is the encapsulation of bootstrap events into the modal events I define.

AddButtons Source:

Addbuttons:function (buttons) {
var buttons =!$.isarray (buttons)? []: Buttons, that
= this,
htmls = [];
Buttons.foreach (function (btn) {
htmls.push (btn.html);
Btn.selector && that $modal. On (' Click ', Btn.selector, $.proxy (function (e) {
var self = this,
$btn = $ (E.) Currenttarget);
Disable the button first
$btn [0].disabled = true;
var callback = typeof Btn.callback = = ' function '? Btn.callback: ',
ret = callback && callback.apply (self, arguments);
if (ret = false) {
$btn [0].disabled = false;
return;
}
if (typeof (ret) = = ' object ' && ' made ' in ret && typeof ret[' done '] = = ' function ') {
//asynchronous task only when the callback is successful Wait to close modal
ret.done (function () {
that.hide ();
}). Always (function () {
$btn [0].disabled = false;
});
} else {
$btn [0].disabled = false;
That.hide ();}}
, that);
};
this. $modalFooter. Prepend ($ (Htmls.join (')));
}

As you can see from this code:

When the button is clicked, the button is disabled;

When the button returns False, the button is restored, but the modal is not closed, indicating that some of the current operations are blocked by the code;

When the button returns a deferred object, the button is restored until the delay object is completed, and the modal is closed only when the object is resolve.

Otherwise, restore the button and actively turn off the modal.

In this piece of code, consider:

Button's anti-repeat click, modal automatic shutdown and asynchronous task processing.

6) Package Alert and confirm

Alert and confirm are actually a special modal, and the other two components can share a modal, and once you know the basics, the components can be defined:

var Alert, Confirm; (function () {var modal, Proxy = function (isalert) {return function () {if (arguments.length!= 1) return; var msg = t ypeof arguments[0] = = ' string ' && arguments[0] | | arguments[0].msg | | ', OnOK = typeof arguments[0] = = ' object ' && typeof Arguments[0].onok = = ' function ' && Arguments[0].ono K, oncancel = typeof arguments[0] = = ' object ' && typeof arguments[0].oncancel = = ' function ' && arguments [0].oncancel, Width = typeof arguments[0] = = ' object ' && arguments[0].width | | _onmodalshow = function () {this.setwidth (width); this.setcontent (msg); this[(Isalert?
' Hide ': ' Show ' + ' Button '] ('. Btn-cancel ');
}, _onmodalhide = function () {this.setcontent (');}; Deferred initialization modal if (!modal) {modal = new modal ({' title ': ' Operation Hint ', Onmodalshow: _onmodalshow, Onmodalhide: _onmodalhide, Oncon
Tentready:function () {this. $modalBody. css ({' padding-top ': ' 30px ', ' padding-bottom ': ' 30px '})}}); else {//If modal is already initialized it needs to be heavyNew Listener event var $modal = modal. $modal;
$modal. Off (' Modalshow modalhide ');
$modal. Off (' Modalshow modalhide ');
$modal. On (' Modalshow ', $.proxy (_onmodalshow, modal));
$modal. On (' Modalhide ', $.proxy (_onmodalhide, modal));
} modal.setoptions ({Onok:onok | | $.noop, ONCANCEL:ONCANCEL | | $.noop});
Modal.open ();
}
};
Alert = Proxy (true);
Confirm = Proxy ();  })();

In this piece of code:

First, the modal component with delay initialization is considered.

Since Onmodalhide and onmodalshow these two callbacks belong to the event callback, the parameters passed in by the options when initializing the component cannot be changed by modifying the options, only by registering While OnOK and OnCancel belong to the function callback, the callback can be changed as long as the references in the options are changed;

Considering the length of the alert and confirm contents, a new parameter width is added to adjust the width of the box.

4. Summary

This article is about their own in the definition of JS components in the process of some of the methods and practices, the code is too much, it is not easy to arouse people's interest in reading, but the method described in this article is relatively simple, and these three components I have been used in several projects, from the current point of view, can solve all my needs of the frame needs, so I recommend it, Hope to bring help to those in need.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.