creating a JQuery function
Sorry to bother you guys & girls again on Christmas eve, but I need help creating 开发者_JAVA技巧a reusable JQuery function. I have "badly crafted" this set of code that all works. But I would really like to put it as a function so I don't have to keep repeating everything for each form. I am not too sure about how all the if statements can be combined etc. that is why I wrote it as it is. Any help much appreciated - Oh I suppose it could also be some kind of plugin but that might be the next step if I can understand how the function works.
$(':input:visible').live('blur',function(){
if($(this).attr('required')) {
if($(this).val() == '' ) {
$(this).css({'background-color':'#FFEEEE' });
$(this).parent('form').children('input[type=submit]').hide();
$(this).next('.errormsg').html('OOPs ... '+$(this).prev('label').html()+' is required');
$(this).focus();
$(this).attr('placeholder').hide(); }
else {
$(this).css({'background-color':'#FFF' , 'border-color':'#999999'});
$(this).next('.errormsg').empty();
$(this).parent('form').children('input[type=submit]').show(); }
}
return false;
});
$(':input[max]').live('blur',function(){
if($(this).attr('max') < parseInt($(this).val()) ){
$(this).next('.errormsg').html( 'OOPs ... the maximum value is '+$(this).attr('max') );
$(this).parent('form').children('input[type=submit]').hide();
$(this).focus();
} else {}
return false;
});
$(':input[min]').live('blur',function(){
if($(this).attr('min') > parseInt($(this).val()) ){
$(this).next('.errormsg').html( 'OOPs ... the minimum value is '+$(this).attr('min') );
$(this).parent('form').children('input[type=submit]').hide();
$(this).focus();
} else {}
return false;
});
$(':input[maxlength]').live('keyup',function(){
if($(this).val()==''){ }
else { $(this).next('.errormsg').html( $(this).attr('maxlength')- $(this).val().length +' chars remaining'); }
return false;
});
As said, help much appreciated with one small (I hope) thing, how can I break out of any function IF there are no error messages to actually submit the form?
Some suggestions:
1) As Clour Blind points out, you can extend jQuery by assigning new functions to jQuery.fn
(aka $.fn
unless you're using noConflict
).
2) You have a lot of
$(this).foo();
$(this).bar();
$(this).baz();
...etc. Every time you do that, jQuery has to execute something like four function calls and allocate memory to a new jQuery instance. Instead, do it once and then reuse the result:
var $this = $(this); // You can call it whatever you like
$this.foo();
$this.bar();
$this.baz();
3) You're quite right, you can factor out the commonality of things and make a reusable thing out of them. For instance, your various validation blur
functions are all the same with slightly different bits and pieces:
$(':input[min]').live('blur',function(){
if($(this).attr('min') > parseInt($(this).val(), 10) ){
$(this).next('.errormsg').html( 'OOPs ... the minimum value is '+$(this).attr('min') );
$(this).parent('form').children('input[type=submit]').hide();
$(this).focus();
} else {}
return false;
});
So perhaps:
$.fn.validateOnBlur = function(attrName, errMsg, validator) {
this.live('blur', function() {
var $this = $(this),
limit = parseInt($this.attr(attrName), 10);
if(!validator(limit, parseInt($this.val(), 10) ){
$this.next('.errormsg').html(errMsg.replace("%limit%", limit));
$this.parent('form').children('input[type=submit]').hide();
$this.focus();
} else {}
return false;
});
};
I've done some very light reworking in there:
- Substituting
attrName
for'min'
or'max'
. - Adding the radix parameter,
10
, to calls toparseInt
. I assume your values are meant to be decimal, so if the user types "08" you want the value 8, not an error (because "08" is invalid octal notation). GivingparseInt
the second parameter tells it to always use that base (10 = decimal). - Look up the limit attribute once and remember it.
- Parameterize (in a very minimal way) the error message and then use
replace
to swap in the limit value for the token%limit%
.
Which you'd then use like this:
$(':input[max]').validateOnBlur(
'max',
'OOPs ... the maximum value is %limit%',
function(limit, value) {
return value <= limit;
}
);
$(':input[min]').validateOnBlur(
'min',
'OOPs ... the minimum value is %limit%',
function(limit, value) {
return value >= limit;
}
);
Or more likely, you'd use it like this:
// In your general purpose stuff
var comparators = {
checkNumberMin: function(limit, value) {
return value >= limit;
},
checkNumberMax: function(limit, value) {
return value <= limit;
}
};
// And then in your specific code using it
$(':input[max]').validateOnBlur(
'max',
'OOPs ... the maximum value is %limit%',
comparators.checkNumberMax
);
$(':input[min]').validateOnBlur(
'min',
'OOPs ... the minimum value is %limit%',
comparators.checkNumberMin
);
You can probably go further and hook up everything in one function rather than just blur
, but you get the idea.
Side note: For the purposes of straightforward examples, I've used a bunch of anonymous functions above, but I'm not a fan of them in practice; more here.
The syntax to create a function JQuery goes like this:
$.fn.functionname = (function(param1, param2) {
});
//You can also return a value.
Update #1
Remember you have to wrap all your JQuery code in this:
$(function() {
});
So you now have:
$(function() {
$.fn.functionname = (function(param1, param2) {
});
});
Update #2
Also remember the functions you create this way can be invoke on a jQuery set, like:
$("a.readmore").functionname(); //That is, if you don't have parameters
$("a.readmore").functionname(1, 2);
This is the basic and i hope it helps.
Why don't you have this code in a JS file and then include to the file as external JS file. Also, I see that you are using $(this) on each line of the live function e.g.
$(this).css({'background-color':'#FFEEEE' });
$(this).parent('form').children('input[type=submit]').hide();
Instead you can define a local variable and assign $(this) to that variable and refer to it across. e.g:
$(':input:visible').live
(
'blur',
function()
{
var $this = $(this);
if($this.attr('required'))
{
if($this.val() == '' ) {
$this.css({'background-color':'#FFEEEE' });
$this.parent('form').children('input[type=submit]').hide();
$this.next('.errormsg').html('OOPs ... '+$this.prev('label').html()+' is required');
$this.focus();
$this.attr('placeholder').hide(); }
else {
$this.css({'background-color':'#FFF' , 'border-color':'#999999'});
$this.next('.errormsg').empty();
$this.parent('form').children('input[type=submit]').show(); }
}
return false;
}
);
精彩评论