(function($) {/*-------------------JQUERY FORM PARA EL PLUG IN DE VALIDACION CON AJAX -----------------------*//** * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX. * * ajaxSubmit accepts a single argument which can be either a success callback function * or an options Object.  If a function is provided it will be invoked upon successful * completion of the submit and will be passed the response from the server. * If an options Object is provided, the following attributes are supported: * *  target:   Identifies the element(s) in the page to be updated with the server response. *            This value may be specified as a jQuery selection string, a jQuery object, *            or a DOM element. *            default value: null * *  url:      URL to which the form data will be submitted. *            default value: value of form's 'action' attribute * *  type:     The method in which the form data should be submitted, 'GET' or 'POST'. *            default value: value of form's 'method' attribute (or 'GET' if none found) * *  data:     Additional data to add to the request, specified as key/value pairs (see $.ajax). * *  beforeSubmit:  Callback method to be invoked before the form is submitted. *            default value: null * *  success:  Callback method to be invoked after the form has been successfully submitted *            and the response has been returned from the server *            default value: null * *  dataType: Expected dataType of the response.  One of: null, 'xml', 'script', or 'json' *            default value: null * *  semantic: Boolean flag indicating whether data must be submitted in semantic order (slower). *            default value: false * *  resetForm: Boolean flag indicating whether the form should be reset if the submit is successful * *  clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful * * * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for * validating the form data.  If the 'beforeSubmit' callback returns false then the form will * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data * in array format, the jQuery object, and the options object passed into ajaxSubmit. * The form data array takes the following form: * *     [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] * * If a 'success' callback method is provided it is invoked after the response has been returned * from the server.  It is passed the responseText or responseXML value (depending on dataType). * See jQuery.ajax for further details. * * * The dataType option provides a means for specifying how the server response should be handled. * This maps directly to the jQuery.httpData method.  The following values are supported: * *      'xml':    if dataType == 'xml' the server response is treated as XML and the 'success' *                   callback method, if specified, will be passed the responseXML value *      'json':   if dataType == 'json' the server response will be evaluted and passed to *                   the 'success' callback, if specified *      'script': if dataType == 'script' the server response is evaluated in the global context * * * Note that it does not make sense to use both the 'target' and 'dataType' options.  If both * are provided the target will be ignored. * * The semantic argument can be used to force form serialization in semantic order. * This is normally true anyway, unless the form contains input elements of type='image'. * If your form must be submitted with name/value pairs in semantic order and your form * contains an input of type='image" then pass true for this arg, otherwise pass false * (or nothing) to avoid the overhead for this logic. * * * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this: * * $("#form-id").submit(function() { *     $(this).ajaxSubmit(options); *     return false; // cancel conventional submit * }); * * When using ajaxForm(), however, this is done for you. * * @example * $('#myForm').ajaxSubmit(function(data) { *     alert('Form submit succeeded! Server returned: ' + data); * }); * @desc Submit form and alert server response * * * @example * var options = { *     target: '#myTargetDiv' * }; * $('#myForm').ajaxSubmit(options); * @desc Submit form and update page element with server response * * * @example * var options = { *     success: function(responseText) { *         alert(responseText); *     } * }; * $('#myForm').ajaxSubmit(options); * @desc Submit form and alert the server response * * * @example * var options = { *     beforeSubmit: function(formArray, jqForm) { *         if (formArray.length == 0) { *             alert('Please enter data.'); *             return false; *         } *     } * }; * $('#myForm').ajaxSubmit(options); * @desc Pre-submit validation which aborts the submit operation if form data is empty * * * @example * var options = { *     url: myJsonUrl.php, *     dataType: 'json', *     success: function(data) { *        // 'data' is an object representing the the evaluated json data *     } * }; * $('#myForm').ajaxSubmit(options); * @desc json data returned and evaluated * * * @example * var options = { *     url: myXmlUrl.php, *     dataType: 'xml', *     success: function(responseXML) { *        // responseXML is XML document object *        var data = $('myElement', responseXML).text(); *     } * }; * $('#myForm').ajaxSubmit(options); * @desc XML data returned from server * * * @example * var options = { *     resetForm: true * }; * $('#myForm').ajaxSubmit(options); * @desc submit form and reset it if successful * * @example * $('#myForm).submit(function() { *    $(this).ajaxSubmit(); *    return false; * }); * @desc Bind form's submit event to use ajaxSubmit * * * @name ajaxSubmit * @type jQuery * @param options  object literal containing options which control the form submission process * @cat Plugins/Form * @return jQuery */$.fn.ajaxSubmit = function(options) {    if (typeof options == 'function')        options = { success: options };    options = $.extend({        url:  this.attr('action') || window.location,        type: this.attr('method') || 'GET'    }, options || {});    // hook for manipulating the form data before it is extracted;    // convenient for use with rich editors like tinyMCE or FCKEditor    var veto = {};    $.event.trigger('form.pre.serialize', [this, options, veto]);    if (veto.veto) return this;    var a = this.formToArray(options.semantic);	if (options.data) {	    for (var n in options.data)	        a.push( { name: n, value: options.data[n] } );	}    // give pre-submit callback an opportunity to abort the submit    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;    // fire vetoable 'validate' event    $.event.trigger('form.submit.validate', [a, this, options, veto]);    if (veto.veto) return this;    var q = $.param(a);//.replace(/%20/g,'+');    if (options.type.toUpperCase() == 'GET') {        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;        options.data = null;  // data is null for 'get'    }    else        options.data = q; // data is the query string for 'post'    var $form = this, callbacks = [];    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });    // perform a load on the target only if dataType is not provided    if (!options.dataType && options.target) {        var oldSuccess = options.success || function(){};        callbacks.push(function(data) {            if (this.evalScripts)                $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments);            else // jQuery v1.1.4                $(options.target).html(data).each(oldSuccess, arguments);        });    }    else if (options.success)        callbacks.push(options.success);    options.success = function(data, status) {        for (var i=0, max=callbacks.length; i < max; i++)            callbacks[i](data, status, $form);    };    // are there files to upload?    var files = $('input:file', this).fieldValue();    var found = false;    for (var j=0; j < files.length; j++)        if (files[j])            found = true;    if (options.iframe || found) // options.iframe allows user to force iframe mode        fileUpload();    else        $.ajax(options);    // fire 'notify' event    $.event.trigger('form.submit.notify', [this, options]);    return this;    // private function for handling file uploads (hat tip to YAHOO!)    function fileUpload() {        var form = $form[0];        var opts = $.extend({}, $.ajaxSettings, options);        var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;        var $io = $('<iframe id="' + id + '" name="' + id + '" />');        var io = $io[0];        var op8 = $.browser.opera && window.opera.version() < 9;        if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });        var xhr = { // mock object            responseText: null,            responseXML: null,            status: 0,            statusText: 'n/a',            getAllResponseHeaders: function() {},            getResponseHeader: function() {},            setRequestHeader: function() {}        };        var g = opts.global;        // trigger ajax global events so that activity/block indicators work like normal        if (g && ! $.active++) $.event.trigger("ajaxStart");        if (g) $.event.trigger("ajaxSend", [xhr, opts]);        var cbInvoked = 0;        var timedOut = 0;        // take a breath so that pending repaints get some cpu time before the upload starts        setTimeout(function() {            $io.appendTo('body');            // jQuery's event binding doesn't work for iframe events in IE            io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);            // make sure form attrs are set            var encAttr = form.encoding ? 'encoding' : 'enctype';            var t = $form.attr('target');            $form.attr({                target:   id,                method:  'POST',                action:   opts.url            });            form[encAttr] = 'multipart/form-data';            // support timout            if (opts.timeout)                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);            form.submit();            $form.attr('target', t); // reset target        }, 10);        function cb() {            if (cbInvoked++) return;            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);            var ok = true;            try {                if (timedOut) throw 'timeout';                // extract the server response from the iframe                var data, doc;                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;                xhr.responseText = doc.body ? doc.body.innerHTML : null;                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;                if (opts.dataType == 'json' || opts.dataType == 'script') {                    var ta = doc.getElementsByTagName('textarea')[0];                    data = ta ? ta.value : xhr.responseText;                    if (opts.dataType == 'json')                        eval("data = " + data);                    else                        $.globalEval(data);                }                else if (opts.dataType == 'xml') {                    data = xhr.responseXML;                    if (!data && xhr.responseText != null)                        data = toXml(xhr.responseText);                }                else {                    data = xhr.responseText;                }            }            catch(e){                ok = false;                $.handleError(opts, xhr, 'error', e);            }            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it            if (ok) {                opts.success(data, 'success');                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);            }            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);            if (g && ! --$.active) $.event.trigger("ajaxStop");            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');            // clean up            setTimeout(function() {                $io.remove();                xhr.responseXML = null;            }, 100);        };        function toXml(s, doc) {            if (window.ActiveXObject) {                doc = new ActiveXObject('Microsoft.XMLDOM');                doc.async = 'false';                doc.loadXML(s);            }            else                doc = (new DOMParser()).parseFromString(s, 'text/xml');            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;        };    };};$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids/** * ajaxForm() provides a mechanism for fully automating form submission. * * The advantages of using this method instead of ajaxSubmit() are: * * 1: This method will include coordinates for <input type="image" /> elements (if the element *    is used to submit the form). * 2. This method will include the submit element's name/value data (for the element that was *    used to submit the form). * 3. This method binds the submit() method to the form for you. * * Note that for accurate x/y coordinates of image submit elements in all browsers * you need to also use the "dimensions" plugin (this method will auto-detect its presence). * * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely * passes the options argument along after properly binding events for submit elements and * the form itself.  See ajaxSubmit for a full description of the options argument. * * * @example * var options = { *     target: '#myTargetDiv' * }; * $('#myForm').ajaxSForm(options); * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response *       when the form is submitted. * * * @example * var options = { *     success: function(responseText) { *         alert(responseText); *     } * }; * $('#myForm').ajaxSubmit(options); * @desc Bind form's submit event so that server response is alerted after the form is submitted. * * * @example * var options = { *     beforeSubmit: function(formArray, jqForm) { *         if (formArray.length == 0) { *             alert('Please enter data.'); *             return false; *         } *     } * }; * $('#myForm').ajaxSubmit(options); * @desc Bind form's submit event so that pre-submit callback is invoked before the form *       is submitted. * * * @name   ajaxForm * @param  options  object literal containing options which control the form submission process * @return jQuery * @cat    Plugins/Form * @type   jQuery */$.fn.ajaxForm = function(options) {    return this.ajaxFormUnbind().submit(submitHandler).each(function() {        // store options in hash        this.formPluginId = $.fn.ajaxForm.counter++;        $.fn.ajaxForm.optionHash[this.formPluginId] = options;        $(":submit,input:image", this).click(clickHandler);    });};$.fn.ajaxForm.counter = 1;$.fn.ajaxForm.optionHash = {};function clickHandler(e) {    var $form = this.form;    $form.clk = this;    if (this.type == 'image') {        if (e.offsetX != undefined) {            $form.clk_x = e.offsetX;            $form.clk_y = e.offsetY;        } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin            var offset = $(this).offset();            $form.clk_x = e.pageX - offset.left;            $form.clk_y = e.pageY - offset.top;        } else {            $form.clk_x = e.pageX - this.offsetLeft;            $form.clk_y = e.pageY - this.offsetTop;        }    }    // clear form vars    setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);};function submitHandler() {    // retrieve options from hash    var id = this.formPluginId;    var options = $.fn.ajaxForm.optionHash[id];    $(this).ajaxSubmit(options);    return false;};/** * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm * * @name   ajaxFormUnbind * @return jQuery * @cat    Plugins/Form * @type   jQuery */$.fn.ajaxFormUnbind = function() {    this.unbind('submit', submitHandler);    return this.each(function() {        $(":submit,input:image", this).unbind('click', clickHandler);    });};/** * formToArray() gathers form element data into an array of objects that can * be passed to any of the following ajax functions: $.get, $.post, or load. * Each object in the array has both a 'name' and 'value' property.  An example of * an array for a simple login form might be: * * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ] * * It is this array that is passed to pre-submit callback functions provided to the * ajaxSubmit() and ajaxForm() methods. * * The semantic argument can be used to force form serialization in semantic order. * This is normally true anyway, unless the form contains input elements of type='image'. * If your form must be submitted with name/value pairs in semantic order and your form * contains an input of type='image" then pass true for this arg, otherwise pass false * (or nothing) to avoid the overhead for this logic. * * @example var data = $("#myForm").formToArray(); * $.post( "myscript.cgi", data ); * @desc Collect all the data from a form and submit it to the server. * * @name formToArray * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) * @type Array<Object> * @cat Plugins/Form */$.fn.formToArray = function(semantic) {    var a = [];    if (this.length == 0) return a;    var form = this[0];    var els = semantic ? form.getElementsByTagName('*') : form.elements;    if (!els) return a;    for(var i=0, max=els.length; i < max; i++) {        var el = els[i];        var n = el.name;        if (!n) continue;        if (semantic && form.clk && el.type == "image") {            // handle image inputs on the fly when semantic == true            if(!el.disabled && form.clk == el)                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});            continue;        }        var v = $.fieldValue(el, true);        if (v && v.constructor == Array) {            for(var j=0, jmax=v.length; j < jmax; j++)                a.push({name: n, value: v[j]});        }        else if (v !== null && typeof v != 'undefined')            a.push({name: n, value: v});    }    if (!semantic && form.clk) {        // input type=='image' are not found in elements array! handle them here        var inputs = form.getElementsByTagName("input");        for(var i=0, max=inputs.length; i < max; i++) {            var input = inputs[i];            var n = input.name;            if(n && !input.disabled && input.type == "image" && form.clk == input)                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});        }    }    return a;};/** * Serializes form data into a 'submittable' string. This method will return a string * in the format: name1=value1&name2=value2 * * The semantic argument can be used to force form serialization in semantic order. * If your form must be submitted with name/value pairs in semantic order then pass * true for this arg, otherwise pass false (or nothing) to avoid the overhead for * this logic (which can be significant for very large forms). * * @example var data = $("#myForm").formSerialize(); * $.ajax('POST', "myscript.cgi", data); * @desc Collect all the data from a form into a single string * * @name formSerialize * @param semantic true if serialization must maintain strict semantic ordering of elements (slower) * @type String * @cat Plugins/Form */$.fn.formSerialize = function(semantic) {    //hand off to jQuery.param for proper encoding    return $.param(this.formToArray(semantic));};/** * Serializes all field elements in the jQuery object into a query string. * This method will return a string in the format: name1=value1&name2=value2 * * The successful argument controls whether or not serialization is limited to * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). * The default value of the successful argument is true. * * @example var data = $("input").formSerialize(); * @desc Collect the data from all successful input elements into a query string * * @example var data = $(":radio").formSerialize(); * @desc Collect the data from all successful radio input elements into a query string * * @example var data = $("#myForm :checkbox").formSerialize(); * @desc Collect the data from all successful checkbox input elements in myForm into a query string * * @example var data = $("#myForm :checkbox").formSerialize(false); * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string * * @example var data = $(":input").formSerialize(); * @desc Collect the data from all successful input, select, textarea and button elements into a query string * * @name fieldSerialize * @param successful true if only successful controls should be serialized (default is true) * @type String * @cat Plugins/Form */$.fn.fieldSerialize = function(successful) {    var a = [];    this.each(function() {        var n = this.name;        if (!n) return;        var v = $.fieldValue(this, successful);        if (v && v.constructor == Array) {            for (var i=0,max=v.length; i < max; i++)                a.push({name: n, value: v[i]});        }        else if (v !== null && typeof v != 'undefined')            a.push({name: this.name, value: v});    });    //hand off to jQuery.param for proper encoding    return $.param(a);};/** * Returns the value(s) of the element in the matched set.  For example, consider the following form: * *  <form><fieldset> *      <input name="A" type="text" /> *      <input name="A" type="text" /> *      <input name="B" type="checkbox" value="B1" /> *      <input name="B" type="checkbox" value="B2"/> *      <input name="C" type="radio" value="C1" /> *      <input name="C" type="radio" value="C2" /> *  </fieldset></form> * *  var v = $(':text').fieldValue(); *  // if no values are entered into the text inputs *  v == ['',''] *  // if values entered into the text inputs are 'foo' and 'bar' *  v == ['foo','bar'] * *  var v = $(':checkbox').fieldValue(); *  // if neither checkbox is checked *  v === undefined *  // if both checkboxes are checked *  v == ['B1', 'B2'] * *  var v = $(':radio').fieldValue(); *  // if neither radio is checked *  v === undefined *  // if first radio is checked *  v == ['C1'] * * The successful argument controls whether or not the field element must be 'successful' * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). * The default value of the successful argument is true.  If this value is false the value(s) * for each element is returned. * * Note: This method *always* returns an array.  If no valid value can be determined the *       array will be empty, otherwise it will contain one or more values. * * @example var data = $("#myPasswordElement").fieldValue(); * alert(data[0]); * @desc Alerts the current value of the myPasswordElement element * * @example var data = $("#myForm :input").fieldValue(); * @desc Get the value(s) of the form elements in myForm * * @example var data = $("#myForm :checkbox").fieldValue(); * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object. * * @example var data = $("#mySingleSelect").fieldValue(); * @desc Get the value(s) of the select control * * @example var data = $(':text').fieldValue(); * @desc Get the value(s) of the text input or textarea elements * * @example var data = $("#myMultiSelect").fieldValue(); * @desc Get the values for the select-multiple control * * @name fieldValue * @param Boolean successful true if only the values for successful controls should be returned (default is true) * @type Array<String> * @cat Plugins/Form */$.fn.fieldValue = function(successful) {    for (var val=[], i=0, max=this.length; i < max; i++) {        var el = this[i];        var v = $.fieldValue(el, successful);        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))            continue;        v.constructor == Array ? $.merge(val, v) : val.push(v);    }    return val;};/** * Returns the value of the field element. * * The successful argument controls whether or not the field element must be 'successful' * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls). * The default value of the successful argument is true.  If the given element is not * successful and the successful arg is not false then the returned value will be null. * * Note: If the successful flag is true (default) but the element is not successful, the return will be null * Note: The value returned for a successful select-multiple element will always be an array. * Note: If the element has no value the return value will be undefined. * * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]); * @desc Gets the current value of the myPasswordElement element * * @name fieldValue * @param Element el The DOM element for which the value will be returned * @param Boolean successful true if value returned must be for a successful controls (default is true) * @type String or Array<String> or null or undefined * @cat Plugins/Form */$.fieldValue = function(el, successful) {    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();    if (typeof successful == 'undefined') successful = true;    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||        (t == 'checkbox' || t == 'radio') && !el.checked ||        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||        tag == 'select' && el.selectedIndex == -1))            return null;    if (tag == 'select') {        var index = el.selectedIndex;        if (index < 0) return null;        var a = [], ops = el.options;        var one = (t == 'select-one');        var max = (one ? index+1 : ops.length);        for(var i=(one ? index : 0); i < max; i++) {            var op = ops[i];            if (op.selected) {                // extra pain for IE...                var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;                if (one) return v;                a.push(v);            }        }        return a;    }    return el.value;};/** * Clears the form data.  Takes the following actions on the form's input fields: *  - input text fields will have their 'value' property set to the empty string *  - select elements will have their 'selectedIndex' property set to -1 *  - checkbox and radio inputs will have their 'checked' property set to false *  - inputs of type submit, button, reset, and hidden will *not* be effected *  - button elements will *not* be effected * * @example $('form').clearForm(); * @desc Clears all forms on the page. * * @name clearForm * @type jQuery * @cat Plugins/Form */$.fn.clearForm = function() {    return this.each(function() {        $('input,select,textarea', this).clearFields();    });};/** * Clears the selected form elements.  Takes the following actions on the matched elements: *  - input text fields will have their 'value' property set to the empty string *  - select elements will have their 'selectedIndex' property set to -1 *  - checkbox and radio inputs will have their 'checked' property set to false *  - inputs of type submit, button, reset, and hidden will *not* be effected *  - button elements will *not* be effected * * @example $('.myInputs').clearFields(); * @desc Clears all inputs with class myInputs * * @name clearFields * @type jQuery * @cat Plugins/Form */$.fn.clearFields = $.fn.clearInputs = function() {    return this.each(function() {        var t = this.type, tag = this.tagName.toLowerCase();        if (t == 'text' || t == 'password' || tag == 'textarea')            this.value = '';        else if (t == 'checkbox' || t == 'radio')            this.checked = false;        else if (tag == 'select')            this.selectedIndex = -1;    });};/** * Resets the form data.  Causes all form elements to be reset to their original value. * * @example $('form').resetForm(); * @desc Resets all forms on the page. * * @name resetForm * @type jQuery * @cat Plugins/Form */$.fn.resetForm = function() {    return this.each(function() {        // guard against an input with the name of 'reset'        // note that IE reports the reset function as an 'object'        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))            this.reset();    });};/* ------------------------------------DATE PICKER--------------------------------------- */	$.fn.extend({/** * Render a calendar table into any matched elements. *  * @param Object s (optional) Customize your calendars. * @option Number month The month to render (NOTE that months are zero based). Default is today's month. * @option Number year The year to render. Default is today's year. * @option Function renderCallback A reference to a function that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Default is no callback. * @option Number showHeader Whether or not to show the header row, possible values are: $.dpConst.SHOW_HEADER_NONE (no header), $.dpConst.SHOW_HEADER_SHORT (first letter of each day) and $.dpConst.SHOW_HEADER_LONG (full name of each day). Default is $.dpConst.SHOW_HEADER_SHORT. * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class. * @type jQuery * @name renderCalendar * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('#calendar-me').renderCalendar({month:0, year:2007}); * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me. * * @example * var testCallback = function($td, thisDate, month, year) * { * if ($td.is('.current-month') && thisDate.getDay() == 4) { *		var d = thisDate.getDate(); *		$td.bind( *			'click', *			function() *			{ *				alert('You clicked on ' + d + '/' + (Number(month)+1) + '/' + year); *			} *		).addClass('thursday'); *	} else if (thisDate.getDay() == 5) { *		$td.html('Friday the ' + $td.html() + 'th'); *	} * } * $('#calendar-me').renderCalendar({month:0, year:2007, renderCallback:testCallback}); *  * @desc Renders a calendar displaying January 2007 into the element with an id of calendar-me. Every Thursday in the current month has a class of "thursday" applied to it, is clickable and shows an alert when clicked. Every Friday on the calendar has the number inside replaced with text. **/		renderCalendar  :   function(s)		{			var dc = function(a)			{				return document.createElement(a);			};						s = $.extend(				{					month			: null,					year			: null,					renderCallback	: null,					showHeader		: $.dpConst.SHOW_HEADER_SHORT,					dpController	: null,					hoverClass		: 'dp-hover'				}				, s			);						if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {				var headRow = $(dc('tr'));				for (var i=Date.firstDayOfWeek; i<Date.firstDayOfWeek+7; i++) {					var weekday = i%7;					var day = Date.dayNames[weekday];					headRow.append(						jQuery(dc('th')).attr({'scope':'col', 'abbr':day, 'title':day, 'class':(weekday == 0 || weekday == 6 ? 'weekend' : 'weekday')}).html(s.showHeader == $.dpConst.SHOW_HEADER_SHORT ? day.substr(0, 1) : day)					);				}			};						var calendarTable = $(dc('table'))									.attr(										{											'cellspacing':2,											'className':'jCalendar'										}									)									.append(										(s.showHeader != $.dpConst.SHOW_HEADER_NONE ? 											$(dc('thead'))												.append(headRow)											:											dc('thead')										)									);			var tbody = $(dc('tbody'));						var today = (new Date()).zeroTime();						var month = s.month == undefined ? today.getMonth() : s.month;			var year = s.year || today.getFullYear();						var currentDate = new Date(year, month, 1);									var firstDayOffset = Date.firstDayOfWeek - currentDate.getDay() + 1;			if (firstDayOffset > 1) firstDayOffset -= 7;			var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + currentDate.getDaysInMonth() ) /7);			currentDate.addDays(firstDayOffset-1);						var doHover = function()			{				if (s.hoverClass) {					$(this).addClass(s.hoverClass);				}			};			var unHover = function()			{				if (s.hoverClass) {					$(this).removeClass(s.hoverClass);				}			};						var w = 0;			while (w++<weeksToDraw) {				var r = jQuery(dc('tr'));				for (var i=0; i<7; i++) {					var thisMonth = currentDate.getMonth() == month;					var d = $(dc('td'))								.text(currentDate.getDate() + '')								.attr('className', (thisMonth ? 'current-month ' : 'other-month ') +													(currentDate.isWeekend() ? 'weekend ' : 'weekday ') +													(thisMonth && currentDate.getTime() == today.getTime() ? 'today ' : '')								)								.hover(doHover, unHover)							;					if (s.renderCallback) {						s.renderCallback(d, currentDate, month, year);					}					r.append(d);					currentDate.addDays(1);				}				tbody.append(r);			}			calendarTable.append(tbody);						return this.each(				function()				{					$(this).empty().append(calendarTable);				}			);		},/** * Create a datePicker associated with each of the matched elements. * * The matched element will receive a few custom events with the following signatures: * * dateSelected(event, date, $td, status) * Triggered when a date is selected. event is a reference to the event, date is the Date selected, $td is a jquery object wrapped around the TD that was clicked on and status is whether the date was selected (true) or deselected (false) *  * dpClosed(event, selected) * Triggered when the date picker is closed. event is a reference to the event and selected is an Array containing Date objects. * * dpMonthChanged(event, displayedMonth, displayedYear) * Triggered when the month of the popped up calendar is changed. event is a reference to the event, displayedMonth is the number of the month now displayed (zero based) and displayedYear is the year of the month. * * dpDisplayed(event, $datePickerDiv) * Triggered when the date picker is created. $datePickerDiv is the div containing the date picker. Use this event to add custom content/ listeners to the popped up date picker. * * @param Object s (optional) Customize your date pickers. * @option Number month The month to render when the date picker is opened (NOTE that months are zero based). Default is today's month. * @option Number year The year to render when the date picker is opened. Default is today's year. * @option String startDate The first date date can be selected. * @option String endDate The last date that can be selected. * @option Boolean inline Whether to create the datePicker as inline (e.g. always on the page) or as a model popup. Default is false (== modal popup) * @option Boolean createButton Whether to create a .dp-choose-date anchor directly after the matched element which when clicked will trigger the showing of the date picker. Default is true. * @option Boolean showYearNavigation Whether to display buttons which allow the user to navigate through the months a year at a time. Default is true. * @option Boolean closeOnSelect Whether to close the date picker when a date is selected. Default is true. * @option Boolean displayClose Whether to create a "Close" button within the date picker popup. Default is false. * @option Boolean selectMultiple Whether a user should be able to select multiple dates with this date picker. Default is false. * @option Boolean clickInput If the matched element is an input type="text" and this option is true then clicking on the input will cause the date picker to appear. * @option Number verticalPosition The vertical alignment of the popped up date picker to the matched element. One of $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM. Default is $.dpConst.POS_TOP. * @option Number horizontalPosition The horizontal alignment of the popped up date picker to the matched element. One of $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT. * @option Number verticalOffset The number of pixels offset from the defined verticalPosition of this date picker that it should pop up in. Default in 0. * @option Number horizontalOffset The number of pixels offset from the defined horizontalPosition of this date picker that it should pop up in. Default in 0. * @option (Function|Array) renderCallback A reference to a function (or an array of seperate functions) that is called as each cell is rendered and which can add classes and event listeners to the created nodes. Each callback function will receive four arguments; a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year. Default is no callback. * @option String hoverClass The class to attach to each cell when you hover over it (to allow you to use hover effects in IE6 which doesn't support the :hover pseudo-class on elements other than links). Default is dp-hover. Pass false if you don't want a hover class. * @type jQuery * @name datePicker * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('input.date-picker').datePicker(); * @desc Creates a date picker button next to all matched input elements. When the button is clicked on the value of the selected date will be placed in the corresponding input (formatted according to Date.format). * * @example demo/index.html * @desc See the projects homepage for many more complex examples... **/		datePicker : function(s)		{						if (!$.event._dpCache) $.event._dpCache = [];						// initialise the date picker controller with the relevant settings...			s = $.extend(				{					month				: undefined,					year				: undefined,					startDate			: undefined,					endDate				: undefined,					inline				: false,					renderCallback		: [],					createButton		: true,					showYearNavigation	: true,					closeOnSelect		: true,					displayClose		: false,					selectMultiple		: false,					clickInput			: false,					verticalPosition	: $.dpConst.POS_TOP,					horizontalPosition	: $.dpConst.POS_LEFT,					verticalOffset		: 0,					horizontalOffset	: 0,					hoverClass			: 'dp-hover'				}				, s			);						return this.each(				function()				{					var $this = $(this);					var alreadyExists = true;										if (!this._dpId) {						this._dpId = $.event.guid++;						$.event._dpCache[this._dpId] = new DatePicker(this);						alreadyExists = false;					}										if (s.inline) {						s.createButton = false;						s.displayClose = false;						s.closeOnSelect = false;						$this.empty();					}										var controller = $.event._dpCache[this._dpId];										controller.init(s);										if (!alreadyExists && s.createButton) {						// create it!						controller.button = $('<a href="#" class="dp-choose-date" title="' + $.dpText.TEXT_CHOOSE_DATE + '">' + $.dpText.TEXT_CHOOSE_DATE + '</a>')								.bind(									'click',									function()									{										$this.dpDisplay(this);										this.blur();										return false;									}								);						$this.after(controller.button);					}										if (!alreadyExists && $this.is(':text')) {						$this							.bind(								'dateSelected',								function(e, selectedDate, $td)								{									this.value = selectedDate.asString();								}							).bind(								'change',								function()								{									var d = Date.fromString(this.value);									if (d) {										controller.setSelected(d, true, true);									}								}							);						if (s.clickInput) {							$this.bind(								'click',								function()								{									$this.dpDisplay();								}							);						}						var d = Date.fromString(this.value);						if (this.value != '' && d) {							controller.setSelected(d, true, true);						}					}										$this.addClass('dp-applied');									}			)		},/** * Disables or enables this date picker * * @param Boolean s Whether to disable (true) or enable (false) this datePicker * @type jQuery * @name dpSetDisabled * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('.date-picker').datePicker(); * $('.date-picker').dpSetDisabled(true); * @desc Prevents this date picker from displaying and adds a class of dp-disabled to it (and it's associated button if it has one) for styling purposes. If the matched element is an input field then it will also set the disabled attribute to stop people directly editing the field. **/		dpSetDisabled : function(s)		{			return _w.call(this, 'setDisabled', s);		},/** * Updates the first selectable date for any date pickers on any matched elements. * * @param String d A string representing the first selectable date (formatted according to Date.format). * @type jQuery * @name dpSetStartDate * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('.date-picker').datePicker(); * $('.date-picker').dpSetStartDate('01/01/2000'); * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the first selectable date for each of these to the first day of the millenium. **/		dpSetStartDate : function(d)		{			return _w.call(this, 'setStartDate', d);		},/** * Updates the last selectable date for any date pickers on any matched elements. * * @param String d A string representing the last selectable date (formatted according to Date.format). * @type jQuery * @name dpSetEndDate * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('.date-picker').datePicker(); * $('.date-picker').dpSetEndDate('01/01/2010'); * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the last selectable date for each of these to the first Janurary 2010. **/		dpSetEndDate : function(d)		{			return _w.call(this, 'setEndDate', d);		},/** * Gets a list of Dates currently selected by this datePicker. This will be an empty array if no dates are currently selected or NULL if there is no datePicker associated with the matched element. * * @type Array * @name dpGetSelected * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('.date-picker').datePicker(); * alert($('.date-picker').dpGetSelected()); * @desc Will alert an empty array (as nothing is selected yet) **/		dpGetSelected : function()		{			var c = _getController(this[0]);			if (c) {				return c.getSelected();			}			return null;		},/** * Selects or deselects a date on any matched element's date pickers. Deselcting is only useful on date pickers where selectMultiple==true. Selecting will only work if the passed date is within the startDate and endDate boundries for a given date picker. * * @param String d A string representing the date you want to select (formatted according to Date.format). * @param Boolean v Whether you want to select (true) or deselect (false) this date. Optional - default = true. * @param Boolean m Whether you want the date picker to open up on the month of this date when it is next opened. Optional - default = true. * @type jQuery * @name dpSetSelected * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('.date-picker').datePicker(); * $('.date-picker').dpSetSelected('01/01/2010'); * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010. **/		dpSetSelected : function(d, v, m)		{			if (v == undefined) v=true;			if (m == undefined) m=true;			return _w.call(this, 'setSelected', Date.fromString(d), v, m);		},/** * Sets the month that will be displayed when the date picker is next opened. If the passed month is before startDate then the month containing startDate will be displayed instead. If the passed month is after endDate then the month containing the endDate will be displayed instead. * * @param Number m The month you want the date picker to display. Optional - defaults to the currently displayed month. * @param Number y The year you want the date picker to display. Optional - defaults to the currently displayed year. * @type jQuery * @name dpSetDisplayedMonth * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('.date-picker').datePicker(); * $('.date-picker').dpSetDisplayedMonth(10, 2008); * @desc Creates a date picker associated with all elements with a class of "date-picker" then sets the selected date on these date pickers to the first Janurary 2010. When the date picker is next opened it will display Janurary 2010. **/		dpSetDisplayedMonth : function(m, y)		{			return _w.call(this, 'setDisplayedMonth', Number(m), Number(y));		},/** * Displays the date picker associated with the matched elements. Since only one date picker can be displayed at once then the date picker associated with the last matched element will be the one that is displayed. * * @param HTMLElement e An element that you want the date picker to pop up relative in position to. Optional - default behaviour is to pop up next to the element associated with this date picker. * @type jQuery * @name dpDisplay * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('#date-picker').datePicker(); * $('#date-picker').dpDisplay(); * @desc Creates a date picker associated with the element with an id of date-picker and then causes it to pop up. **/		dpDisplay : function(e)		{			return _w.call(this, 'display', e);		},/** * Sets a function or array of functions that is called when each TD of the date picker popup is rendered to the page * * @param (Function|Array) a A function or an array of functions that are called when each td is rendered. Each function will receive four arguments; a jquery object wrapping the created TD, a Date object containing the date this TD represents, a number giving the currently rendered month and a number giving the currently rendered year. * @type jQuery * @name dpSetRenderCallback * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('#date-picker').datePicker(); * $('#date-picker').dpSetRenderCallback(function($td, thisDate, month, year) * { * 	// do stuff as each td is rendered dependant on the date in the td and the displayed month and year * }); * @desc Creates a date picker associated with the element with an id of date-picker and then creates a function which is called as each td is rendered when this date picker is displayed. **/		dpSetRenderCallback : function(a)		{			return _w.call(this, 'setRenderCallback', a);		},/** * Sets the position that the datePicker will pop up (relative to it's associated element) * * @param Number v The vertical alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_TOP and $.dpConst.POS_BOTTOM * @param Number h The horizontal alignment of the created date picker to it's associated element. Possible values are $.dpConst.POS_LEFT and $.dpConst.POS_RIGHT * @type jQuery * @name dpSetPosition * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('#date-picker').datePicker(); * $('#date-picker').dpSetPosition($.dpConst.POS_BOTTOM, $.dpConst.POS_RIGHT); * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be bottom and right aligned to the #date-picker element. **/		dpSetPosition : function(v, h)		{			return _w.call(this, 'setPosition', v, h);		},/** * Sets the offset that the popped up date picker will have from it's default position relative to it's associated element (as set by dpSetPosition) * * @param Number v The vertical offset of the created date picker. * @param Number h The horizontal offset of the created date picker. * @type jQuery * @name dpSetOffset * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('#date-picker').datePicker(); * $('#date-picker').dpSetOffset(-20, 200); * @desc Creates a date picker associated with the element with an id of date-picker and makes it so that when this date picker pops up it will be 20 pixels above and 200 pixels to the right of it's default position. **/		dpSetOffset : function(v, h)		{			return _w.call(this, 'setOffset', v, h);		},/** * Closes the open date picker associated with this element. * * @type jQuery * @name dpClose * @cat plugins/datePicker * @author Kelvin Luck (http://www.kelvinluck.com/) * * @example $('.date-pick') *		.datePicker() *		.bind( *			'focus', *			function() *			{ *				$(this).dpDisplay(); *			} *		).bind( *			'blur', *			function() *			{ *				$(this).dpClose(); *			} *		); * @desc Creates a date picker and makes it appear when the relevant element is focused and disappear when it is blurred. **/		dpClose : function()		{			return _w.call(this, '_closeCalendar', false, this[0]);		},		// private function called on unload to clean up any expandos etc and prevent memory links...		_dpDestroy : function()		{			// TODO - implement this?		}	});		// private internal function to cut down on the amount of code needed where we forward	// dp* methods on the jQuery object on to the relevant DatePicker controllers...	var _w = function(f, a1, a2, a3)	{		return this.each(			function()			{				var c = _getController(this);				if (c) {					c[f](a1, a2, a3);				}			}		);	};		function DatePicker(ele)	{		this.ele = ele;				// initial values...		this.displayedMonth		=	null;		this.displayedYear		=	null;		this.startDate			=	null;		this.endDate			=	null;		this.showYearNavigation	=	null;		this.closeOnSelect		=	null;		this.displayClose		=	null;		this.selectMultiple		=	null;		this.verticalPosition	=	null;		this.horizontalPosition	=	null;		this.verticalOffset		=	null;		this.horizontalOffset	=	null;		this.button				=	null;		this.renderCallback		=	[];		this.selectedDates		=	{};		this.inline				=	null;		this.context			=	'#dp-popup';	};	$.extend(		DatePicker.prototype,		{				init : function(s)			{				this.setStartDate(s.startDate);				this.setEndDate(s.endDate);				this.setDisplayedMonth(Number(s.month), Number(s.year));				this.setRenderCallback(s.renderCallback);				this.showYearNavigation = s.showYearNavigation;				this.closeOnSelect = s.closeOnSelect;				this.displayClose = s.displayClose;				this.selectMultiple = s.selectMultiple;				this.verticalPosition = s.verticalPosition;				this.horizontalPosition = s.horizontalPosition;				this.hoverClass = s.hoverClass;				this.setOffset(s.verticalOffset, s.horizontalOffset);				this.inline = s.inline;				if (this.inline) {					this.context = this.ele;					this.display();				}			},			setStartDate : function(d)			{				if (d) {					this.startDate = Date.fromString(d);				}				if (!this.startDate) {					this.startDate = (new Date()).zeroTime();				}				this.setDisplayedMonth(this.displayedMonth, this.displayedYear);			},			setEndDate : function(d)			{				if (d) {					this.endDate = Date.fromString(d);				}				if (!this.endDate) {					this.endDate = (new Date('12/31/2999')); // using the JS Date.parse function which expects mm/dd/yyyy				}				if (this.endDate.getTime() < this.startDate.getTime()) {					this.endDate = this.startDate;				}				this.setDisplayedMonth(this.displayedMonth, this.displayedYear);			},			setPosition : function(v, h)			{				this.verticalPosition = v;				this.horizontalPosition = h;			},			setOffset : function(v, h)			{				this.verticalOffset = parseInt(v) || 0;				this.horizontalOffset = parseInt(h) || 0;			},			setDisabled : function(s)			{				$e = $(this.ele);				$e[s ? 'addClass' : 'removeClass']('dp-disabled');				if (this.button) {					$but = $(this.button);					$but[s ? 'addClass' : 'removeClass']('dp-disabled');					$but.attr('title', s ? '' : $.dpText.TEXT_CHOOSE_DATE);				}				if ($e.is(':text')) {					$e.attr('disabled', s ? 'disabled' : '');				}			},			setDisplayedMonth : function(m, y)			{				if (this.startDate == undefined || this.endDate == undefined) {					return;				}				var s = new Date(this.startDate.getTime());				s.setDate(1);				var e = new Date(this.endDate.getTime());				e.setDate(1);								var t;				if ((!m && !y) || (isNaN(m) && isNaN(y))) {					// no month or year passed - default to current month					t = new Date().zeroTime();					t.setDate(1);				} else if (isNaN(m)) {					// just year passed in - presume we want the displayedMonth					t = new Date(y, this.displayedMonth, 1);				} else if (isNaN(y)) {					// just month passed in - presume we want the displayedYear					t = new Date(this.displayedYear, m, 1);				} else {					// year and month passed in - that's the date we want!					t = new Date(y, m, 1)				}								// check if the desired date is within the range of our defined startDate and endDate				if (t.getTime() < s.getTime()) {					t = s;				} else if (t.getTime() > e.getTime()) {					t = e;				}				this.displayedMonth = t.getMonth();				this.displayedYear = t.getFullYear();			},			setSelected : function(d, v, moveToMonth)			{				if (this.selectMultiple == false) {					this.selectedDates = {};					$('td.selected', this.context).removeClass('selected');				}				if (moveToMonth) {					this.setDisplayedMonth(d.getMonth(), d.getFullYear());				}				this.selectedDates[d.toString()] = v;			},			isSelected : function(d)			{				return this.selectedDates[d.toString()];			},			getSelected : function()			{				var r = [];				for(s in this.selectedDates) {					if (this.selectedDates[s] == true) {						r.push(Date.parse(s));					}				}				return r;			},			display : function(eleAlignTo)			{				if ($(this.ele).is('.dp-disabled')) return;								eleAlignTo = eleAlignTo || this.ele;				var c = this;				var $ele = $(eleAlignTo);				var eleOffset = $ele.offset();								var $createIn;				var attrs;				var attrsCalendarHolder;				var cssRules;								if (c.inline) {					$createIn = $(this.ele);					attrs = {						'id'		:	'calendar-' + this.ele._dpId,						'className'	:	'dp-popup dp-popup-inline'					};					cssRules = {					};				} else {					$createIn = $('body');					attrs = {						'id'		:	'dp-popup',						'className'	:	'dp-popup'					};					cssRules = {						'top'	:	eleOffset.top + c.verticalOffset,						'left'	:	eleOffset.left + c.horizontalOffset					};										var _checkMouse = function(e)					{						var el = e.target;						var cal = $('#dp-popup')[0];												while (true){							if (el == cal) {								return true;							} else if (el == document) {								c._closeCalendar();								return false;							} else {								el = $(el).parent()[0];							}						}					};					this._checkMouse = _checkMouse;									this._closeCalendar(true);				}												$createIn					.append(						$('<div></div>')							.attr(attrs)							.css(cssRules)							.append(								$('<h2></h2>'),								$('<div class="dp-nav-prev"></div>')									.append(										$('<a class="dp-nav-prev-year" href="#" title="' + $.dpText.TEXT_PREV_YEAR + '"><<</a>')											.bind(												'click',												function()												{													return c._displayNewMonth.call(c, this, 0, -1);												}											),										$('<a class="dp-nav-prev-month" href="#" title="' + $.dpText.TEXT_PREV_MONTH + '"><</a>')											.bind(												'click',												function()												{													return c._displayNewMonth.call(c, this, -1, 0);												}											)									),								$('<div class="dp-nav-next"></div>')									.append(										$('<a class="dp-nav-next-year" href="#" title="' + $.dpText.TEXT_NEXT_YEAR + '">>></a>')											.bind(												'click',												function()												{													return c._displayNewMonth.call(c, this, 0, 1);												}											),										$('<a class="dp-nav-next-month" href="#" title="' + $.dpText.TEXT_NEXT_MONTH + '">></a>')											.bind(												'click',												function()												{													return c._displayNewMonth.call(c, this, 1, 0);												}											)									),								$('<div></div>')									.attr('className', 'dp-calendar')							)							.bgIframe()						);									var $pop = this.inline ? $('.dp-popup', this.context) : $('#dp-popup');								if (this.showYearNavigation == false) {					$('.dp-nav-prev-year, .dp-nav-next-year', c.context).css('display', 'none');				}				if (this.displayClose) {					$pop.append(						$('<a href="#" id="dp-close">' + $.dpText.TEXT_CLOSE + '</a>')							.bind(								'click',								function()								{									c._closeCalendar();									return false;								}							)					);				}				c._renderCalendar();								$(this.ele).trigger('dpDisplayed', $pop);								if (!c.inline) {					if (this.verticalPosition == $.dpConst.POS_BOTTOM) {						$pop.css('top', eleOffset.top + $ele.height() - $pop.height() + c.verticalOffset);					}					if (this.horizontalPosition == $.dpConst.POS_RIGHT) {						$pop.css('left', eleOffset.left + $ele.width() - $pop.width() + c.horizontalOffset);					}					$(document).bind('mousedown', this._checkMouse);				}			},			setRenderCallback : function(a)			{				if (a && typeof(a) == 'function') {					a = [a];				}				this.renderCallback = this.renderCallback.concat(a);			},			cellRender : function ($td, thisDate, month, year) {				var c = this.dpController;				var d = new Date(thisDate.getTime());								// add our click handlers to deal with it when the days are clicked...								$td.bind(					'click',					function()					{						var $this = $(this);						if (!$this.is('.disabled')) {							c.setSelected(d, !$this.is('.selected') || !c.selectMultiple);							var s = c.isSelected(d);							$(c.ele).trigger('dateSelected', [d, $td, s]);							$(c.ele).trigger('change');							if (c.closeOnSelect) {								c._closeCalendar();							} else {								$this[s ? 'addClass' : 'removeClass']('selected');							}						}					}				);								if (c.isSelected(d)) {					$td.addClass('selected');				}								// call any extra renderCallbacks that were passed in				for (var i=0; i<c.renderCallback.length; i++) {					c.renderCallback[i].apply(this, arguments);				}											},			// ele is the clicked button - only proceed if it doesn't have the class disabled...			// m and y are -1, 0 or 1 depending which direction we want to go in...			_displayNewMonth : function(ele, m, y) 			{				if (!$(ele).is('.disabled')) {					this.setDisplayedMonth(this.displayedMonth + m, this.displayedYear + y);					this._clearCalendar();					this._renderCalendar();					$(this.ele).trigger('dpMonthChanged', [this.displayedMonth, this.displayedYear]);				}				ele.blur();				return false;			},			_renderCalendar : function()			{				// set the title...				$('h2', this.context).html(Date.monthNames[this.displayedMonth] + ' ' + this.displayedYear);								// render the calendar...				$('.dp-calendar', this.context).renderCalendar(					{						month			: this.displayedMonth,						year			: this.displayedYear,						renderCallback	: this.cellRender,						dpController	: this,						hoverClass		: this.hoverClass					}				);								// update the status of the control buttons and disable dates before startDate or after endDate...				// TODO: When should the year buttons be disabled? When you can't go forward a whole year from where you are or is that annoying?				if (this.displayedYear == this.startDate.getFullYear() && this.displayedMonth == this.startDate.getMonth()) {					$('.dp-nav-prev-year', this.context).addClass('disabled');					$('.dp-nav-prev-month', this.context).addClass('disabled');					$('.dp-calendar td.other-month', this.context).each(						function()						{							var $this = $(this);							if (Number($this.text()) > 20) {								$this.addClass('disabled');							}						}					);					var d = this.startDate.getDate();					$('.dp-calendar td.current-month', this.context).each(						function()						{							var $this = $(this);							if (Number($this.text()) < d) {								$this.addClass('disabled');							}						}					);				} else {					$('.dp-nav-prev-year', this.context).removeClass('disabled');					$('.dp-nav-prev-month', this.context).removeClass('disabled');					var d = this.startDate.getDate();					if (d > 20) {						// check if the startDate is last month as we might need to add some disabled classes...						var sd = new Date(this.startDate.getTime());						sd.addMonths(1);						if (this.displayedYear == sd.getFullYear() && this.displayedMonth == sd.getMonth()) {							$('dp-calendar td.other-month', this.context).each(								function()								{									var $this = $(this);									if (Number($this.text()) < d) {										$this.addClass('disabled');									}								}							);						}					}				}				if (this.displayedYear == this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) {					$('.dp-nav-next-year', this.context).addClass('disabled');					$('.dp-nav-next-month', this.context).addClass('disabled');					$('.dp-calendar td.other-month', this.context).each(						function()						{							var $this = $(this);							if (Number($this.text()) < 14) {								$this.addClass('disabled');							}						}					);					var d = this.endDate.getDate();					$('.dp-calendar td.current-month', this.context).each(						function()						{							var $this = $(this);							if (Number($this.text()) > d) {								$this.addClass('disabled');							}						}					);				} else {					$('.dp-nav-next-year', this.context).removeClass('disabled');					$('.dp-nav-next-month', this.context).removeClass('disabled');					var d = this.endDate.getDate();					if (d < 13) {						// check if the endDate is next month as we might need to add some disabled classes...						var ed = new Date(this.endDate.getTime());						ed.addMonths(-1);						if (this.displayedYear == ed.getFullYear() && this.displayedMonth == ed.getMonth()) {							$('.dp-calendar td.other-month', this.context).each(								function()								{									var $this = $(this);									if (Number($this.text()) > d) {										$this.addClass('disabled');									}								}							);						}					}				}			},			_closeCalendar : function(programatic, ele)			{				if (!ele || ele == this.ele)				{					$(document).unbind('mousedown', this._checkMouse);					this._clearCalendar();					$('#dp-popup a').unbind();					$('#dp-popup').empty().remove();					if (!programatic) {						$(this.ele).trigger('dpClosed', [this.getSelected()]);					}				}			},			// empties the current dp-calendar div and makes sure that all events are unbound			// and expandos removed to avoid memory leaks...			_clearCalendar : function()			{				// TODO.				$('.dp-calendar td', this.context).unbind();				$('.dp-calendar', this.context).empty();			}		}	);		// static constants	$.dpConst = {		SHOW_HEADER_NONE	:	0,		SHOW_HEADER_SHORT	:	1,		SHOW_HEADER_LONG	:	2,		POS_TOP				:	0,		POS_BOTTOM			:	1,		POS_LEFT			:	0,		POS_RIGHT			:	1	};	// localisable text	$.dpText = {		TEXT_PREV_YEAR		:	'Año ant.',		TEXT_PREV_MONTH		:	'Mes ant.',		TEXT_NEXT_YEAR		:	'Sig año',		TEXT_NEXT_MONTH		:	'Sig. mes',		TEXT_CLOSE			:	'Cerrar',		TEXT_CHOOSE_DATE	:	'Elige una fecha'	};	// version	$.dpVersion = '$Id: jquery.datePicker.js 3739 2007-10-25 13:55:30Z kelvin.luck $';	function _getController(ele)	{		if (ele._dpId) return $.event._dpCache[ele._dpId];		return false;	};		// make it so that no error is thrown if bgIframe plugin isn't included (allows you to use conditional	// comments to only include bgIframe where it is needed in IE without breaking this plugin).	if ($.fn.bgIframe == undefined) {		$.fn.bgIframe = function() {return this; };	};	// clean-up	$(window)		.bind('unload', function() {			var els = $.event._dpCache || [];			for (var i in els) {				$(els[i].ele)._dpDestroy();			}		});/*------------------------VALIDACIONES     JQUERY--------------------------------*/ $.extend($.fn, {	// http://docs.jquery.com/Plugins/Validation/validate	validate: function( options ) {				// if nothing is selected, return nothing; can't chain anyway		if (!this.length) {			options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );			return;		}				// check if a validator for this form was already created		var validator = $.data(this[0], 'validator');		if ( validator ) {			return validator;		}				validator = new $.validator( options, this[0] );		$.data(this[0], 'validator', validator); 				if ( validator.settings.onsubmit ) {					// allow suppresing validation by adding a cancel class to the submit button			this.find("input, button").filter(".cancel").click(function() {				validator.cancelSubmit = true;			});					// validate the form on submit			this.submit( function( event ) {				if ( validator.settings.debug )					// prevent form submit to be able to see console output					event.preventDefault();									function handle() {					if ( validator.settings.submitHandler ) {						validator.settings.submitHandler.call( validator, validator.currentForm );						return false;					}					return true;				}									// prevent submit for invalid forms or custom submit handlers				if ( validator.cancelSubmit ) {					validator.cancelSubmit = false;					return handle();				}				if ( validator.form() ) {					if ( validator.pendingRequest ) {						validator.formSubmitted = true;						return false;					}					return handle();				} else {					validator.focusInvalid();					return false;				}			});		}				return validator;	},	// http://docs.jquery.com/Plugins/Validation/valid	valid: function() {        if ( $(this[0]).is('form')) {            return this.validate().form();        } else {            var valid = false;            var validator = $(this[0].form).validate();            this.each(function() {				valid |= validator.element(this);            });            return valid;        }    },	// attributes: space seperated list of attributes to retrieve and remove	removeAttrs: function(attributes) {		var result = {},			$element = this;		$.each(attributes.split(/\s/), function() {			result[this] = $element.attr(this);			$element.removeAttr(this);		});		return result;	},	// http://docs.jquery.com/Plugins/Validation/rules	rules: function(command, argument) {		var element = this[0];				if (command) {			var staticRules = $.data(element.form, 'validator').settings.rules;			var existingRules = $.validator.staticRules(element);			switch(command) {			case "add":				$.extend(existingRules, $.validator.normalizeRule(argument));				staticRules[element.id] = existingRules;				break;			case "remove":				if (!argument) {					delete staticRules[element.id];					return existingRules;				}				var filtered = {};				$.each(argument.split(/\s/), function(index, method) {					filtered[method] = existingRules[method];					delete existingRules[method];				});				return filtered;			}		}				var data = $.validator.normalizeRules(		$.extend(			{},			$.validator.metadataRules(element),			$.validator.classRules(element),			$.validator.attributeRules(element),			$.validator.staticRules(element)		), element);				// make sure required is at front		if (data.required) {			var param = data.required;			delete data.required;			data = $.extend({required: param}, data);		}				return data;	},	// destructive add	push: function( t ) {		return this.setArray( this.add(t).get() );	}});// Custom selectors$.extend($.expr[":"], {	// http://docs.jquery.com/Plugins/Validation/blank	blank: function(a) {return !$.trim(a.value);},	// http://docs.jquery.com/Plugins/Validation/filled	filled: function(a) {return !!$.trim(a.value);},	// http://docs.jquery.com/Plugins/Validation/unchecked	unchecked: function(a) {return !a.checked;}});$.format = function(source, params) {	if ( arguments.length == 1 ) 		return function() {			var args = $.makeArray(arguments);			args.unshift(source);			return $.format.apply( this, args );		};	if ( arguments.length > 2 && params.constructor != Array  ) {		params = $.makeArray(arguments).slice(1);	}	if ( params.constructor != Array ) {		params = [ params ];	}	$.each(params, function(i, n) {		source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);	});	return source;};// constructor for validator$.validator = function( options, form ) {	this.settings = $.extend( {}, $.validator.defaults, options );	this.currentForm = form;	this.init();};$.extend($.validator, {	defaults: {		messages: {},		groups: {},		rules: {},		errorClass: "error",		errorElement: "label",		focusInvalid: true,		errorContainer: $( [] ),		errorLabelContainer: $( [] ),		onsubmit: true,		ignore: [],		onfocusin: function(element) {			this.lastActive = element;							// hide error label and remove error class on focus if enabled			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {				this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass );				this.errorsFor(element).hide();			}		},		onfocusout: function(element) {			if ( !this.checkable(element) && (element.id in this.submitted || !this.optional(element)) ) {				this.element(element);			}		},		onkeyup: function(element) {			if ( element.id in this.submitted || element == this.lastElement ) {				this.element(element);			}		},		onclick: function(element) {			if ( element.id in this.submitted )				this.element(element);		},		highlight: function( element, errorClass ) {			$( element ).addClass( errorClass );		},		unhighlight: function( element, errorClass ) {			$( element ).removeClass( errorClass );		}	},	// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults	setDefaults: function(settings) {		$.extend( $.validator.defaults, settings );	},	messages: {		minusculas : "* Este campo debe contener minusculas,numero y/o '_'",		required: "* Campo requerido",		remote:  $.format("* {0} no esta disponible."),		email: "* Email no valido",		url: "* URL no valida",		date: "Please enter a valid date.",		dateISO: "Please enter a valid date (ISO).",		dateDE: "Bitte geben Sie ein gültiges Datum ein.",		number: "Please enter a valid number.",		numberDE: "Bitte geben Sie eine Nummer ein.",		digits: "Please enter only digits",		creditcard: "Please enter a valid credit card.",		equalTo: "* Escribe nuevamente el valor anterior correctamente.",		NotEqualTo: "* Los Valores no deben ser iguales.",		accept: "Please enter a value with a valid extension.",		maxlength: $.format("Please enter no more than {0} characters."),		minlength: $.format("*Debe contener al menos {0} caracteres."),		rangelength: $.format("Please enter a value between {0} and {1} characters long."),		range: $.format("Please enter a value between {0} and {1}."),		max: $.format("Please enter a value less than or equal to {0}."),		min: $.format("Please enter a value greater than or equal to {0}.")	},		autoCreateRanges: false,		prototype: {				init: function() {			this.labelContainer = $(this.settings.errorLabelContainer);			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );			this.submitted = {};			this.valueCache = {};			this.pendingRequest = 0;			this.pending = {};			this.invalid = {};			this.reset();						var groups = (this.groups = {});			$.each(this.settings.groups, function(key, value) {				$.each(value.split(/\s/), function(index, name) {					groups[name] = key;				});			});			var rules = this.settings.rules;			$.each(rules, function(key, value) {				rules[key] = $.validator.normalizeRule(value);			});						function delegate(event) {				var validator = $.data(this[0].form, "validator");				validator.settings["on" + event.type] && validator.settings["on" + event.type].call(validator, this[0] );			}			$(this.currentForm)				.delegate("focusin focusout keyup", ":text, :password, :file, select, textarea", delegate)				.delegate("click", ":radio, :checkbox", delegate);		},		// http://docs.jquery.com/Plugins/Validation/Validator/form		form: function() {			this.checkForm();			$.extend(this.submitted, this.errorMap);			this.invalid = $.extend({}, this.errorMap);			if (!this.valid())				$(this.currentForm).triggerHandler("invalid-form.validate", [this]);			this.showErrors();			return this.valid();		},				checkForm: function() {			this.prepareForm();			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {				this.check( elements[i] );			}			return this.valid(); 		},				// http://docs.jquery.com/Plugins/Validation/Validator/element		element: function( element ) {			element = this.clean( element );			this.lastElement = element;			this.prepareElement( element );			this.currentElements = $(element);			var result = this.check( element );			if ( result ) {				delete this.invalid[element.id];			} else {				this.invalid[element.id] = true;			}			if ( !this.numberOfInvalids() ) {				// Hide error containers on last error				this.toHide.push( this.containers );			}			this.showErrors();			return result;		},		// http://docs.jquery.com/Plugins/Validation/Validator/showErrors		showErrors: function(errors) {			if(errors) {				// add items to error list and map				$.extend( this.errorMap, errors );				this.errorList = [];				for ( var id in errors ) {					this.errorList.push({						message: errors[id],						element: this.findById(id)[0]					});				}				// remove items from success list				this.successList = $.grep( this.successList, function(element) {					return !(element.id in errors);				});			}			this.settings.showErrors				? this.settings.showErrors.call( this, this.errorMap, this.errorList )				: this.defaultShowErrors();		},				// http://docs.jquery.com/Plugins/Validation/Validator/resetForm		resetForm: function() {			if ( $.fn.resetForm )				$( this.currentForm ).resetForm();			this.submitted = {};			this.prepareForm();			this.hideErrors();			this.elements().removeClass( this.settings.errorClass );		},				numberOfInvalids: function() {			return this.objectLength(this.invalid);		},				objectLength: function( obj ) {			var count = 0;			for ( var i in obj )				count++;			return count;		},				hideErrors: function() {			this.addWrapper( this.toHide ).hide();		},				valid: function() {			return this.size() == 0;		},				size: function() {			return this.errorList.length;		},				focusInvalid: function() {			if( this.settings.focusInvalid ) {				try {					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || []).filter(":visible").focus();				} catch(e) { /* ignore IE throwing errors when focusing hidden elements */ }			}		},				findLastActive: function() {			var lastActive = this.lastActive;			return lastActive && $.grep(this.errorList, function(n) {				return n.element.id == lastActive.id;			}).length == 1 && lastActive;		},				elements: function() {			var validator = this,				rulesCache = {};						// select all valid inputs inside the form (no submit or reset buttons)			// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved			return $([]).add(this.currentForm.elements)			.filter(":input")			.not(":submit, :reset, :image, [disabled]")			.not( this.settings.ignore )			.filter(function() {				!this.id && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);							// select only the first element for each name, and only those with rules specified				if ( this.id in rulesCache || !validator.objectLength($(this).rules()) )					return false;								rulesCache[this.id] = true;				return true;			});		},				clean: function( selector ) {			return $( selector )[0];		},				errors: function() {			return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );		},				reset: function() {			this.successList = [];			this.errorList = [];			this.errorMap = {};			this.toShow = $([]);			this.toHide = $([]);			this.formSubmitted = false;			this.currentElements = $([]);		},				prepareForm: function() {			this.reset();			this.toHide = this.errors().push( this.containers );		},				prepareElement: function( element ) {			this.reset();			this.toHide = this.errorsFor(element);		},			check: function( element ) {			element = this.clean( element );						// if radio/checkbox, validate first element in group instead			if (this.checkable(element)) {				element = this.findById( element.id )[0];			}						var rules = $(element).rules();			var dependencyMismatch = false;			for( method in rules ) {				var rule = { method: method, parameters: rules[method] };				try {					var result = $.validator.methods[method].call( this, $.trim(element.value), element, rule.parameters );										// if a method indicates that the field is optional and therefore valid,					// don't mark it as valid when there are no other rules					if ( result == "dependency-mismatch" ) {						dependencyMismatch = true;						continue;					}					dependencyMismatch = false;										if ( result == "pending" ) {						this.toHide = this.toHide.not( this.errorsFor(element) );						return;					}										if( !result ) {						this.formatAndAdd( element, rule );						return false;					}				} catch(e) {					this.settings.debug && window.console && console.log("exception occured when checking element " + element.id						 + ", check the '" + rule.method + "' method");					throw e;				}			}			if (dependencyMismatch)				return;			if ( this.objectLength(rules) )				this.successList.push(element);			return true;		},				// return the custom message for the given element and validation method		// specified in the element's "messages" metadata		customMetaMessage: function(element, method) {			if (!$.metadata)				return;						var meta = this.settings.meta				? $(element).metadata()[this.settings.meta]				: $(element).metadata();						return meta.messages && meta.messages[method];		},				// return the custom message for the given element name and validation method		customMessage: function( name, method ) {			var m = this.settings.messages[name];			return m && (m.constructor == String				? m				: m[method]);		},				// return the first defined argument, allowing empty strings		findDefined: function() {			for(var i = 0; i < arguments.length; i++) {				if (arguments[i] !== undefined)					return arguments[i];			}			return undefined;		},				defaultMessage: function( element, method) {			return this.findDefined(				this.customMessage( element.id, method ),				this.customMetaMessage( element, method ),				// title is never undefined, so handle empty string as undefined				element.title || undefined,				$.validator.messages[method],				"<strong>Warning: No message defined for " + element.id + "</strong>"			);		},				formatAndAdd: function( element, rule ) {			var message = this.defaultMessage( element, rule.method );			if ( typeof message == "function" ) 				message = message.call(this, rule.parameters, element);			this.errorList.push({				message: message,				element: element			});			this.errorMap[element.id] = message;			this.submitted[element.id] = message;		},				addWrapper: function(toToggle) {			if ( this.settings.wrapper )				toToggle.push( toToggle.parents( this.settings.wrapper ) );			return toToggle;		},				defaultShowErrors: function() {			for ( var i = 0; this.errorList[i]; i++ ) {				var error = this.errorList[i];				this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass );				this.showLabel( error.element, error.message );			}			if( this.errorList.length ) {				this.toShow.push( this.containers );			}			if (this.settings.success) {				for ( var i = 0; this.successList[i]; i++ ) {					this.showLabel( this.successList[i] );				}			}			if (this.settings.unhighlight) {				for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass );				}			}			this.toHide = this.toHide.not( this.toShow );			this.hideErrors();			this.addWrapper( this.toShow ).show();		},				validElements: function() {			return this.currentElements.not(this.invalidElements());		},				invalidElements: function() {			return $(this.errorList).map(function() {				return this.element;			});		},				showLabel: function(element, message) {			var label = this.errorsFor( element );			if ( label.length ) {				// refresh error/success class				label.removeClass().addClass( this.settings.errorClass );							// check if we have a generated label, replace the message then				label.attr("generated") && label.html(message);			} else {				// create label				label = $("<" + this.settings.errorElement + "/>")					.attr({"for":  this.idOrName(element), generated: true})					.addClass(this.settings.errorClass)					.html(message || "");				if ( this.settings.wrapper ) {					// make sure the element is visible, even in IE					// actually showing the wrapped element is handled elsewhere					label = label.hide().show().wrap("<" + this.settings.wrapper + ">").parent();				}				if ( !this.labelContainer.append(label).length )					this.settings.errorPlacement						? this.settings.errorPlacement(label, $(element) )						: label.insertAfter(element);			}			if ( !message && this.settings.success ) {				label.text("");				typeof this.settings.success == "string"					? label.addClass( this.settings.success )					: this.settings.success( label );			}			this.toShow.push(label);		},				errorsFor: function(element) {			return this.errors().filter("[@for='" + this.idOrName(element) + "']");		},				idOrName: function(element) {						return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);		},		checkable: function( element ) {			return /radio|checkbox/i.test(element.type);		},				findById: function( id ) {			// select by name and filter by form for performance over form.find("[name=...]")			var form = this.currentForm;			return $(document.getElementById(id)).map(function(index, element) {				return element.form == form && element.id == id && element  || null;			});		},				getLength: function(value, element) {			switch( element.nodeName.toLowerCase() ) {			case 'select':				return $("option:selected", element).length;			case 'input':				if( this.checkable( element) )					return this.findById(element.id).filter(':checked').length;			}			return value.length;		},			depend: function(param, element) {			return this.dependTypes[typeof param]				? this.dependTypes[typeof param](param, element)				: true;		},			dependTypes: {			"boolean": function(param, element) {				return param;			},			"string": function(param, element) {				return !!$(param, element.form).length;			},			"function": function(param, element) {				return param(element);			}		},				optional: function(element) {			return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";		},				startRequest: function(element) {			if (!this.pending[element.id]) {				this.pendingRequest++;				this.pending[element.id] = true;			}		},				stopRequest: function(element, valid) {			this.pendingRequest--;			// sometimes synchronization fails, make pendingRequest is never < 0			if (this.pendingRequest < 0)				this.pendingRequest = 0;			delete this.pending[element.id];			if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {				$(this.currentForm).submit();			}		},				previousValue: function(element) {			return $.data(element, "previousValue") || $.data(element, "previousValue", previous = {				old: null,				valid: true,				message: this.defaultMessage( element, "remote" )			});		}			},		classRuleSettings: {		minusculas:{minusculas: true},		required: {required: true},		email: {email: true},		url: {url: true},		date: {date: true},		dateISO: {dateISO: true},		dateDE: {dateDE: true},		number: {number: true},		numberDE: {numberDE: true},		digits: {digits: true},		creditcard: {creditcard: true}	},		addClassRules: function(className, rules) {		className.constructor == String ?			this.classRuleSettings[className] = rules :			$.extend(this.classRuleSettings, className);	},		classRules: function(element) {		var rules = {};		var classes = $(element).attr('class');		classes && $.each(classes.split(' '), function() {			if (this in $.validator.classRuleSettings) {				$.extend(rules, $.validator.classRuleSettings[this]);			}		});		return rules;	},		attributeRules: function(element) {		var rules = {};		var $element = $(element);				for (method in $.validator.methods) {			var value = $element.attr(method);			if (value) {				rules[method] = value;			}		}				// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs		if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {			delete rules.maxlength;		}				return rules;	},		metadataRules: function(element) {		if (!$.metadata) return {};				var meta = $.data(element.form, 'validator').settings.meta;		return meta ?			$(element).metadata()[meta] :			$(element).metadata();	},		staticRules: function(element) {		var rules = {};		var validator = $.data(element.form, 'validator');		if (validator.settings.rules) {			rules = $.validator.normalizeRule(validator.settings.rules[element.id]) || {};		}		return rules;	},		normalizeRules: function(rules, element) {		// handle dependency check		$.each(rules, function(prop, val) {			// ignore rule when param is explicitly false, eg. required:false			if (val === false) {				delete rules[prop];				return;			}			if (val.param || val.depends) {				var keepRule = true;				switch (typeof val.depends) {					case "string":						keepRule = !!$(val.depends, element.form).length;						break;					case "function":						keepRule = val.depends.call(element, element);						break;				}				if (keepRule) {					rules[prop] = val.param !== undefined ? val.param : true;				} else {					delete rules[prop];				}			}		});				// evaluate parameters		$.each(rules, function(rule, parameter) {			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;		});				// clean number parameters		$.each(['minlength', 'maxlength', 'min', 'max'], function() {			if (rules[this]) {				rules[this] = Number(rules[this]);			}		});		$.each(['rangelength', 'range'], function() {			if (rules[this]) {				rules[this] = [Number(rules[this][0]), Number(rules[this][1])];			}		});				if ($.validator.autoCreateRanges) {			// auto-create ranges			if (rules.min && rules.max) {				rules.range = [rules.min, rules.max];				delete rules.min;				delete rules.max;			}			if (rules.minlength && rules.maxlength) {				rules.rangelength = [rules.minlength, rules.maxlength];				delete rules.minlength;				delete rules.maxlength;			}		}				// To support custom messages in metadata ignore rule methods titled "messages"		if (rules.messages) {			delete rules.messages		}				return rules;	},		// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}	normalizeRule: function(data) {		if( typeof data == "string" ) {			var transformed = {};			$.each(data.split(/\s/), function() {				transformed[this] = true;			});			data = transformed;		}		return data;	},		// http://docs.jquery.com/Plugins/Validation/Validator/addMethod	addMethod: function(name, method, message) {		$.validator.methods[name] = method;		$.validator.messages[name] = message;		if (method.length < 3) {			$.validator.addClassRules(name, $.validator.normalizeRule(name));		}	},	methods: {		// http://docs.jquery.com/Plugins/Validation/Methods/required		required: function(value, element, param) {			// check if dependency is met			if ( !this.depend(param, element) )				return "dependency-mismatch";			switch( element.nodeName.toLowerCase() ) {			case 'select':				var options = $("option:selected", element);				return options.length > 0 && ( element.type == "select-multiple" || ($.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);			case 'input':				if ( this.checkable(element) )					return this.getLength(value, element) > 0;			default:				return value.length > 0;			}		},				// http://docs.jquery.com/Plugins/Validation/Methods/remote		remote: function(value, element, param) {			if ( this.optional(element) )				return "dependency-mismatch";						var previous = this.previousValue(element);						if (!this.settings.messages[element.id] )				this.settings.messages[element.id] = {};			this.settings.messages[element.id].remote = typeof previous.message == "function" ? previous.message(value) : previous.message;						if ( previous.old !== value ) {				previous.old = value;				var validator = this;				this.startRequest(element);				var data = {};				data[element.name] = value;				$.ajax({					url: param,					type: 'POST',					mode: "abort",					port: "validate" + element.id,					dataType: "json",					data: data,					success: function(response) {						if ( !response ) {							var errors = {};							errors[element.id] =  response || validator.defaultMessage( element, "remote" );							validator.showErrors(errors);						} else {							var submitted = validator.formSubmitted;							validator.prepareElement(element);							validator.formSubmitted = submitted;							validator.successList.push(element);							validator.showErrors();						}						previous.valid = response;						validator.stopRequest(element, response);					}				});				return "pending";			} else if( this.pending[element.id] ) {				return "pending";			}			return previous.valid;		},		// http://docs.jquery.com/Plugins/Validation/Methods/minlength		minlength: function(value, element, param) {			return this.optional(element) || this.getLength(value, element) >= param;		},				// http://docs.jquery.com/Plugins/Validation/Methods/maxlength		maxlength: function(value, element, param) {			return this.optional(element) || this.getLength(value, element) <= param;		},				// http://docs.jquery.com/Plugins/Validation/Methods/rangelength		rangelength: function(value, element, param) {			var length = this.getLength(value, element);			return this.optional(element) || ( length >= param[0] && length <= param[1] );		},				// http://docs.jquery.com/Plugins/Validation/Methods/min		min: function( value, element, param ) {			return this.optional(element) || value >= param;		},				// http://docs.jquery.com/Plugins/Validation/Methods/max		max: function( value, element, param ) {			return this.optional(element) || value <= param;		},				// http://docs.jquery.com/Plugins/Validation/Methods/range		range: function( value, element, param ) {			return this.optional(element) || ( value >= param[0] && value <= param[1] );		},				// http://docs.jquery.com/Plugins/Validation/Methods/email		email: function(value, element) {			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/			return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(element.value);		},		minusculas: function(value, element) {			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/			return this.optional(element) || /^[a-z0-9_]*$/.test(element.value);		},			// http://docs.jquery.com/Plugins/Validation/Methods/url		url: function(value, element) {			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/			return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(element.value);		},        		// http://docs.jquery.com/Plugins/Validation/Methods/date		date: function(value, element) {			return this.optional(element) || !/Invalid|NaN/.test(new Date(value));		},			// http://docs.jquery.com/Plugins/Validation/Methods/dateISO		dateISO: function(value, element) {			return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);		},			// http://docs.jquery.com/Plugins/Validation/Methods/dateDE		dateDE: function(value, element) {			return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);		},			// http://docs.jquery.com/Plugins/Validation/Methods/number		number: function(value, element) {			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);		},			// http://docs.jquery.com/Plugins/Validation/Methods/numberDE		numberDE: function(value, element) {			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);		},				// http://docs.jquery.com/Plugins/Validation/Methods/digits		digits: function(value, element) {			return this.optional(element) || /^\d+$/.test(value);		},				// http://docs.jquery.com/Plugins/Validation/Methods/creditcard		// based on http://en.wikipedia.org/wiki/Luhn		creditcard: function(value, element) {			if ( this.optional(element) )				return "dependency-mismatch";			// accept only digits and dashes			if (/[^0-9-]+/.test(value))				return false;			var nCheck = 0,				nDigit = 0,				bEven = false;			value = value.replace(/\D/g, "");			for (n = value.length - 1; n >= 0; n--) {				var cDigit = value.charAt(n);				var nDigit = parseInt(cDigit, 10);				if (bEven) {					if ((nDigit *= 2) > 9)						nDigit -= 9;				}				nCheck += nDigit;				bEven = !bEven;			}			return (nCheck % 10) == 0;		},				// http://docs.jquery.com/Plugins/Validation/Methods/accept		accept: function(value, element, param) {			param = typeof param == "string" ? param : "png|jpe?g|gif";			return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); 		},				// http://docs.jquery.com/Plugins/Validation/Methods/equalTo		equalTo: function(value, element, param) {			return value == $(param).val();		},		// http://docs.jquery.com/Plugins/Validation/Methods/equalTo		notEqualTo: function(value, element, param) {			return value != $(param).val();		}	}	});})(jQuery);// ajax mode: abort// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() ;(function($) {	var ajax = $.ajax;	var pendingRequests = {};	$.ajax = function(settings) {		// create settings for compatibility with ajaxSetup		settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));		var port = settings.port;		if (settings.mode == "abort") {			if ( pendingRequests[port] ) {				pendingRequests[port].abort();			}			return (pendingRequests[port] = ajax.apply(this, arguments));		}		return ajax.apply(this, arguments);	};})(jQuery);// provides cross-browser focusin and focusout events// IE has native support, in other browsers, use event caputuring (neither bubbles)// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target // provides triggerEvent(type: String, target: Element) to trigger delegated events;(function($) {	$.each({		focus: 'focusin',		blur: 'focusout'		}, function( original, fix ){		$.event.special[fix] = {			setup:function() {				if ( $.browser.msie ) return false;				this.addEventListener( original, $.event.special[fix].handler, true );			},			teardown:function() {				if ( $.browser.msie ) return false;				this.removeEventListener( original,				$.event.special[fix].handler, true );			},			handler: function(e) {				arguments[0] = $.event.fix(e);				arguments[0].type = fix;				return $.event.handle.apply(this, arguments);			}		};	});	$.extend($.fn, {		delegate: function(type, delegate, handler) {			return this.bind(type, function(event) {				var target = $(event.target);				if (target.is(delegate)) {					return handler.apply(target, arguments);				}			});		},		triggerEvent: function(type, target) {			return this.triggerHandler(type, [$.event.fix({ type: type, target: target })]);		}	})		/* * Flexigrid for jQuery - New Wave Grid * * Copyright (c) 2008 Paulo P. Marinas (webplicity.net/flexigrid) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * $Date: 2008-07-14 00:09:43 +0800 (Tue, 14 Jul 2008) $ */$.addFlex = function(t,p)	{		if (t.grid) return false; //return if already exist					// apply default properties		p = $.extend({			 seccion : '', // Seccion para acciones			 tabla 	 : '',			 cond    : '',			 valor   : '',			 indice  : '',			 campos  : '',			 acciones: '',			 left    : '',			 indice2 : '',			 tabla2  : '',			 columnas: '',			 height: 200, //default height			 width: 'auto', //auto width			 striped: true, //apply odd even stripes			 novstripe: false,			 minwidth: 30, //min width of columns			 minheight: 80, //min height of columns			 resizable: false, //resizable table			 url: false, //ajax url			 method: 'POST', // data sending method			 dataType: 'xml', // type of data loaded			 errormsg: 'Error de conexion.',			 usepager: false, //			 nowrap: true, //			 page: 1, //current page			 total: 1, //total pages			 useRp: true, //use the results per page select box			 rp: 15, // results per page			 rpOptions: [10,15,20,25,40],			 title: false,			 pagestat: 'Del {from} al {to} de {total} Registros',			 procmsg: 'Actualizando, un momento ...',			 query: '',			 qtype: '',			 nomsg: 'No hay registros',			 minColToggle: 1, //minimum allowed column to be hidden			 showToggleBtn: false, //show or hide column toggle popup			 hideOnSubmit: true,			 autoload: true,			 blockOpacity: 0.5,			 onToggleCol: false,			 onChangeSort: false,			 onSuccess: false,			 onSubmit: false // using a custom populate function		  }, p);		  				$(t)		.show() //show if hidden		.attr({cellPadding: 0, cellSpacing: 0, border: 0})  //remove padding and spacing		.removeAttr('width') //remove width properties			;				//create grid class		var g = {			hset : {},			rePosDrag: function () {			var cdleft = 0 - this.hDiv.scrollLeft;			if (this.hDiv.scrollLeft>0) cdleft -= Math.floor(p.cgwidth/2);			$(g.cDrag).css({top:g.hDiv.offsetTop+1});			var cdpad = this.cdpad;						$('div',g.cDrag).hide();						$('thead tr:first th:visible',this.hDiv).each				(			 	function ()					{					var n = $('thead tr:first th:visible',g.hDiv).index(this);					var cdpos = parseInt($('div',this).width());					var ppos = cdpos;					if (cdleft==0) 							cdleft -= Math.floor(p.cgwidth/2); 					cdpos = cdpos + cdleft + cdpad;										$('div:eq('+n+')',g.cDrag).css({'left':cdpos+'px'}).show();					cdleft = cdpos;					}				);							},			fixHeight: function (newH) {					newH = false;					if (!newH) newH = $(g.bDiv).height();					var hdHeight = $(this.hDiv).height();					$('div',this.cDrag).each(						function ()							{								$(this).height(newH+hdHeight);							}					);										var nd = parseInt($(g.nDiv).height());										if (nd>newH)						$(g.nDiv).height(newH).width(200);					else						$(g.nDiv).height('auto').width('auto');										$(g.block).css({height:newH,marginBottom:(newH * -1)});										var hrH = g.bDiv.offsetTop + newH;					if (p.height != 'auto' && p.resizable) hrH = g.vDiv.offsetTop;					$(g.rDiv).css({height: hrH});							},			dragStart: function (dragtype,e,obj) { //default drag function start								if (dragtype=='colresize') //column resize					{						$(g.nDiv).hide();$(g.nBtn).hide();						var n = $('div',this.cDrag).index(obj);						var ow = $('th:visible div:eq('+n+')',this.hDiv).width();						$(obj).addClass('dragging').siblings().hide();						$(obj).prev().addClass('dragging').show();												this.colresize = {startX: e.pageX, ol: parseInt(obj.style.left), ow: ow, n : n };						$('body').css('cursor','col-resize');					}				else if (dragtype=='vresize') //table resize					{						var hgo = false;						$('body').css('cursor','row-resize');						if (obj) 							{							hgo = true;							$('body').css('cursor','col-resize');							}						this.vresize = {h: p.height, sy: e.pageY, w: p.width, sx: e.pageX, hgo: hgo};											}				else if (dragtype=='colMove') //column header drag					{						$(g.nDiv).hide();$(g.nBtn).hide();						this.hset = $(this.hDiv).offset();						this.hset.right = this.hset.left + $('table',this.hDiv).width();						this.hset.bottom = this.hset.top + $('table',this.hDiv).height();						this.dcol = obj;						this.dcoln = $('th',this.hDiv).index(obj);												this.colCopy = document.createElement("div");						this.colCopy.className = "colCopy";						this.colCopy.innerHTML = obj.innerHTML;						if ($.browser.msie)						{						this.colCopy.className = "colCopy ie";						}																		$(this.colCopy).css({position:'absolute',float:'left',display:'none', textAlign: obj.align});						$('body').append(this.colCopy);						$(this.cDrag).hide();											}																		$('body').noSelect();						},			dragMove: function (e) {							if (this.colresize) //column resize					{						var n = this.colresize.n;						var diff = e.pageX-this.colresize.startX;						var nleft = this.colresize.ol + diff;						var nw = this.colresize.ow + diff;						if (nw > p.minwidth)							{								$('div:eq('+n+')',this.cDrag).css('left',nleft);								this.colresize.nw = nw;							}					}				else if (this.vresize) //table resize					{						var v = this.vresize;						var y = e.pageY;						var diff = y-v.sy;												if (!p.defwidth) p.defwidth = p.width;												if (p.width != 'auto' && !p.nohresize && v.hgo)						{							var x = e.pageX;							var xdiff = x - v.sx;							var newW = v.w + xdiff;							if (newW > p.defwidth)								{									this.gDiv.style.width = newW + 'px';									p.width = newW;								}						}												var newH = v.h + diff;						if ((newH > p.minheight || p.height < p.minheight) && !v.hgo)							{								this.bDiv.style.height = newH + 'px';								p.height = newH;								this.fixHeight(newH);							}						v = null;					}				else if (this.colCopy) {					$(this.dcol).addClass('thMove').removeClass('thOver'); 					if (e.pageX > this.hset.right || e.pageX < this.hset.left || e.pageY > this.hset.bottom || e.pageY < this.hset.top)					{						//this.dragEnd();						$('body').css('cursor','move');					}					else 					$('body').css('cursor','pointer');					$(this.colCopy).css({top:e.pageY + 10,left:e.pageX + 20, display: 'block'});				}																			},			dragEnd: function () {				if (this.colresize)					{						var n = this.colresize.n;						var nw = this.colresize.nw;								$('th:visible div:eq('+n+')',this.hDiv).css('width',nw);								$('tr',this.bDiv).each (									function ()										{										$('td:visible div:eq('+n+')',this).css('width',nw);										}								);								this.hDiv.scrollLeft = this.bDiv.scrollLeft;						$('div:eq('+n+')',this.cDrag).siblings().show();						$('.dragging',this.cDrag).removeClass('dragging');						this.rePosDrag();						this.fixHeight();						this.colresize = false;					}				else if (this.vresize)					{						this.vresize = false;					}				else if (this.colCopy)					{						$(this.colCopy).remove();						if (this.dcolt != null)							{																					if (this.dcoln>this.dcolt)																$('th:eq('+this.dcolt+')',this.hDiv).before(this.dcol);							else								$('th:eq('+this.dcolt+')',this.hDiv).after(this.dcol);																												this.switchCol(this.dcoln,this.dcolt);							$(this.cdropleft).remove();							$(this.cdropright).remove();							this.rePosDrag();																																	}												this.dcol = null;						this.hset = null;						this.dcoln = null;						this.dcolt = null;						this.colCopy = null;												$('.thMove',this.hDiv).removeClass('thMove');						$(this.cDrag).show();					}														$('body').css('cursor','default');				$('body').noSelect(false);			},			toggleCol: function(cid,visible) {								var ncol = $("th[axis='col"+cid+"']",this.hDiv)[0];				var n = $('thead th',g.hDiv).index(ncol);				var cb = $('input[value='+cid+']',g.nDiv)[0];												if (visible==null)					{						visible = ncol.hide;					}																if ($('input:checked',g.nDiv).length<p.minColToggle&&!visible) return false;								if (visible)					{						ncol.hide = false;						$(ncol).show();						cb.checked = true;					}				else					{						ncol.hide = true;						$(ncol).hide();						cb.checked = false;					}											$('tbody tr',t).each							(								function ()									{										if (visible)											$('td:eq('+n+')',this).show();										else											$('td:eq('+n+')',this).hide();									}							);															this.rePosDrag();								if (p.onToggleCol) p.onToggleCol(cid,visible);								return visible;			},			switchCol: function(cdrag,cdrop) { //switch columns								$('tbody tr',t).each					(						function ()							{								if (cdrag>cdrop)									$('td:eq('+cdrop+')',this).before($('td:eq('+cdrag+')',this));								else									$('td:eq('+cdrop+')',this).after($('td:eq('+cdrag+')',this));							}					);										//switch order in nDiv					if (cdrag>cdrop)						$('tr:eq('+cdrop+')',this.nDiv).before($('tr:eq('+cdrag+')',this.nDiv));					else						$('tr:eq('+cdrop+')',this.nDiv).after($('tr:eq('+cdrag+')',this.nDiv));											if ($.browser.msie&&$.browser.version<7.0) $('tr:eq('+cdrop+') input',this.nDiv)[0].checked = true;											this.hDiv.scrollLeft = this.bDiv.scrollLeft;			},						scroll: function() {					this.hDiv.scrollLeft = this.bDiv.scrollLeft;					this.rePosDrag();			},			addData: function (data) { //parse data								if (p.preProcess)					data = p.preProcess(data);								$('.pReload',this.pDiv).removeClass('loading');				this.loading = false;				if (!data) 					{					$('.pPageStat',this.pDiv).html(p.errormsg);						return false;					}				if (p.dataType=='xml')					p.total = +$('rows total',data).text();				else					p.total = data.total;									if (p.total==0)					{					$('tr, a, td, div',t).unbind();					$(t).empty();					p.pages = 1;					p.page = 1;					this.buildpager();					$('.pPageStat',this.pDiv).html(p.nomsg);					return false;					}								p.pages = Math.ceil(p.total/p.rp);								if (p.dataType=='xml')					p.page = +$('rows page',data).text();				else					p.page = data.page;								this.buildpager();				//build new body				var tbody = document.createElement('tbody');								if (p.dataType=='json')				{					$.each					(					 data.rows,					 function(i,row) 					 	{							var tr = document.createElement('tr');							if (i % 2 && p.striped) tr.className = 'erow';														if (row.id) tr.id = 'row' + row.id;														//add cell							$('thead tr:first th',g.hDiv).each							(							 	function ()									{																				var td = document.createElement('td');										var idx = $(this).attr('axis').substr(3);										td.align = this.align;										td.innerHTML = row.cell[idx];										$(tr).append(td);										td = null;									}							); 																					if ($('thead',this.gDiv).length<1) //handle if grid has no headers							{									for (idx=0;idx<cell.length;idx++)										{										var td = document.createElement('td');										td.innerHTML = row.cell[idx];										$(tr).append(td);										td = null;										}							}																					$(tbody).append(tr);							tr = null;						}					);													} else if (p.dataType=='xml') {				i = 1;				$("rows row",data).each				(				 				 	function ()						{														i++;														var tr = document.createElement('tr');							if (i % 2 && p.striped) tr.className = 'erow';							var nid =$(this).attr('id');							if (nid) tr.id = 'row' + nid;														nid = null;														var robj = this;																					$('thead tr:first th',g.hDiv).each							(							 	function ()									{																				var td = document.createElement('td');										var idx = $(this).attr('axis').substr(3);										td.align = this.align;										td.innerHTML = $("cell:eq("+ idx +")",robj).text();										$(tr).append(td);										td = null;									}							);																					if ($('thead',this.gDiv).length<1) //handle if grid has no headers							{								$('cell',this).each								(								 	function ()										{										var td = document.createElement('td');										td.innerHTML = $(this).text();										$(tr).append(td);										td = null;										}								);							}														$(tbody).append(tr);							tr = null;							robj = null;						}				);								}				$('tr',t).unbind();				$(t).empty();								$(t).append(tbody);				this.addCellProp();				this.addRowProp();								//this.fixHeight($(this.bDiv).height());								this.rePosDrag();								tbody = null; data = null; i = null; 								if (p.onSuccess) p.onSuccess();				if (p.hideOnSubmit) $(g.block).remove();//$(t).show();								this.hDiv.scrollLeft = this.bDiv.scrollLeft;				if ($.browser.opera) $(t).css('visibility','visible');							},			changeSort: function(th) { //change sortorder							if (this.loading) return true;								$(g.nDiv).hide();$(g.nBtn).hide();								if (p.sortname == $(th).attr('abbr'))					{						if (p.sortorder=='asc') p.sortorder = 'desc'; 						else p.sortorder = 'asc';											}								$(th).addClass('sorted').siblings().removeClass('sorted');				$('.sdesc',this.hDiv).removeClass('sdesc');				$('.sasc',this.hDiv).removeClass('sasc');				$('div',th).addClass('s'+p.sortorder);				p.sortname= $(th).attr('abbr');								if (p.onChangeSort)					p.onChangeSort(p.sortname,p.sortorder);				else					this.populate();										},			buildpager: function(){ //rebuild pager based on new properties						$('.pcontrol input',this.pDiv).val(p.page);			$('.pcontrol span',this.pDiv).html(p.pages);						var r1 = (p.page-1) * p.rp + 1; 			var r2 = r1 + p.rp - 1; 						if (p.total<r2) r2 = p.total;						var stat = p.pagestat;						stat = stat.replace(/{from}/,r1);			stat = stat.replace(/{to}/,r2);			stat = stat.replace(/{total}/,p.total);						$('.pPageStat',this.pDiv).html(stat);						},			populate: function () { //get latest data				if (this.loading) return true;				if (p.onSubmit)					{						var gh = p.onSubmit();						if (!gh) return false;					}				this.loading = true;				if (!p.url) return false;								$('.pPageStat',this.pDiv).html(p.procmsg);								$('.pReload',this.pDiv).addClass('loading');								$(g.block).css({top:g.bDiv.offsetTop});								if (p.hideOnSubmit) $(this.gDiv).prepend(g.block); //$(t).hide();								if ($.browser.opera) $(t).css('visibility','hidden');								if (!p.newp) p.newp = 1;								if (p.page>p.pages) p.page = p.pages;				//var param = {page:p.newp, rp: p.rp, sortname: p.sortname, sortorder: p.sortorder, query: p.query, qtype: p.qtype};				var param = [					 { name : 'page', value : p.newp }					,{ name : 'rp', value : p.rp }					,{ name : 'sortname', value : p.sortname}					,{ name : 'sortorder', value : p.sortorder }					,{ name : 'query', value : p.query}					,{ name : 'qtype', value : p.qtype}					,{ name : 'seccion', value : p.seccion}					,{ name : 'tabla', value : p.tabla}					,{ name : 'cond', value : p.cond}					,{ name : 'valor', value : p.valor}					,{ name : 'indice', value : p.indice}					,{ name : 'campos', value : p.campos}					,{ name : 'acciones', value : p.acciones}					,{ name : 'left', value : p.left}					,{ name : 'indice2', value : p.indice2}					,{ name : 'tabla2', value : p.tabla2}					,{ name : 'columnas', value : p.columnas}					];							 							 				if (p.params)					{						for (var pi = 0; pi < p.params.length; pi++) param[param.length] = p.params[pi];					}									$.ajax({					   type: p.method,					   url: p.url,					   data: param,					   dataType: p.dataType,					   success: function(data){g.addData(data);},					   error: function(data) { try { if (p.onError) p.onError(data); } catch (e) {} }					 });			},			doSearch: function () {				p.query = $('input[name=q]',g.sDiv).val();				p.qtype = $('select[name=qtype]',g.sDiv).val();				p.newp = 1;				this.populate();							},			changePage: function (ctype){ //change page							if (this.loading) return true;							switch(ctype)				{					case 'first': p.newp = 1; break;					case 'prev': if (p.page>1) p.newp = parseInt(p.page) - 1; break;					case 'next': if (p.page<p.pages) p.newp = parseInt(p.page) + 1; break;					case 'last': p.newp = p.pages; break;					case 'input': 							var nv = parseInt($('.pcontrol input',this.pDiv).val());							if (isNaN(nv)) nv = 1;							if (nv<1) nv = 1;							else if (nv > p.pages) nv = p.pages;							$('.pcontrol input',this.pDiv).val(nv);							p.newp =nv;							break;				}							if (p.newp==p.page) return false;								if (p.onChangePage) 					p.onChangePage(p.newp);				else									this.populate();						},			addCellProp: function ()			{									$('tbody tr td',g.bDiv).each					(						function ()							{									var tdDiv = document.createElement('div');									var n = $('td',$(this).parent()).index(this);									var pth = $('th:eq('+n+')',g.hDiv).get(0);												if (pth!=null)									{									if (p.sortname==$(pth).attr('abbr')&&p.sortname) 										{										this.className = 'sorted';										}									 $(tdDiv).css({textAlign:pth.align,width: $('div:first',pth)[0].style.width});									 									 if (pth.hide) $(this).css('display','none');									 									 }									 									 if (p.nowrap==false) $(tdDiv).css('white-space','normal');									 									 if (this.innerHTML=='') this.innerHTML = ' ';									 									 //tdDiv.value = this.innerHTML; //store preprocess value									 tdDiv.innerHTML = this.innerHTML;									 									 var prnt = $(this).parent()[0];									 var pid = false;									 if (prnt.id) pid = prnt.id.substr(3);									 									 if (pth!=null)									 {									 if (pth.process) pth.process(tdDiv,pid);									 }									 									$(this).empty().append(tdDiv).removeAttr('width'); //wrap content									//add editable event here 'dblclick'							}					);								},			getCellDim: function (obj) // get cell prop for editable event			{				var ht = parseInt($(obj).height());				var pht = parseInt($(obj).parent().height());				var wt = parseInt(obj.style.width);				var pwt = parseInt($(obj).parent().width());				var top = obj.offsetParent.offsetTop;				var left = obj.offsetParent.offsetLeft;				var pdl = parseInt($(obj).css('paddingLeft'));				var pdt = parseInt($(obj).css('paddingTop'));				return {ht:ht,wt:wt,top:top,left:left,pdl:pdl, pdt:pdt, pht:pht, pwt: pwt};			},			addRowProp: function()			{					$('tbody tr',g.bDiv).each					(						function ()							{							$(this)							.click(								function (e) 									{ 										var obj = (e.target || e.srcElement); if (obj.href || obj.type) return true;										$(this).toggleClass('trSelected');										if (p.singleSelect) $(this).siblings().removeClass('trSelected');									}							)							.mousedown(								function (e)									{										if (e.shiftKey)										{										$(this).toggleClass('trSelected'); 										g.multisel = true; 										this.focus();										$(g.gDiv).noSelect();										}									}							)							.mouseup(								function ()									{										if (g.multisel)										{										g.multisel = false;										$(g.gDiv).noSelect(false);										}									}							)							.hover(								function (e) 									{ 									if (g.multisel) 										{										$(this).toggleClass('trSelected'); 										}									},								function () {}													)							;														if ($.browser.msie&&$.browser.version<7.0)								{									$(this)									.hover(										function () { $(this).addClass('trOver'); },										function () { $(this).removeClass('trOver'); }									)									;								}							}					);													},			pager: 0			};						//create model if any		if (p.colModel)		{			thead = document.createElement('thead');			tr = document.createElement('tr');						for (i=0;i<p.colModel.length;i++)				{					var cm = p.colModel[i];					var th = document.createElement('th');					th.innerHTML = cm.display;										if (cm.name&&cm.sortable)						$(th).attr('abbr',cm.name);										//th.idx = i;					$(th).attr('axis','col'+i);										if (cm.align)						th.align = cm.align;											if (cm.width) 						$(th).attr('width',cm.width);					if (cm.hide)						{						th.hide = true;						}											if (cm.process)						{							th.process = cm.process;						}					$(tr).append(th);				}			$(thead).append(tr);			$(t).prepend(thead);		} // end if p.colmodel			//init divs		g.gDiv = document.createElement('div'); //create global container		g.mDiv = document.createElement('div'); //create title container		g.hDiv = document.createElement('div'); //create header container		g.bDiv = document.createElement('div'); //create body container		g.vDiv = document.createElement('div'); //create grip		g.rDiv = document.createElement('div'); //create horizontal resizer		g.cDrag = document.createElement('div'); //create column drag		g.block = document.createElement('div'); //creat blocker		g.nDiv = document.createElement('div'); //create column show/hide popup		g.nBtn = document.createElement('div'); //create column show/hide button		g.iDiv = document.createElement('div'); //create editable layer		g.tDiv = document.createElement('div'); //create toolbar		g.sDiv = document.createElement('div');				if (p.usepager) g.pDiv = document.createElement('div'); //create pager container		g.hTable = document.createElement('table');		//set gDiv		g.gDiv.className = 'flexigrid';		if (p.width!='auto') g.gDiv.style.width = p.width + 'px';		//add conditional classes		if ($.browser.msie)			$(g.gDiv).addClass('ie');				if (p.novstripe)			$(g.gDiv).addClass('novstripe');		$(t).before(g.gDiv);		$(g.gDiv)		.append(t)		;		//set toolbar		if (p.buttons) 		{			g.tDiv.className = 'tDiv';			var tDiv2 = document.createElement('div');			tDiv2.className = 'tDiv2';						for (i=0;i<p.buttons.length;i++)				{					var btn = p.buttons[i];					if (!btn.separator)					{						var btnDiv = document.createElement('div');						btnDiv.className = 'fbutton';						btnDiv.innerHTML = "<div><span>"+btn.name+"</span></div>";						if (btn.bclass) 							$('span',btnDiv)							.addClass(btn.bclass)							.css({paddingLeft:20})							;						btnDiv.onpress = btn.onpress;						btnDiv.name = btn.name;						if (btn.onpress)						{							$(btnDiv).click							(									function () 								{								this.onpress(this.name,g.gDiv);								}							);						}						$(tDiv2).append(btnDiv);						if ($.browser.msie&&$.browser.version<7.0)						{							$(btnDiv).hover(function(){$(this).addClass('fbOver');},function(){$(this).removeClass('fbOver');});						}											} else {						$(tDiv2).append("<div class='btnseparator'></div>");					}				}				$(g.tDiv).append(tDiv2);				$(g.tDiv).append("<div style='clear:both'></div>");				$(g.gDiv).prepend(g.tDiv);		}				//set hDiv		g.hDiv.className = 'hDiv';		$(t).before(g.hDiv);		//set hTable			g.hTable.cellPadding = 0;			g.hTable.cellSpacing = 0;			$(g.hDiv).append('<div class="hDivBox"></div>');			$('div',g.hDiv).append(g.hTable);			var thead = $("thead:first",t).get(0);			if (thead) $(g.hTable).append(thead);			thead = null;				if (!p.colmodel) var ci = 0;		//setup thead						$('thead tr:first th',g.hDiv).each			(			 	function ()					{						var thdiv = document.createElement('div');																							if ($(this).attr('abbr'))							{							$(this).click(								function (e) 									{																				if (!$(this).hasClass('thOver')) return false;										var obj = (e.target || e.srcElement);										if (obj.href || obj.type) return true; 										g.changeSort(this);									}							)							;														if ($(this).attr('abbr')==p.sortname)								{								this.className = 'sorted';								thdiv.className = 's'+p.sortorder;								}							}														if (this.hide) $(this).hide();														if (!p.colmodel)							{								$(this).attr('axis','col' + ci++);							}																				 $(thdiv).css({textAlign:this.align, width: this.width + 'px'});						 thdiv.innerHTML = this.innerHTML;						 						$(this).empty().append(thdiv).removeAttr('width')						.mousedown(function (e) 							{								g.dragStart('colMove',e,this);							})						.hover(							function(){								if (!g.colresize&&!$(this).hasClass('thMove')&&!g.colCopy) $(this).addClass('thOver');																if ($(this).attr('abbr')!=p.sortname&&!g.colCopy&&!g.colresize&&$(this).attr('abbr')) $('div',this).addClass('s'+p.sortorder);								else if ($(this).attr('abbr')==p.sortname&&!g.colCopy&&!g.colresize&&$(this).attr('abbr'))									{										var no = '';										if (p.sortorder=='asc') no = 'desc';										else no = 'asc';										$('div',this).removeClass('s'+p.sortorder).addClass('s'+no);									}																if (g.colCopy) 									{									var n = $('th',g.hDiv).index(this);																		if (n==g.dcoln) return false;																																				if (n<g.dcoln) $(this).append(g.cdropleft);									else $(this).append(g.cdropright);																		g.dcolt = n;																		} else if (!g.colresize) {																			var nv = $('th:visible',g.hDiv).index(this);									var onl = parseInt($('div:eq('+nv+')',g.cDrag).css('left'));									var nw = parseInt($(g.nBtn).width()) + parseInt($(g.nBtn).css('borderLeftWidth'));									nl = onl - nw + Math.floor(p.cgwidth/2);																		$(g.nDiv).hide();$(g.nBtn).hide();																		$(g.nBtn).css({'left':nl,top:g.hDiv.offsetTop}).show();																		var ndw = parseInt($(g.nDiv).width());																		$(g.nDiv).css({top:g.bDiv.offsetTop});																		if ((nl+ndw)>$(g.gDiv).width())										$(g.nDiv).css('left',onl-ndw+1);									else										$(g.nDiv).css('left',nl);																			if ($(this).hasClass('sorted')) 										$(g.nBtn).addClass('srtd');									else										$(g.nBtn).removeClass('srtd');																			}																},							function(){								$(this).removeClass('thOver');								if ($(this).attr('abbr')!=p.sortname) $('div',this).removeClass('s'+p.sortorder);								else if ($(this).attr('abbr')==p.sortname)									{										var no = '';										if (p.sortorder=='asc') no = 'desc';										else no = 'asc';																				$('div',this).addClass('s'+p.sortorder).removeClass('s'+no);									}								if (g.colCopy) 									{																	$(g.cdropleft).remove();									$(g.cdropright).remove();									g.dcolt = null;									}							})						; //wrap content					}			);		//set bDiv		g.bDiv.className = 'bDiv';		$(t).before(g.bDiv);		$(g.bDiv)		.css({ height: (p.height=='auto') ? 'auto' : p.height+"px"})		.scroll(function (e) {g.scroll()})		.append(t)		;				if (p.height == 'auto') 			{			$('table',g.bDiv).addClass('autoht');			}		//add td properties		g.addCellProp();				//add row properties		g.addRowProp();				//set cDrag				var cdcol = $('thead tr:first th:first',g.hDiv).get(0);				if (cdcol != null)		{				g.cDrag.className = 'cDrag';		g.cdpad = 0;				g.cdpad += (isNaN(parseInt($('div',cdcol).css('borderLeftWidth'))) ? 0 : parseInt($('div',cdcol).css('borderLeftWidth'))); 		g.cdpad += (isNaN(parseInt($('div',cdcol).css('borderRightWidth'))) ? 0 : parseInt($('div',cdcol).css('borderRightWidth'))); 		g.cdpad += (isNaN(parseInt($('div',cdcol).css('paddingLeft'))) ? 0 : parseInt($('div',cdcol).css('paddingLeft'))); 		g.cdpad += (isNaN(parseInt($('div',cdcol).css('paddingRight'))) ? 0 : parseInt($('div',cdcol).css('paddingRight'))); 		g.cdpad += (isNaN(parseInt($(cdcol).css('borderLeftWidth'))) ? 0 : parseInt($(cdcol).css('borderLeftWidth'))); 		g.cdpad += (isNaN(parseInt($(cdcol).css('borderRightWidth'))) ? 0 : parseInt($(cdcol).css('borderRightWidth'))); 		g.cdpad += (isNaN(parseInt($(cdcol).css('paddingLeft'))) ? 0 : parseInt($(cdcol).css('paddingLeft'))); 		g.cdpad += (isNaN(parseInt($(cdcol).css('paddingRight'))) ? 0 : parseInt($(cdcol).css('paddingRight'))); 		$(g.bDiv).before(g.cDrag);				var cdheight = $(g.bDiv).height();		var hdheight = $(g.hDiv).height();				$(g.cDrag).css({top: -hdheight + 'px'});				$('thead tr:first th',g.hDiv).each			(			 	function ()					{						var cgDiv = document.createElement('div');						$(g.cDrag).append(cgDiv);						if (!p.cgwidth) p.cgwidth = $(cgDiv).width();						$(cgDiv).css({height: cdheight + hdheight})						.mousedown(function(e){g.dragStart('colresize',e,this);})						;						if ($.browser.msie&&$.browser.version<7.0)						{							g.fixHeight($(g.gDiv).height());							$(cgDiv).hover(								function () 								{								g.fixHeight();								$(this).addClass('dragging') 								},								function () { if (!g.colresize) $(this).removeClass('dragging') }							);						}					}			);				//g.rePosDrag();									}				//add strip				if (p.striped) 			$('tbody tr:odd',g.bDiv).addClass('erow');								if (p.resizable && p.height !='auto') 		{		g.vDiv.className = 'vGrip';		$(g.vDiv)		.mousedown(function (e) { g.dragStart('vresize',e)})		.html('<span></span>');		$(g.bDiv).after(g.vDiv);		}				if (p.resizable && p.width !='auto' && !p.nohresize) 		{		g.rDiv.className = 'hGrip';		$(g.rDiv)		.mousedown(function (e) {g.dragStart('vresize',e,true);})		.html('<span></span>')		.css('height',$(g.gDiv).height())		;		if ($.browser.msie&&$.browser.version<7.0)		{			$(g.rDiv).hover(function(){$(this).addClass('hgOver');},function(){$(this).removeClass('hgOver');});		}		$(g.gDiv).append(g.rDiv);		}				// add pager		if (p.usepager)		{		g.pDiv.className = 'pDiv';		g.pDiv.innerHTML = '<div class="pDiv2"></div>';		$(g.bDiv).after(g.pDiv);		var html = ' <div class="pGroup"> <div class="pFirst pButton"><span></span></div><div class="pPrev pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pcontrol">Pagina <input type="text" size="4" value="1" /> de <span> 1 </span></span></div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pNext pButton"><span></span></div><div class="pLast pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pReload pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pPageStat"></span></div>';		$('div',g.pDiv).html(html);				$('.pReload',g.pDiv).click(function(){g.populate()});		$('.pFirst',g.pDiv).click(function(){g.changePage('first')});		$('.pPrev',g.pDiv).click(function(){g.changePage('prev')});		$('.pNext',g.pDiv).click(function(){g.changePage('next')});		$('.pLast',g.pDiv).click(function(){g.changePage('last')});		$('.pcontrol input',g.pDiv).keydown(function(e){if(e.keyCode==13) g.changePage('input')});		if ($.browser.msie&&$.browser.version<7) $('.pButton',g.pDiv).hover(function(){$(this).addClass('pBtnOver');},function(){$(this).removeClass('pBtnOver');});						if (p.useRp)			{			var opt = "";			for (var nx=0;nx<p.rpOptions.length;nx++)			{				if (p.rp == p.rpOptions[nx]) sel = 'selected="selected"'; else sel = '';				 opt += "<option value='" + p.rpOptions[nx] + "' " + sel + " >" + p.rpOptions[nx] + "&nbsp;&nbsp;</option>";			};			$('.pDiv2',g.pDiv).prepend("<div class='pGroup'><select name='rp'>"+opt+"</select></div> <div class='btnseparator'></div>");			$('select',g.pDiv).change(					function ()					{						if (p.onRpChange) 							p.onRpChange(+this.value);						else							{							p.newp = 1;							p.rp = +this.value;							g.populate();							}					}				);			}				//add search button		if (p.searchitems)			{				$('.pDiv2',g.pDiv).prepend("<div class='pGroup'> <div class='pSearch pButton'><span></span></div> </div>  <div class='btnseparator'></div>");				$('.pSearch',g.pDiv).click(function(){$(g.sDiv).slideToggle('fast',function(){$('.sDiv:visible input:first',g.gDiv).trigger('focus');});});								//add search box				g.sDiv.className = 'sDiv';								sitems = p.searchitems;								var sopt = "";				for (var s = 0; s < sitems.length; s++)				{					if (p.qtype=='' && sitems[s].isdefault==true)					{					p.qtype = sitems[s].name;					sel = 'selected="selected"';					} else sel = '';					sopt += "<option value='" + sitems[s].name + "' " + sel + " >" + sitems[s].display + "  </option>";										}								if (p.qtype=='') p.qtype = sitems[0].name;								$(g.sDiv).append("<div class='sDiv2'>Buscar : <input type='text' size='30' name='q' class='qsbox' /> <select name='qtype'>"+sopt+"</select> <input type='button' value='Borrar' /></div>");				$('input[name=q],select[name=qtype]',g.sDiv).keydown(function(e){if(e.keyCode==13) g.doSearch()});				$('input[value=Clear]',g.sDiv).click(function(){$('input[name=q]',g.sDiv).val(''); p.query = ''; g.doSearch(); });				$(g.bDiv).after(g.sDiv);											}				}		$(g.pDiv,g.sDiv).append("<div style='clear:both'></div>");			// add title		if (p.title)		{			g.mDiv.className = 'mDiv';			g.mDiv.innerHTML = '<div class="ftitle">'+p.title+'</div>';			$(g.gDiv).prepend(g.mDiv);			if (p.showTableToggleBtn)				{					$(g.mDiv).append('<div class="ptogtitle" title="Minimize/Maximize Table"><span></span></div>');					$('div.ptogtitle',g.mDiv).click					(					 	function ()							{								$(g.gDiv).toggleClass('hideBody');								$(this).toggleClass('vsble');							}					);				}			//g.rePosDrag();		}		//setup cdrops		g.cdropleft = document.createElement('span');		g.cdropleft.className = 'cdropleft';		g.cdropright = document.createElement('span');		g.cdropright.className = 'cdropright';		//add block		g.block.className = 'gBlock';		var gh = $(g.bDiv).height();		var gtop = g.bDiv.offsetTop;		$(g.block).css(		{			width: g.bDiv.style.width,			height: gh,			background: 'white',			position: 'relative',			marginBottom: (gh * -1),			zIndex: 1,			top: gtop,			left: '0px'		}		);		$(g.block).fadeTo(0,p.blockOpacity);								// add column control		if ($('th',g.hDiv).length)		{						g.nDiv.className = 'nDiv';			g.nDiv.innerHTML = "<table cellpadding='0' cellspacing='0'><tbody></tbody></table>";			$(g.nDiv).css(			{				marginBottom: (gh * -1),				display: 'none',				top: gtop			}			).noSelect()			;						var cn = 0;									$('th div',g.hDiv).each			(			 	function ()					{						var kcol = $("th[axis='col" + cn + "']",g.hDiv)[0];						var chk = 'checked="checked"';						if (kcol.style.display=='none') chk = '';												$('tbody',g.nDiv).append('<tr><td class="ndcol1"><input type="checkbox" '+ chk +' class="togCol" value="'+ cn +'" /></td><td class="ndcol2">'+this.innerHTML+'</td></tr>');						cn++;					}			);						if ($.browser.msie&&$.browser.version<7.0)				$('tr',g.nDiv).hover				(				 	function () {$(this).addClass('ndcolover');},					function () {$(this).removeClass('ndcolover');}				);						$('td.ndcol2',g.nDiv).click			(			 	function ()					{						if ($('input:checked',g.nDiv).length<=p.minColToggle&&$(this).prev().find('input')[0].checked) return false;						return g.toggleCol($(this).prev().find('input').val());					}			);						$('input.togCol',g.nDiv).click			(			 	function ()					{												if ($('input:checked',g.nDiv).length<p.minColToggle&&this.checked==false) return false;						$(this).parent().next().trigger('click');						//return false;					}			);			$(g.gDiv).prepend(g.nDiv);						$(g.nBtn).addClass('nBtn')			.html('<div></div>')			.attr('title','Hide/Show Columns')			.click			(			 	function ()				{			 	$(g.nDiv).toggle(); return true;				}			);						if (p.showToggleBtn) $(g.gDiv).prepend(g.nBtn);					}				// add date edit layer		$(g.iDiv)		.addClass('iDiv')		.css({display:'none'})		;		$(g.bDiv).append(g.iDiv);				// add flexigrid events		$(g.bDiv)		.hover(function(){$(g.nDiv).hide();$(g.nBtn).hide();},function(){if (g.multisel) g.multisel = false;})		;		$(g.gDiv)		.hover(function(){},function(){$(g.nDiv).hide();$(g.nBtn).hide();})		;				//add document events		$(document)		.mousemove(function(e){g.dragMove(e)})		.mouseup(function(e){g.dragEnd()})		.hover(function(){},function (){g.dragEnd()})		;				//browser adjustments		if ($.browser.msie&&$.browser.version<7.0)		{			$('.hDiv,.bDiv,.mDiv,.pDiv,.vGrip,.tDiv, .sDiv',g.gDiv)			.css({width: '100%'});			$(g.gDiv).addClass('ie6');			if (p.width!='auto') $(g.gDiv).addClass('ie6fullwidthbug');					} 				g.rePosDrag();		g.fixHeight();				//make grid functions accessible		t.p = p;		t.grid = g;				// load data		if (p.url&&p.autoload) 			{			g.populate();			}				return t;						};	var docloaded = false;	$(document).ready(function () {docloaded = true} );	$.fn.flexigrid = function(p) {		return this.each( function() {				if (!docloaded)				{					$(this).hide();					var t = this;					$(document).ready					(						function ()						{						$.addFlex(t,p);						}					);				} else {					$.addFlex(this,p);				}			});	}; //end flexigrid	$.fn.flexReload = function(p) { // function to reload grid		return this.each( function() {				if (this.grid&&this.p.url) this.grid.populate();			});	}; //end flexReload	$.fn.flexOptions = function(p) { //function to update general options		return this.each( function() {				if (this.grid) $.extend(this.p,p);			});	}; //end flexOptions	$.fn.flexToggleCol = function(cid,visible) { // function to reload grid		return this.each( function() {				if (this.grid) this.grid.toggleCol(cid,visible);			});	}; //end flexToggleCol	$.fn.flexAddData = function(data) { // function to add data to grid		return this.each( function() {				if (this.grid) this.grid.addData(data);			});	};	$.fn.noSelect = function(p) { //no select plugin by me :-)		if (p == null) 			prevent = true;		else			prevent = p;		if (prevent) {				return this.each(function ()			{				if ($.browser.msie||$.browser.safari) $(this).bind('selectstart',function(){return false;});				else if ($.browser.mozilla) 					{						$(this).css('MozUserSelect','none');						$('body').trigger('focus');					}				else if ($.browser.opera) $(this).bind('mousedown',function(){return false;});				else $(this).attr('unselectable','on');			});					} else {				return this.each(function ()			{				if ($.browser.msie||$.browser.safari) $(this).unbind('selectstart');				else if ($.browser.mozilla) $(this).css('MozUserSelect','inherit');				else if ($.browser.opera) $(this).unbind('mousedown');				else $(this).removeAttr('unselectable','on');			});				}	}; //end noSelect})(jQuery);