Giter VIP home page Giter VIP logo

ketchup-plugin's Introduction

jQuery Ketchup Plugin - Tasty Form Validation

Ketchup is a small (3.4KB minified & gzipped) jQuery Plugin that helps you to validate your forms. Out of the box it has 18 basic validations and a bubble like style. But truly this Plugin wants to be hacked to fit your needs. Easily write your own validations and overwrite/extend the default behaviour. Bubbles are not for everyone...

Default Behavior

If you like the style of the bubbles and all validations you need are already included you can get this Plugin up and running like so:

Your HTML Header

Include the default stylesheet (located in ./css/ in this package) and the bundled and minified Plugin along with the latest jQuery version in your HTML header.

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Yammie</title>

    <link rel="stylesheet" type="text/css" media="screen" href="css/jquery.ketchup.css" />

    <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="js/jquery.ketchup.all.min.js"></script>
  </head>

  <body>
    ... form stuff ...

Your HTML

By default Ketchup checks the data-validate attribute of form fields if it can find matching validations. The default indicator for validations is validate(), all validations go in there and are separated by comma. Validations can have arguments, also separated by comma. About checkboxes: You only need to declare the validations on one checkbox. Ketchup binds all other checkboxes with the same name automatically.

<form id="default-behavior" action="index.html">
  <ul>
    <li>
      <label for="db-mail">E-Mail</label>
      <input type="text" id="db-mail" data-validate="validate(required, email)" />
    </li>
    <li>
      <label for="db-username">Username</label>
      <input type="text" id="db-username" data-validate="validate(required, username, minlength(3))" />
    </li>
    <li>
      <label for="db-skill">Skills</label>
      <input type="checkbox" id="db-skill" name="db-skill" data-validate="validate(minselect(2))" /> jQuery
      <input type="checkbox" name="db-skill" /> HTML
      <input type="checkbox" name="db-skill" /> CSS
      <input type="checkbox" name="db-skill" /> Rails
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

Just call ketchup() on your form, voilà.

$('#default-behavior').ketchup();

Declare fields to validate in the call

In last version Ketchup checked the class attribute for validations... which was not everyones taste because class should be used for defining CSS classes. In HTML5 we have the data- attributes for the rescue to set custom data.

However, if you still want to separate the validations declarations from your markup you can do so by passing an object with jQuery selectors as keys and validations as values to Ketchup.

Your HTML

Note that required is not a validation declaration but an actual class name. We use that to select the fields to validate.

<form id="fields-in-call" action="index.html">
  <ul>
    <li>
      <label for="fic-email">E-Mail</label>
      <input type="text" id="fic-email" class="required" />
    </li>
    <li>
      <label for="fic-username">Username</label>
      <input type="text" id="fic-username" class="required" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

Right after the options (empty here {}) we pass in an object. Use the key to declare the jQuery selector on which fields the validations in the value are processed. Validations declared like this don't need the validate() indicator.

$('#fields-in-call').ketchup({}, {
  '.required'    : 'required',              //all fields in the form with the class 'required'
  '#fic-username': 'username, minlength(3)' //one field in the form with the id 'fic-username'
});

Validate on different events

By default Ketchup listens to the blur event on form fields. You can overwrite that behaviour for every field in the options, and you can overwrite it separately for a single field.

Your HTML

In the data-validate attribute you can have a on() indicator. Events go in there and are separated by a space. These are strings jQuery's bind() accepts.

<form id="validation-events" action="index.html">
  <ul>
    <li>
      <label for="ve-username">Username</label>
      <input type="text" id="ve-username" data-validate="validate(required, minlength(3)) on(keyup focus)" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

$('#validation-events').ketchup({
  validateEvents: 'dblclick'
});

/*if you set the fields to validate in the call
  you  simply pass  in a array as value.  First
  argument is  the validations string  and  the
  second is the events string. Like so:

$('#validation-events').ketchup({}, {
  '#ve-username': ['required, minlength(3)', 'keyup focus']
});*/

Included Validations

  • required - The field is required.
  • minlength(min) - The field must have a minimal length of min characters.
  • maxlength(max) - The field must have a maximal length of max characters.
  • rangelength(min, max) - The field must have a length between min and max characters.
  • min(min) - The field must have a minimal number of min.
  • max(max) - The field must have a maximal number of max.
  • range(min, max) - The field must have a number between min and max.
  • number - The field must be a number.
  • digits - The field must be a digit (full number).
  • email - The field must be a valid email.
  • url - The field must be a valid URL.
  • username - The field must be a valid username.
  • match(word) - The field must match the value word.
  • contain(word) - The field must contain word.
  • date - The field must be a valid date.
  • minselect(min) - At least min checkboxes with the same name must be selected.
  • maxselect(max) - No more than max checkboxes with the same name must be selected.
  • rangeselect(min, max) - Between min and max checkboxes with the same name must be selected.

Write your own validations

You can write your own validation functions for Ketchup. A validation function must return a boolean, true if the field validates fine and false if it fails to validate.

Validations pass in at least three arguments:

  • form - the jQuery object for the form (we validate in this form)
  • el - the jQuery object for the form field (we validate on this field)
  • value - the value of the form field (short for el.val())

After these three arguments you can declare the arguments for your validation. In this example the word validation has two arguments, word1 and word2. You pass in the arguments in your validation call like word(ketchup, mustard). Now 'ketchup' is the word1 argument and so on.

Validation messages have {argN} placeholders for your arguments. Is {arg1} would become Is ketchup.

A validation can have a initial callback, optionally passed in as function as the second argument. Use this to bind elements with the same name, checkboxes for example. Or apply a class to the field to style Ketchup enabled fields. The initial callback passes in two arguments, form and el. You already know what these are.

Your HTML

<form id="own-validation" action="index.html">
  <ul>
    <li>
      <label for="ov-word">Ketchup or Mustard</label>
      <input type="text" id="ov-word" data-validate="validate(word(ketchup, mustard))" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

$.ketchup.validation('word', 'Either "{arg1}" or "{arg2}"', function(form, el, value, word1, word2) {
  if(value == word1 || value == word2) {
    return true;
  } else {
    return false;
  }
}, function(form, el) {
  //initial callback, this is optional
});

$('#own-validation').ketchup();

Helpers for your validations

Helpers are repeating functions you can use in your validations via this.

  • isNumber(value) - Check if the value is a valid number. Returns true/false.
  • contains(value, word) - Check if the value contains word. Returns true/false.
  • isEmail(value) - Check if the value is a valid email. Returns true/false.
  • isUrl(value) - Check if the value is a valid URL. Returns true/false.
  • isUsername(value) - Check if the value is a valid username. Returns true/false.
  • isDate(value) - Check if the value is a valid date. Returns true/false.
  • inputsWithName(form, el) - Get all elements in the form with the name of el. Returns a jQuery object.
  • inputsWithNameNotSelf(form, el) - Get all elements in the form with the name of el but not itself. Returns a jQuery object.
  • getKetchupEvents(el) - Get all events Ketchup has used on the el. Returns a String.
  • bindBrothers(form, el) - Bind all elements in the form with el's name to el's Ketchup events. This is helpful on checkboxes and co. Returns undefined.

Your HTML

<form id="validation-helper" action="index.html">
  <ul>
    <li>
      <label for="vh-email">Your E-Mail (must contain 'ketchup')</label>
      <input type="text" id="vh-email" data-validate="validate(ketchupEmail)" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

$.ketchup.validation('ketchupEmail', 'Must be a valid e-mail and contain "ketchup"', function(form, el, value) {
  if(this.isEmail(value) && this.contains(value.toLowerCase(), 'ketchup')) {
    return true;
  } else {
    return false;
  }
});

$('#validation-helper').ketchup();

Write your own helpers

Of course you can extend helpers too. Pass a helper name and the actual helper function with the arguments to helper().

Your HTML

<form id="own-helper" action="index.html">
  <ul>
    <li>
      <label for="oh-rand1">This field is validated randomly</label>
      <input type="text" id="oh-rand1" data-validate="validate(random)" />
    </li>
    <li>
      <label for="oh-rand2">Words are validated randomly: ketchup, mustard</label>
      <input type="text" id="oh-rand2" data-validate="validate(randomWord(ketchup, mustard))" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

$.ketchup.helper('randomNumber', function(min, max) {
  return (min + parseInt(Math.random() * (max - min + 1)));
});

$.ketchup.validation('random', 'Not this time...', function(form, el, value) {
  return (this.randomNumber(0, 1) ? true : false);
});

$.ketchup.validation('randomWord', 'Try the other word', function(form, el, value, word1, word2) {      
  return (this.randomNumber(0, 1) ? word1 : word2) == value;
});

$('#own-helper').ketchup();

Set the messages for your validations

In the examples above we set the message for the validations directly as second argument in the validate() function. This is not necessary. If you want to seperate the messages from the validation code you have two choices.

Either overwrite single messages:

$.ketchup.message('word', 'Guess the word!');

Or pass in an object to the messages() method (you can copy and paste them from the last version of Ketchup). Note that only declared validation messages gets overwritten, the others are still set.

$.ketchup.messages({
  required : 'Something?',
  minlength: '>= {arg1}'
});

Control the behavior of the error container

Time to control the behavior and the style of the error container. Several functions can be overwritten leaving creating, showing and hiding the error container and add error messages completely up to you.

  • createErrorContainer(function(form, el) {})

    This function creates the error container one time. form is the form we are currently in and el the element we are currently validating. It must return a jQuery object of the error container.

  • showErrorContainer(function(form, el, container) {})

    This function shows the error container every time the field el fails to validate. form is the form we are currently in and el the element we are currently validating. container is the jQuery object of the error container, you created it with createErrorContainer(). Must not return anything

  • hideErrorContainer(function(form, el, container) {})

    As opposite to showErrorContainer() this function hides the error container when the field el validates fine. It pass in the same arguments as showErrorContainer() and must not return anything.

  • addErrorMessages(function(form, el, container, messages) {})

    If the field el fails to validate you need to update the error messages via this function. form, el and container are the same arguments as in showErrorContainer() and hideErrorContainer(). messages is a Array containing strings of all error messages the field fails to validate.

Your CSS

.ketchup-custom {
  line-height: 1em;
  display: none;
}

.ketchup-custom li {
  font-size: 10px;
  text-transform: uppercase;
  text-shadow: 1px 1px 0 #9F4631;
  border: 0;
  color: white;
  background: #F46644;
  padding: 1px 10px;
  margin-top: 1px;
}

Your HTML

<form id="custom-behavior" action="index.html">
  <ul>
    <li>
      <label for="cb-mail">E-Mail</label>
      <input type="text" id="cb-mail" data-validate="validate(required, email)" />
    </li>
    <li>
      <label for="cb-username">Username</label>
      <input type="text" id="cb-username" data-validate="validate(required, minlength(3))" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

$.ketchup

.createErrorContainer(function(form, el) {
  return $('<ul/>', {
           'class': 'ketchup-custom'
         }).insertAfter(el);
})

.addErrorMessages(function(form, el, container, messages) {
  container.html('');
  
  for(i = 0; i < messages.length; i++) {
    $('<li/>', {
      text: messages[i]
    }).appendTo(container);
  }
})

.showErrorContainer(function(form, el, container) {
  container.slideDown('fast');
})

.hideErrorContainer(function(form, el, container) {
  container.slideUp('fast');
});

$('#custom-behavior').ketchup({
  validateEvents: 'blur focus keyup'
});

Ketchup Events

Your HTML

<form id="ketchup-events" action="index.html">
  <ul>
    <li>
      <label for="ke-username">Username</label>
      <input type="text" id="ke-username" data-validate="validate(required, username, minlength(5))" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

$('#ketchup-events')
  .bind('formIsValid', function(event, form) {
    //do whatever when the form is valid
    //form - the form that is valid (jQuery Object)
  })
  .bind('formIsInvalid', function(event, form) {
    //do whatever when the form is invalid
    //form - the form that is invalid (jQuery Object)
  })
  .bind('fieldIsValid', function(event, form, el) {
    //do whatever if a field is valid
    //form - the form where the el is located (jQuery Object)
    //el   - the element that is valid (jQuery Object)
  })
  .bind('fieldIsInvalid', function(event, form, el) {
    //do whatever if a field is invalid
    //form - the form where the el is located (jQuery Object)
    //el   - the element that is invalid (jQuery Object)
  })
  .ketchup();

Check if the form and fields are valid from outside

You can use Ketchup's internal function to check if a form or a field is valid from your own script without triggering the validation container. el.ketchup('isValid') returns true if the form/field (el) is valid, otherwise it returns false.

If you want to trigger the validation from your script use el.ketchup('validate') where el is the field.

Your CSS

#from-outside { position: relative; }

#fo-errors {
  position: absolute;
  top: 30px;
  left: 200px;
}

#fo-errors li { padding: 0 10px; margin-bottom: 1px; }
#fo-errors .valid { background: #9ADF61; }
#fo-errors .invalid { background: #F46644; }

#from-outside .ketchup-custom { position: absolute; left: -30000px; } /* hide ketchup errors on blur and form submit */

Your HTML

<form id="from-outside" action="index.html">
  <ul>
    <li>
      <label for="fo-mail">E-Mail</label>
      <input type="text" id="fo-mail" data-validate="validate(required, email)" />
    </li>
    <li>
      <label for="fo-username">Username</label>
      <input type="text" id="fo-username" data-validate="validate(required, username, minlength(5))" />
    </li>
    <li>
      <input type="submit" value="Is Tasty?" />
    </li>
  </ul>
</form>

Your Javascript

var form     = $('#from-outside'),
    mail     = $('#fo-mail', form),
    username = $('#fo-username', form),
    result   = $('<ul/>', { id: 'fo-errors' }).appendTo(form);

form
  .ketchup()
  .find('input').keyup(function() {
    result.html('');
  
    $.each([form, mail, username], function(index, el) {
      var valid = el.ketchup('isValid') ? 'valid' : 'invalid';
    
      $('<li/>', {
        'class': valid,
        text   : '#' + el.attr('id') + ' is ' + valid
      }).appendTo(result);
    });
  })
  .last().keyup();

Default Options

attribute           : 'data-validate',                //look in that attribute for an validation string
validateIndicator   : 'validate',                     //in the validation string this indicates the validations eg validate(required)
eventIndicator      : 'on',                           //in the validation string this indicates the events when validations get fired eg on(blur)
validateEvents      : 'blur',                         //the default event when validations get fired on every field
validateElements    : ['input', 'textarea', 'select'],//check this fields in the form for a validation string on the attribute
createErrorContainer: null,                           //function to create the error container (can also be set via $.ketchup.createErrorContainer(fn))
showErrorContainer  : null,                           //function to show the error container (can also be set via $.ketchup.showErrorContainer(fn))
hideErrorContainer  : null,                           //function to hide the error container (can also be set via $.ketchup.hideErrorContainer(fn))
addErrorMessages    : null                            //function to add error messages to the error container (can also be set via $.ketchup.addErrorMessages(fn))

License and Copyright

The jQuery Ketchup Plugin is dual licensed under the GPL and MIT licenses.

(c) 2011 Sebastian Senf - http://mustardamus.com - http://usejquery.com - @mustardamus

ketchup-plugin's People

Contributors

mustardamus avatar philippbosch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ketchup-plugin's Issues

Latest version doesn't work in IE7 / IE6

Hey,

Been using the plugin for a year or so. Switched to latest version and found it didn't work with IE7/IE6.

Traced bug to:

switch(fullString[i]) {

returning nothing in IE.

Fixed to:
switch(fullString.charAt(i)) {

Now it fully works.

Bug with a div in display:none resolved

If some input are in a div with a display:none; the error container is at the left of the window :
You have to put this line in the positionContainer : "left: fOffset.left + field.width() - 10,"

var positionContainer = function(errorContainer, field) {
var fOffset = field.offset();
errorContainer.animate({
left: fOffset.left + field.width() - 10,
top: field.offset().top - errorContainer.height()
});
};

Position issue on hidden form

I have a form that is hidden until a calender date is clicked. When the ketchup plugin gets called, the positioning is not correct, from the left anyway. The bubble appears to the far left of the screen. However, it will jump to the correct place after a few seconds. Is there a fix for this?

I am using Firefox 3.

Example here - http://www.longbarnshelve.co.uk/availability.php

Localization feature

The validation messages may depend on the client language. A way to do this is to replace the current contents of the "jquery.ketchup.validations.js" file with the below (working) code. Would you add this into the next builds?

// Retrieve value from
var pageLanguage = document.documentElement.lang

if ( pageLanguage=='fr' ) {

jQuery.ketchup
.validation('required', 'Ce champ est requis.', function(form, el, value) {
var type = el.attr('type').toLowerCase();
if(type == 'checkbox' || type == 'radio') {
return (el.attr('checked') == true);
} else {
return (value.length != 0);
}
})
.validation('minlength', 'Ce champ doit avoir une longueur minimale de {arg1}.', function(form, el, value, min) {
return (value.length >= +min);
})
.validation('maxlength', 'Ce champ doit avoir une longueur maximale de {arg1}.', function(form, el, value, max) {
return (value.length <= +max);
})
.validation('rangelength', 'Ce champ doit avoir une longueur entre {arg1} et {arg2}.', function(form, el, value, min, max) {
return (value.length >= min && value.length <= max);
})
.validation('min', 'Valeur minimale de {arg1}.', function(form, el, value, min) {
return (this.isNumber(value) && +value >= +min);
})
.validation('max', 'Valeur maximale de {arg1}.', function(form, el, value, max) {
return (this.isNumber(value) && +value <= +max);
})
.validation('range', 'Valeur entre {arg1} et {arg2}.', function(form, el, value, min, max) {
return (this.isNumber(value) && +value >= +min && +value <= +max);
})
.validation('number', 'Doit être un nombre.', function(form, el, value) {
return this.isNumber(value);
})
.validation('digits', 'Doivent être des chiffres.', function(form, el, value) {
return /^\d+$/.test(value);
})
.validation('email', 'Doit avoir un format d'adresse mél.', function(form, el, value) {
return this.isEmail(value);
})
.validation('url', 'Doit être une adresse web.', function(form, el, value) {
return this.isUrl(value);
})
.validation('username', 'Doit être un nom utilisateur en usage.', function(form, el, value) {
return this.isUsername(value);
})
.validation('match', 'Doit être {arg1}.', function(form, el, value, word) {
return (el.val() == word);
})
.validation('contain', 'Doit contenir {arg1}', function(form, el, value, word) {
return this.contains(value, word);
})
.validation('date', 'Doit avoir un format de date.', function(form, el, value) {
return this.isDate(value);
})
.validation('minselect', 'Cochez au moins {arg1} cases.', function(form, el, value, min) {
return (min <= this.inputsWithName(form, el).filter(':checked').length);
}, function(form, el) {
this.bindBrothers(form, el);
})
.validation('maxselect', 'Ne cochez pas plus que {arg1} cases.', function(form, el, value, max) {
return (max >= this.inputsWithName(form, el).filter(':checked').length);
}, function(form, el) {
this.bindBrothers(form, el);
})
.validation('rangeselect', 'Cochez entre {arg1} et {arg2} cases.', function(form, el, value, min, max) {
var checked = this.inputsWithName(form, el).filter(':checked').length;
return (min <= checked && max >= checked);
}, function(form, el) {
this.bindBrothers(form, el);
});

// If pageLanguage is unidentified or if HTML lang is English
} else {

jQuery.ketchup

.validation('required', 'This field is required.', function(form, el, value) {
var type = el.attr('type').toLowerCase();
if(type == 'checkbox' || type == 'radio') {
return (el.attr('checked') == true);
} else {
return (value.length != 0);
}
})
.validation('minlength', 'This field must have a minimal length of {arg1}.', function(form, el, value, min) {
return (value.length >= +min);
})
.validation('maxlength', 'This field must have a maximal length of {arg1}.', function(form, el, value, max) {
return (value.length <= +max);
})
.validation('rangelength', 'This field must have a length between {arg1} and {arg2}.', function(form, el, value, min, max) {
return (value.length >= min && value.length <= max);
})
.validation('min', 'Must be at least {arg1}.', function(form, el, value, min) {
return (this.isNumber(value) && +value >= +min);
})
.validation('max', 'Can not be greater than {arg1}.', function(form, el, value, max) {
return (this.isNumber(value) && +value <= +max);
})
.validation('range', 'Must be between {arg1} and {arg2}.', function(form, el, value, min, max) {
return (this.isNumber(value) && +value >= +min && +value <= +max);
})
.validation('number', 'Must be a number.', function(form, el, value) {
return this.isNumber(value);
})
.validation('digits', 'Must be digits.', function(form, el, value) {
return /^\d+$/.test(value);
})
.validation('email', 'Must have the format of an e-mail.', function(form, el, value) {
return this.isEmail(value);
})
.validation('url', 'Must be a web address.', function(form, el, value) {
return this.isUrl(value);
})
.validation('username', 'Must be a used username.', function(form, el, value) {
return this.isUsername(value);
})
.validation('match', 'Must be {arg1}.', function(form, el, value, word) {
return (el.val() == word);
})
.validation('contain', 'Must contain {arg1}', function(form, el, value, word) {
return this.contains(value, word);
})
.validation('date', 'Must have the format of a date.', function(form, el, value) {
return this.isDate(value);
})
.validation('minselect', 'Select at least {arg1} checkboxes.', function(form, el, value, min) {
return (min <= this.inputsWithName(form, el).filter(':checked').length);
}, function(form, el) {
this.bindBrothers(form, el);
})
.validation('maxselect', 'Select not more than {arg1} checkboxes.', function(form, el, value, max) {
return (max >= this.inputsWithName(form, el).filter(':checked').length);
}, function(form, el) {
this.bindBrothers(form, el);
})
.validation('rangeselect', 'Select between {arg1} and {arg2} checkboxes.', function(form, el, value, min, max) {
var checked = this.inputsWithName(form, el).filter(':checked').length;
return (min <= checked && max >= checked);
}, function(form, el) {
this.bindBrothers(form, el);
});

}

Radio Buttons and Ketchup

I am having a issue getting Ketchup to validate a set of radio buttons to ensure they made a selection.

There are no examples on the site showing how to handle this. I have tried the class="validate(required)" but it does not work. I also tried class="validate(rangeselect(1,3))" and it works but radio buttons are not a multi select thing like checkboxes.

Any assistance would be appreciated.

support remote validation

Could ketchup support remote validation? If a JSON "true" is returned, then accept the value.

$.fn.ketchup.validation('remote', function(element, url, testValue) {
  $.get(url, { x: testValue }, function(json) {
    return (json == true);
  });
});

I'd made a fork, but my repository is offline for backups right now.

Typo

Noticed 'Download' is spelled wrong on the 'You need to validate in a different way? Make your own Ketchup!" page.

via Chad

Feature Request - Additional Events + Scenario's

Hi There,

I've been implementing your validator over the past couple of day's and have encountered a couple of quirks that are easy to resolve, and would enhance the product I think.

1/
The hideContainer and showContainer should pass the associated field through. This way, you can easily apply styles or animations to the field itself should you want to.

2/
Perhaps the addition classes that are added to a container based on success or fail. The reason being, we're implementing inline form validation - but want a visual representation of the field being correct as well as incorrect. So we don't want to hide the container, just change it. :) If a class was applied to the container indicating this - then we could determine how to present it based on this.

3/
Going on the above comment, perhaps it might be prudent to add a couple of events, like onSuccess and onFail?

Otherwise - cheer's for an easy to use validator! :)

Offset Calculation

Hi mustradamus :)

I'm having trouble integrating ketchup in a page with lot of div tag. some of the tags are 10+ levels deep. i think, the problem is mostly due to the way offset is calculated for absolute positioning of the bubble.

By the nature of absolute positioning, the element is placed with regards to an ancestor with non static positioning, right?. usually in most of the layouts ive encountered, the divs use positioning to align themselves. But the current offset logic finds the position of the field with reference to default origin. shouldn't it calculate its offset from the last ancestor element whose position is non static? (maybe using closest() )

The current version breaks when used in such context.since the location of the form element can be anywhere in the page, shouldn the positioning logic be flexible?

Problem with position relative

Hi,

I've noticed an issue with ketchup (and worked out a fix).

The position of the the error box is wrong if any parent in the hierarchy of the text field is set to position:relative, because the absolute positioning will be calculated from there.

Also using the errorContainer height in initialPositionContainer doesn't really work as the error labels inside it haven't been built.

Here's my patch for it. Works with both position:relative or not.

diff --git a/js/jquery.ketchup.js b/js/jquery.ketchup.js
index 8e31d2e..0be084a 100644
--- a/js/jquery.ketchup.js
+++ b/js/jquery.ketchup.js
@@ -204,17 +204,41 @@

   var initialPositionContainer = function(errorContainer, field) {
     var fOffset = field.offset();
+   var left = fOffset.left;
+   var top = fOffset.top;
+   
+   // check if there's a 'relative' parent
+   field.parents().each(function(){
+       if ($(this).css('position')=='relative')
+       {
+           fOffset = $(this).offset();
+           
+           left -= fOffset.left;
+           top -= fOffset.top;
+           
+           return false
+           
+       }
+       
+   });
+
+   // back it up for later 
+   field.data('offset',{left:left,top:top});

     errorContainer.css({
-      left: fOffset.left + field.width() - 10,
-      top: fOffset.top - errorContainer.height()
+      left: left + field.width() - 10,
+      top: top
     });
   };


   var positionContainer = function(errorContainer, field) {
+   // re-position the error, the height is correct here.
+   errorContainer.css({top:field.data('offset').top - errorContainer.height() + field.innerHeight()});
+   
+   // animate
     errorContainer.animate({
-      top: field.offset().top - errorContainer.height()
+      top: field.data('offset').top - errorContainer.height()
     });
   };

Cheers

Error on select validation

I tried to make a required select (combobox) and got the following error:

b.attr("type") is undefined
jQuery.ketchup.validation("required","...tween {arg1} and {arg2}.",function(g, ...

Is possible validation of select elements?

Validation For AJAX Forms

Hi, I'm trying to use Ketchup to validate some forms but in my case I never "submit" the forms, I call a function that sends an AJAX request to do the work.

Is there any way to "trigger" the validation and get a "true" (no errors) or "false" (errors) without submiting?

Thanks in advance and keep up the good work!

Scroll to first ketchup on submit

Hi Folks

I edited jquery.ketchup.js so it focus the frist ketchup-error-container when there's an error on submit, looks like this now:

around line 38:

  if(!tasty){
        //get the top offset of the target anchor
        var target_offset = $('div.ketchup-error-container:visible:first').offset();
        var target_top = target_offset.top - 30;

        //goto that anchor by setting the body scroll top to anchor top
        $('html, body').animate({scrollTop:target_top}, 500);
      return false;
  };

There may be a better way to do this :) but that's what I got ;)

Hope it helps somebody.

Form Reset

What's the best way to hide all validation bubbles when a user clicks a form reset button?

TIA,
Damon

Validation for file uploading

Hi,

Anybody knows about file uploading validation means user can upload only .jpg etc.,

Kindly tell me how to give that..
Thanks in advance

Need help, Would really be happy to get some help :) please.

I am using this with a 3rd part forms app, I have been able to integrate ketchup with live validation but I have the regular styles, I am trying to convert it to the pop-under style as shown here:

Have it your way. Error-Container styling and behaviour. ( http://demos.usejquery.com/ketchup-plugin/yourway.html )

Right now I use the normal styling as shown here: http://demos.usejquery.com/ketchup-plugin/yourway.html

Here is the code which I use along with my code:

<script type="text/javascript" src="/form-lead-management/js/ketchup-plugin/js/jquery.ketchup.js"></script> <script type="text/javascript" src="/form-lead-management/js/ketchup-plugin/js/jquery.ketchup.messages.js"></script> <script type="text/javascript" src="/form-lead-management/js/ketchup-plugin/js/jquery.ketchup.validations.basic.js"></script> <script type="text/javascript"> $(document).ready(function() { //add ketchup class to field //name $('#form_3 input#element_2_1').addClass("validate(required)"); $('#form_3 input#element_2_2').addClass("validate(required)"); $('#form_3 input#element_2_3').addClass("validate(required)"); $('#form_3 input#element_2_4').addClass("validate(required)"); //phone $('#form_3 input#element_1_1').addClass("validate(required)"); $('#form_3 input#element_1_2').addClass("validate(required)"); $('#form_3 input#element_1_3').addClass("validate(required)"); //email $('#form_3 input#element_3').addClass("aaaaaaaaaaaaaaaaa"); //city $('#form_3 input#element_5').addClass("validate(required)"); //service $('#form_3 input#element_4').addClass("validate(required)"); $('#form_3').ketchup(); }); </script>

My question is, how would I make it work with the new validation as shown here Have it your way. Error-Container styling and behaviour. ( http://demos.usejquery.com/ketchup-plugin/yourway.html )

I tried to tweak and make changes but I just could not get it to work, any help would be great,

Thank you guys and amazing work!

Samer

We really need a submitHandler

I can use you validation only if the forms are submitting normally to another window.
I need to use it with ajaxSubmit instead of submit.
please

offset v. offsetParent

If your form element is child to a relatively or absolutely positioned element, the error messages are in the wrong place.

Should inject the messages into the end of the body, instead of after the form element.

Need 'optional field' behavior

For example, I have a field that is optional for the user but if they type something in it, I want to check it to make sure it is a valid URL. If nothing has been entered then I just want the validation bypassed. If I just have validate(url) then if someone just clicks in the field, and moves away they get an error popup. There should be a way to allow this. Perhaps a flag on a field by field basis to not error on empty?

Thoughts???

Issue with validation of checkboxes

When validating checkboxes (like minselect), the other checkboxes in the group are only tagged for validation if they are siblings of the same parent element as the checkbox that the validation is tagged to. This means that if say, for styling purposes each checkbox/label is wrapped in a div, the only checkbox that the validation will be applied to is the one which is tagged with the validation code.

future date

What changes do i have to make if i want to check "no future date allowed" ???

Drop down menu with pre-selected value

How do you tell Ketchup to work on a drop-down menu if there is a pre-selected option value? For example, is there a validation that says something like "require if the value is NOT this "select a state""?

where I put the code?

which file i must insert this code

$(document).ready(function() {
$('#example1').ketchup();
});

and I'll try to put this code in a form .php with the action to other .php!

Need ability to validate an entry regardless of it being required...

There are some inputs on my form that are not required, but that could still benefit from being validated. However, it appears that this is currently not possible. The plugin treats any element that's not "tasty" as being invalid and prevents the form from being submitted, even if the input is not also marked as being required.

error in position

i have one error in position when I validade a form inside a div opened by blockUI ....
the code:

$("#btnID").bind("click",function()
{
$.blockUI(
{
message: $("#form2"),
});

$("#form2").ketchup(
{
onSuccess: login,
initialPositionContainer: function( errorContainer , field ){},
positionContainer: function(errorContainer, field){}
});
});

the buble appears below the field and not in the correct position.... some can help me?

issue with validation with UI-Datepicker

I can't seem to get validation working on an input field that has a UI-datepicker attached to it. Whenever I assign a datevalue to the field with the datepicker calendar and validate it after that validation does not recognize the date value and gives the message "field is required".
How do I solve this?

Problem with positioning ( in latest version )

Hi,
The initial positioning works fine, but in my layout , when i scroll the bubble sticks to the same place. this i presume is due to the positioning relative to the body.

a short version of the current layout would be

<body scroll="no">
<form >
<div style='overflow-y:hidden;height:30px'>
some content
</div>
<div style='position:relative;overflow-y:scroll'>
some more content
<div>
<input type='text' data-validate='validate(required, email)' id='mail'>
<input type='submit'/>
</div>
</div>
</form>
<!--your bubble div comes here-->
</body>

Now, if the page uses similar layout, the plugin breaks.

process document event "onresize"

some code:

$.fn.ketchup = function(opt) {
options = $.extend({}, $.fn.ketchup.defaults, opt);

// ++ PATCH
var ketchup = this.data("doc-height", $(document).height() );
$(document).click( function ()
{
  var previousHeight = ketchup.data("doc-height");
  var nextHeight = $(document).height();
  if (nextHeight != previousHeight)
  {
    $('.' + options.errorContainer.attr("class")).each( function ()
    {
      var bubble = $(this);
      bubble.animate({
        top: bubble.offset().top + nextHeight - previousHeight
      })
    });
    ketchup.data("doc-height", nextHeight);
  }
});
// -- PATCH

return this.each(function() {
  squeeze($(this));
});

};

Whitespace validation

In the about you portion of the demo, one can enter more than ten spaces. maybe multiple (3+) &nbsp could be filtered out of the count?

French version

Hello !

I have translated messages in french :

'required': 'Ce champ est obligatoire',

'minlength': 'Ce champ doit avoir une taille minimale de $arg1.',

'maxlength': 'Ce champ doit avoir une taille maximale de $arg1.',

'rangelength': 'Ce champ doit avoir une taille comprise entre $arg1 et $arg2.',

'min': 'Doit contenir au moins $arg1.',

'max': 'Ne peut pas être plus grand que $arg1.',

'range': 'Doit être compris entre $arg1 et $arg2.',

'number': 'Vous devez indiquer un nombre',

'digits': 'Vous devez indiquer un chiffre',

'email': 'Vous devez indiquer un email valide',

'url': 'Vous devez indique une URL valide',

'username': 'Vous devez indiquer un login valide',

'match': 'Doit correspondre au champ ci-dessus',

'date': 'Vous devez indiquer une date valide',

'minselect': 'Sélectionner au moins $arg1 cases à cocher.',

'maxselect': 'Ne pas sélectionner plus de $arg1 cases à cocher.',

'rangeselect': 'Sélectionner de $arg1 à $arg2 cases à cocher.'

Have fun with ketchup...

jquery conflicts

hello
I am using jgrowl on the same page where i am trying to validate the fields at the same time now the problem is both are jquery and are mutually exclusive..what to do?
pleae help
// For Jgrowl
<script src="../jquery-1.3.2.js" type="text/javascript"></script>
<script src="../jquery.jgrowl.js" type="text/javascript"></script>

//For Ketchup

<script src="../JS/ketchup.jquery.min.js" type="text/javascript"></script> <script src="../JS/ketchup.jquery.ketchup.js" type="text/javascript"></script> <script src="../JS/ketchup.jquery.ketchup.messages.js" type="text/javascript"></script> <script src="../JS/ketchup.jquery.ketchup.validations.basic.js" type="text/javascript"></script>
        <script type ="text/javascript">
        $(document).ready(function() {
        $('#example1').ketchup();
        });
        </script>

Possible to validate a SELECT?

I can't find anywhere about validating a select (drop down list) with ketchup, I've tried but it doesn't work, anyone else done this?

minselect matches name, useless for checkboxes

If you've got:

<input type=checkbox name=one value="one"> One
<input type=checkbox name=one class="validates(minselect(1))" value="two"> Two

The validation works great, but it's useless. When a user select both checkboxes only one value is passed to the sever, in this case "two" would be passed even though both are selected. Checkboxes can't share the same name.

Currently I'm using a custom data-group attribute and using that in the validation. I'm not settled on the best solution, but the current implementation is borked so I'm going with a data attribute.

An alternative I like is using fieldset and wrapping all the checkboxes into a fieldset and using that to find the checked elements.

horizontal position

// ++ PATCH
function changePosition (errorContainer, field, handler)
{
var fOffset = field.offset();

errorContainer[handler]({
  left: fOffset.left + field.width() - 10,
  top: fOffset.top - errorContainer.height()
});

}
// -- PATCH

var initialPositionContainer = function(errorContainer, field) {
changePosition(errorContainer, field, "css"); // ++ PATCH
};

var positionContainer = function(errorContainer, field) {
changePosition(errorContainer, field, "animate"); // ++ PATCH
};

Useful functions

I have modified ketchup in order to be able to run custom functions in key events :

  • before validation
  • after validation
  • on successful validation
  • on failed validation

Here are my changes :
...
form.submit(function() {
options.beforeValidation();
var tasty = true;

        for ( var i = 0; i < fields.length; i++) {
            if (buildErrorList(extractValidations(fields[i].blur()),
                    fields[i]).length)
                tasty = false;
        }

        options.afterValidation();

        if (!tasty) {
            options.onFailure();
            return false;
        }

        return options.onSuccess();
    });
    ...
var beforeValidation = function() {};
var onSuccess = function() {return true;};
var onFailure = function() {};
var afterValidation = function() {};
...
$.fn.ketchup.defaults = {
    validationAttribute : 'class',
    errorContainer : errorContainer,
    initialPositionContainer : initialPositionContainer,
    positionContainer : positionContainer,
    showContainer : showContainer,
    hideContainer : hideContainer,
    beforeValidation : beforeValidation,
    onSuccess : onSuccess,
    onFailure : onFailure,
    afterValidation : afterValidation
};

hide error container on click

function bindField(field) {
...
errorContainer.click( function () {
hideContainer( $(this) );
visibleContainer = false;
});
...
}

bug: Custom validations fail if they take a parameter and end in "on"

Custom validations will fail if they take a parameter and end in "on"

Suppose you create a function -

password_confirmation(.orig_password_field)

This would become:

data-validate="validate(password_confirmation(.orig_password_field))"

Look at the function "extractEvents" -

extractEvents: function(toExtract, indicator) {
  var events = false,
  pos    = toExtract.indexOf(indicator + '(');

In the default release indicator is "on". Ergo, for the example above, it ends up returning the parameter we're passing into our custom validation. Instead, extract events should return false so that the default events are used.

The fix would be to change the code so that it does a regex for a space or a quote mark followed by the indicator... This allows the indicator to start the validation string or be placed after it provided there is a space..

The temporary workaround we're using is changing the indicator to " on" and requring that the on part of the statement always be specified second.

Renaming of rules

A more appropriate name for the "username" rule would be "alphaNumeric" or similar. Many sites allow usernames containing dots and underscores.

Similarly if there is another text field where only letters and numbers are allowed the default error message is rather misleading; "must be a valid username".

Perhaps a default "alphaNumeric" rule would be possible to see in future versions?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.