123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /* http://keith-wood.name/realPerson.html
- Real Person Form Submission for jQuery v1.0.1.
- Written by Keith Wood (kwood{at}iinet.com.au) June 2009.
- Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
- MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
- Please attribute the author if you use it. */
- (function($) { // Hide scope, no $ conflict
- var PROP_NAME = 'realPerson';
- /* Real person manager. */
- function RealPerson() {
- this._defaults = {
- length: 6, // Number of characters to use
- includeNumbers: false, // True to use numbers as well as letters
- regenerate: 'Click to change', // Instruction text to regenerate
- hashName: '{n}Hash' // Name of the hash value field to compare with,
- // use {n} to substitute with the original field name
- };
- }
- var CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- var DOTS = [
- [' * ', ' * * ', ' * * ', ' * * ', ' ***** ', '* *', '* *'],
- ['****** ', '* *', '* *', '****** ', '* *', '* *', '****** '],
- [' ***** ', '* *', '* ', '* ', '* ', '* *', ' ***** '],
- ['****** ', '* *', '* *', '* *', '* *', '* *', '****** '],
- ['*******', '* ', '* ', '**** ', '* ', '* ', '*******'],
- ['*******', '* ', '* ', '**** ', '* ', '* ', '* '],
- [' ***** ', '* *', '* ', '* ', '* ***', '* *', ' ***** '],
- ['* *', '* *', '* *', '*******', '* *', '* *', '* *'],
- ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'],
- [' *', ' *', ' *', ' *', ' *', '* *', ' ***** '],
- ['* *', '* ** ', '* ** ', '** ', '* ** ', '* ** ', '* *'],
- ['* ', '* ', '* ', '* ', '* ', '* ', '*******'],
- ['* *', '** **', '* * * *', '* * *', '* *', '* *', '* *'],
- ['* *', '** *', '* * *', '* * *', '* * *', '* **', '* *'],
- [' ***** ', '* *', '* *', '* *', '* *', '* *', ' ***** '],
- ['****** ', '* *', '* *', '****** ', '* ', '* ', '* '],
- [' ***** ', '* *', '* *', '* *', '* * *', '* * ', ' **** *'],
- ['****** ', '* *', '* *', '****** ', '* * ', '* * ', '* *'],
- [' ***** ', '* *', '* ', ' ***** ', ' *', '* *', ' ***** '],
- ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
- ['* *', '* *', '* *', '* *', '* *', '* *', ' ***** '],
- ['* *', '* *', ' * * ', ' * * ', ' * * ', ' * * ', ' * '],
- ['* *', '* *', '* *', '* * *', '* * * *', '** **', '* *'],
- ['* *', ' * * ', ' * * ', ' * ', ' * * ', ' * * ', '* *'],
- ['* *', ' * * ', ' * * ', ' * ', ' * ', ' * ', ' * '],
- ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'],
- [' *** ', ' * * ', '* *', '* *', '* *', ' * * ', ' *** '],
- [' * ', ' ** ', ' * * ', ' * ', ' * ', ' * ', '*******'],
- [' ***** ', '* *', ' *', ' * ', ' ** ', ' ** ', '*******'],
- [' ***** ', '* *', ' *', ' ** ', ' *', '* *', ' ***** '],
- [' * ', ' ** ', ' * * ', ' * * ', '*******', ' * ', ' * '],
- ['*******', '* ', '****** ', ' *', ' *', '* *', ' ***** '],
- [' **** ', ' * ', '* ', '****** ', '* *', '* *', ' ***** '],
- ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '* '],
- [' ***** ', '* *', '* *', ' ***** ', '* *', '* *', ' ***** '],
- [' ***** ', '* *', '* *', ' ******', ' *', ' * ', ' **** ']];
- $.extend(RealPerson.prototype, {
- /* Class name added to elements to indicate already configured with real person. */
- markerClassName: 'hasRealPerson',
- /* Override the default settings for all real person instances.
- @param settings (object) the new settings to use as defaults
- @return (RealPerson) this object */
- setDefaults: function(settings) {
- $.extend(this._defaults, settings || {});
- return this;
- },
- /* Attach the real person functionality to an input field.
- @param target (element) the control to affect
- @param settings (object) the custom options for this instance */
- _attachRealPerson: function(target, settings) {
- target = $(target);
- if (target.hasClass(this.markerClassName)) {
- return;
- }
- target.addClass(this.markerClassName);
- var inst = {settings: $.extend({}, this._defaults)};
- $.data(target[0], PROP_NAME, inst);
- this._changeRealPerson(target, settings);
- },
- /* Reconfigure the settings for a real person control.
- @param target (element) the control to affect
- @param settings (object) the new options for this instance or
- (string) an individual property name
- @param value (any) the individual property value (omit if settings is an object) */
- _changeRealPerson: function(target, settings, value) {
- target = $(target);
- if (!target.hasClass(this.markerClassName)) {
- return;
- }
- settings = settings || {};
- if (typeof settings == 'string') {
- var name = settings;
- settings = {};
- settings[name] = value;
- }
- var inst = $.data(target[0], PROP_NAME);
- $.extend(inst.settings, settings);
- target.prevAll('.realperson-challenge,.realperson-hash').remove().end().
- before(this._generateHTML(target, inst));
- },
- /* Generate the additional content for this control.
- @param target (jQuery) the input field
- @param inst (object) the current instance settings
- @return (string) the additional content */
- _generateHTML: function(target, inst) {
- var text = '';
- for (var i = 0; i < inst.settings.length; i++) {
- text += CHARS.charAt(Math.floor(Math.random() *
- (inst.settings.includeNumbers ? 36 : 26)));
- }
- var html = '<div class="realperson-challenge"><div class="realperson-text">';
- for (var i = 0; i < DOTS[0].length; i++) {
- for (var j = 0; j < text.length; j++) {
- html += DOTS[CHARS.indexOf(text.charAt(j))][i].replace(/ /g, ' ') +
- ' ';
- }
- html += '<br>';
- }
- html += '</div><div class="realperson-regen">' + inst.settings.regenerate +
- '</div></div><input type="hidden" class="realperson-hash" name="' +
- inst.settings.hashName.replace(/\{n\}/, target.attr('name')) +
- '" value="' + this._hash(text) + '">';
- return html;
- },
- /* Remove the real person functionality from a control.
- @param target (element) the control to affect */
- _destroyRealPerson: function(target) {
- target = $(target);
- if (!target.hasClass(this.markerClassName)) {
- return;
- }
- target.removeClass(this.markerClassName).
- prevAll('.realperson-challenge,.realperson-hash').remove();
- $.removeData(target[0], PROP_NAME);
- },
- /* Compute a hash value for the given text.
- @param value (string) the text to hash
- @return the corresponding hash value */
- _hash: function(value) {
- var hash = 5381;
- for (var i = 0; i < value.length; i++) {
- hash = ((hash << 5) + hash) + value.charCodeAt(i);
- }
- return hash;
- }
- });
- /* Attach the real person functionality to a jQuery selection.
- @param command (string) the command to run (optional, default 'attach')
- @param options (object) the new settings to use for these instances (optional)
- @return (jQuery) for chaining further calls */
- $.fn.realperson = function(options) {
- var otherArgs = Array.prototype.slice.call(arguments, 1);
- return this.each(function() {
- if (typeof options == 'string') {
- $.realperson['_' + options + 'RealPerson'].
- apply($.realperson, [this].concat(otherArgs));
- }
- else {
- $.realperson._attachRealPerson(this, options || {});
- }
- });
- };
- /* Initialise the real person functionality. */
- $.realperson = new RealPerson(); // singleton instance
- $('.realperson-challenge').live('click', function() {
- $(this).next().next().realperson('change');
- });
- })(jQuery);
|