Extending alert's functionality with JavaScript

As with extending the styles, to extend the JavaScript, we can modify Bootstrap's alert.js directly, but again, that is a bad idea in terms of maintainability. Instead, we will create a js directory in our project, and a file called alert.js. Include this file in your HTML, after bootstrap.min.js:

    <script 
    src="node_modules/bootstrap/dist/js/bootstrap.min.js">          
</script> <script src="js/alert.js"></script>

The first thing we will do is to create an immediately invoked function and add the function to the jQuery object:

    +function ($) {
        'use strict';
        var Alert = $.fn.alert.Constructor;
    }(jQuery);

The function assigns an Alert variable to the alert plugins prototype—which as we saw earlier, is made available through the Constructor property.

With this reference to the Alert prototype, we can add our own functions to the prototype to handle minimizing and expanding an alert. Taking the close function we studied earlier, and with a few changes, let's create a function to minimize the alert:

    Alert.prototype.minimize = function (e) {
        var $this = $(this)
        var selector = $this.attr('data-minimize')
        if (!selector) {
            selector = $this.attr('href')
            selector = selector && selector.replace(/.*(?=#[^s]*$)/, 
'') // strip for ie7 } $this.addClass('d-none') $this.siblings('.expand').removeClass('d-none') var $parent = $(selector) if (e) e.preventDefault() if (!$parent.length) { $parent = $this.closest('.alert') } $parent.trigger(e = $.Event('minimize.bs.alert')) if (e.isDefaultPrevented()) return $parent.addClass('alert-minimize') }

The function is quite similar to the close function, so we will highlight the important differences. Line 15 and 16 handle hiding the minimize button and showing the expand button, adding the d-none class to the element that triggered the event, and removing the d-none class from any sibling element with the expand class. Line 30 adds the alert-minimize class, which handles the shrinking of the Alert element, to the parent of the element that triggered the event. Essentially, the minimize function will shrink the alert, hide the minimize button, and show the expand button. Let's hook up a listener to this function.

We do this in the same way as the Bootstrap alert plugin links the data—dismiss the click event to the close function, adding the following to alert.js below the minimize function definition:

    $(document).on('click.bs.alert.data-api', '[data-                     
minimize="alert"]', Alert.prototype.minimize)

Now, an element with the data-minimize attribute with an "alert" value will call the Alert.prototype.minimize function on a click event. The minimize element in our special offers alert has this attribute. Open up MyPhoto and click on the minimize button. Take a look at the screenshot in figure 6.5:

Figure 6.5: Our minimized custom promotion alert—note the expand and close buttons (example02.html)

That's excellent. Our minimize button and functionality are wired up correctly to shrink our special offers alert and replace the minimize button with an expand button when clicked on.

The last thing we need to do now is ensure that the user can expand the alert when they click on the expand button. To do this, we follow the same steps as we did for the minimize functionality. Let's add an expand function to the Alert prototype:

    Alert.prototype.expand = function (e) {
        var $this = $(this)
        var selector = $this.attr('data-expand')
        if (!selector) {
          selector = $this.attr('href')
          selector = selector && selector.replace(/.*(?=#[^s]*$)/, 
'') // strip for ie7 } $this.addClass('d-none') $this.siblings('.minimize').removeClass('d-none') var $parent = $(selector) if (e) e.preventDefault() if (!$parent.length) { $parent = $this.closest('.alert') } $parent.trigger(e = $.Event('expand.bs.alert')) if (e.isDefaultPrevented()) return $parent.removeClass('alert-minimize') }

The differences between the expand and minimize functions are very small, so small that it probably makes sense for them to be encapsulated into one function. However, for the sake of simplicity, we will keep the two functions separate. Essentially, the actions of minimize are reversed. The d-none class is again applied to the element triggering the event, the d-none class is removed from any sibling with the minimize class, and the alert-minimize class is removed from the parent element. This is simple and effective. Now, we just need to hook up a click event on an element with the data-expand attribute set to alert to the expand method. Observe the following code:

    $(document).on('click.bs.alert.data-api', '[data-expand="alert"]', 
    Alert.prototype.expand)

That's it. With our extension to the alert plugin, when a user clicks on expand in the minimized state, the alert reverts to its initial expanded state, and the expand button is replaced by the minimize button. Our users now have the ability to reduce the screen real estate our alert covers but are still able to retrieve the information from the alert at a later stage if needed.

While these alert customizations are relatively simple, they do provide a strong example of how to extend a plugin's functionality and teach principles that can be applied to more complex extensions.

In summary, our complete code is as follows:

+ function($) {
'use strict';
var Alert = $.fn.alert.Constructor;
Alert.prototype.minimize = function(e) {
var $this = $(this)
var selector = $this.attr('data-minimize')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^s]*$)/,
'') // strip for ie7
}
$this.addClass('d-none')
$this.siblings('.expand').removeClass('d-none')
var $parent = $(selector)
if (e) e.preventDefault()
if (!$parent.length) {
$parent = $this.closest('.alert')
}
$parent.trigger(e = $.Event('minimize.bs.alert'))
if (e.isDefaultPrevented()) return $parent.addClass('alert-
minimize')
}
Alert.prototype.expand = function(e) {
var $this = $(this)
var selector = $this.attr('data-expand')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^s]*$)/,
'') // strip for ie7
}
$this.addClass('d-none')
$this.siblings('.minimize').removeClass('d-none')
var $parent = $(selector)
if (e) e.preventDefault()
if (!$parent.length) {
$parent = $this.closest('.alert')
}
$parent.trigger(e = $.Event('expand.bs.alert'))
if (e.isDefaultPrevented()) return $parent.removeClass('alert-
minimize')
}
$(document).on('click.bs.alert.data-api', '[data-
minimize="alert"]', Alert.prototype.minimize)
$(document).on('click.bs.alert.data-api', '[data-expand="alert"]',
Alert.prototype.expand)
}(jQuery);

The accompanying markup is this:

<div class="alert alert-info alert-position">
<a href="#" class="close" data-dismiss="alert" aria-
label="close">&times;</a>
<strong><i class="fa fa-exclamation"></i> Special Offer -</strong>
2 FOR 1 PRINTS TODAY ONLY WITH PROMO CODE
<span style="font-style: italic">BOOTSTRAP</span>
</div>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.105.220