I'm starting doing jQuery plugins so I don't have much experience doing it, the thing what I want to have done today is to create a custom event for the plugin I'm working on.
I thing a good example to show you exact what I want to do is the bootstrap tooltip plugin, with this plugin I can do something like that:
$('.my-tooltip').tooltip('show');
Forcing the plugin to do an action, in this case execute show()
plugin function
For my specific case I'm doing a plugin to custom validate forms around a website using jQuery validate plugin and I wan't to do something like:
$('form#whatever').validateForm('showInlineChecks');
To force the plugin to run a validation for some specific fields.
Let's take a look of my code:
/*
* jQuery plugin to validate forms around segurosdigitales
* requires jquery validate plugin
* */
if( typeof Object.create !== 'function' ){
Object.create = function( obj ) {
function F(){};
F.prototype = obj;
return new F();
}
}
(function($){
var validator = {
// init the plugin
init: function(options, element){
var self = this;
self.options = $.extend( {}, $.fn.validateForm.options, options );
self.elem = element;
self.$elem = $(element);
self.validateTheForm();
},
// Set default options for jQuery validate plugin
setValidationOptions: function(){
var self = this;
// Default options for all forms around the app
// These are the default options for jquery validate plugin
var jQueryValidatePluginOptions = {
onfocusout: function(e){
// Validate all elements when 'blur' event happens, except if it has a 'datepicker-open' class, I'm adding this class because datepicker causes that the input element loses focus and validation error is triggered
if(!$(e).hasClass('datepicker-open')){
this.element(e);
}
},
errorElement: 'span',
errorClass: 'error help-block',
errorPlacement: function(error, element){
if(element.is('input[type="checkbox"]')){
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
},
// Highlight occurs when element has erros
highlight: function(element, errorClass, validClass){
$(element).addClass(errorClass).removeClass(validClass);
var control_group = $(element).closest('.control-group, .controls-row');
control_group.addClass(errorClass).removeClass(validClass);
// Remove any valid icon
control_group.find('i.icon-ok').remove();
},
// Unhighlight occurs when element is valid
unhighlight: function(element, errorClass, validClass){
$(element).removeClass(errorClass).addClass(validClass);
// get the parent of the field
var control_group = $(element).closest('.control-group, .controls-row');
// is field empty?
var element_is_empty = ( $(element).val() === '' );
if (!element_is_empty && !control_group.find('i.icon-ok').length) {
var label = control_group.find('label');
// Prevent to add more than one icon if control group contains more than one label (ie. when we have checkboxes and radio buttons)
$.each(label, function () {
$(this).prepend('<i class="icon-ok green"></i>');
return false;
});
// add class only if element is valid and not empty
control_group.removeClass(errorClass).addClass(validClass);
}
}
};
// add other options depending of validateForm plugin options
if( self.options.errorMessages ){
jQueryValidatePluginOptions.messages = self.options.errorMessages;
}
if( self.options.rules ){
jQueryValidatePluginOptions.rules = self.options.rules;
}
if( self.options.showNotification ){
jQueryValidatePluginOptions.invalidHandler = function(event, validator){
var errors = validator.numberOfInvalids();
if(errors){
generateNotification('error', false, 'Por favor corrige los errores en los campos resaltados en rojo para poder continuar.');
}
}
}
return jQueryValidatePluginOptions;
},
// Validate form
validateTheForm: function(){
var self = this;
var validateOpts = self.setValidationOptions();
self.$elem.validate(validateOpts);
}
};
$.fn.validateForm = function(options){
return this.each(function(){
var validate = Object.create(validator);
validate.init(options, this);
});
};
$.fn.validateForm.options = {
errorMessages: null,
rules: null,
showNotification: true
}
})(jQuery);
How can I do it?
Creating, emitting and subscribing to custom events are quite simple with jquery.
In order to emit custom event you simply call trigger
$(elem).trigger('myCustomEvent.myNS')
I would recommend always useing namespaces, for easier managing custom events
Then you subscribe to your event like you do to regular event
$(elem).on('myCustomEvent.myNS', function(event) {
})
You can also add additional parameters passed to your event handler, like that
$(elem).trigger('myCustomEvent.myNS', ['p1', 'p2'])
$(elem).on('myCustomEvent.myNS', function(event, param1, param2) {
console.log(param1) // outputs p1
console.log(param2) // outputs p2
})
So overall , on some user actions , say clicking a button, you'll emit your custom event, like this
$(elem).on('click', 'button.save', function (e) {
$(elem).trigger('validate.myCtrl', [e, this])
})
Also note that in case your event has the same name as some method on the object you are defining events on, jquery will try to call this method when calling
trigger
. To avoid that behavior usetriggerHandler
jquery method.
UPDATE: @cristiangrojas, I would recomend you check different "standard" ways of setting up jquery plugin here https://github.com/shichuan/javascript-patterns/tree/master/jquery-plugin-patterns'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With