Index: branches/1.3.x/platform/inc/form_manager.js =================================================================== diff -u -N -r15665 -r15893 --- branches/1.3.x/platform/inc/form_manager.js (.../form_manager.js) (revision 15665) +++ branches/1.3.x/platform/inc/form_manager.js (.../form_manager.js) (revision 15893) @@ -17,13 +17,27 @@ this.fieldWatermarks = {}; this.xhrRequests = []; + this.windowScope = 'a.form-manager-window, area.form-manager-window, input.form-manager-window'; + this.windowManager = undefined; $.extend(this, $settings); -} + if ( this.windowManager === undefined ) { + this.windowManager = new FormManager_WindowManagerExample(); + } + + $(document).ready(function () { + FormManager.windowManager.init(FormManager.windowScope); + + $(document).on('FormManager.WindowManager.Ready', function ($e) { + $(FormManager.windowManager.getContentSelector()).scrollTop(0); + }); + }); +}; + FormManager.resetFields = function ($prefix) { this.fields[$prefix] = []; -} +}; FormManager.registerField = function ($prefix, $field, $watermark, $field_type) { // fields are registered before form -> store them in separate array @@ -42,7 +56,7 @@ if ($field_type !== undefined) { this.fieldTypes[$prefix + '_' + $field] = $field_type; } -} +}; FormManager.unregisterField = function ($prefix, $field) { var $field_index = array_search($field, this.fields[$prefix]); @@ -51,12 +65,11 @@ delete this.fieldWatermarks[$prefix + '_' + $field]; delete this.fieldTypes[$prefix + '_' + $field]; -} +}; - FormManager.getFieldMask = function ($prefix) { return this.fieldMask.replace('#PREFIX#', $prefix).replace('#ID#', this.form_param($prefix, 'id')); -} +}; FormManager.getField = function ($prefix, $field, $prepend, $append) { if ($prepend === undefined) { @@ -70,7 +83,7 @@ var $control_id = this.getFieldMask($prefix).replace('#FIELD_NAME#', $field); return document.getElementById($prepend + $control_id + $append); -} +}; FormManager.getBlurFields = function ($prefix, $field) { var $field_mask = this.getFieldMask($prefix); @@ -102,7 +115,7 @@ } return this.getField($prefix, $field); -} +}; FormManager.registerForm = function ($settings) { var $defaults = { @@ -116,14 +129,16 @@ form_id: '', // form id to work with before_close: '', // before window close callback validation_failure: '', // on validate failure callback - immediate_validation: true // perfom validation on blur - } + immediate_validation: true // perform validation on blur + }; this.forms[$settings.prefix] = {}; $.extend(this.forms[$settings.prefix], $defaults, $settings); - // when form is registred, then all it's fields should also be registred + $(document).trigger('FormManager.Form.Ready', [$settings.prefix]); + // when form is registered, then all it's fields should also be registered + if ( !this.form_param($settings.prefix, 'immediate_validation') ) { return ; } @@ -146,15 +161,11 @@ for (var $error_field in this.errors[$settings.prefix]) { this.setFieldStatus($settings.prefix, $error_field, this.errors[$settings.prefix][$error_field]); } -} +}; FormManager.getURL = function ($prefix, $template, $event, $params) { - var $url = this.form_param($prefix, 'url'); + var $url = this.getUrlMask($prefix); - if (!$url) { - $url = this.url; - } - if ($template === undefined) { $template = this.form_param($prefix, 'template'); } @@ -172,8 +183,25 @@ } return $url; -} +}; +FormManager.getUrlMask = function ($prefix) { + // 1. look in form config + var $url = this.form_param($prefix, 'url'); + + if ( !$url ) { + // 2. look at 'action' attribute of a form + $url = this.getForm($prefix).attr('action'); + } + + if ( !$url ) { + // 3. use global fallback url + $url = this.url; + } + + return $url; +}; + FormManager.processResponse = function ($prefix, $data, $add_params) { // enable form back // alert('enabling for for [' + $prefix + '] in processResponse'); @@ -186,6 +214,7 @@ } this.clearErrors($prefix); + this.processUploadFields($prefix, $data); if ($data.status == 'OK') { var $next_template = this.getNextTemplate($prefix, $data); @@ -199,15 +228,19 @@ if ( $next_template ) { // load another template instead of current form - $('#TB_ajaxContent').html('').load( this.getURL($prefix, $next_template, undefined, $data.params) ); + $(this.windowManager.getContentSelector()) + .html('') + .load(this.getURL($prefix, $next_template, undefined, $data.params), function () { + $(document).trigger('FormManager.WindowManager.Ready'); + }); } else if ( $data.do_refresh ) { // refresh whole page - window.location.href = window.location.href; + window.location.reload(true); } else if ( $data.redirect_to ) { // redirect to given page - window.location.href = $data.redirect_to; + window.location.assign($data.redirect_to); } } else { @@ -232,7 +265,7 @@ // var $me = this; // setTimeout(function () { $me.enableForm($prefix, true); }, 1000); -} +}; /** * Clear errors from all from fields @@ -251,7 +284,7 @@ for (var $i = 0; $i < $fields.length; $i++) { this.setFieldStatus($prefix, $fields[$i]); } -} +}; FormManager.getNextTemplate = function ($prefix, $responce) { if ( $responce.next_template && $responce.next_template != '' ) { @@ -262,23 +295,23 @@ } return false; -} +}; FormManager.getCell = function ($prefix, $field_name, $cell_type) { $field_name = $field_name.replace(/_(date|time)$/, ''); return this.getField($prefix, $field_name, undefined, '_' + $cell_type + '_cell'); -} +}; FormManager.setFieldStatus = function ($prefix, $field_name, $error_msg) { - var field_cell = this.getCell($prefix, $field_name, 'field'); - var status_cell = this.getCell($prefix, $field_name, 'status'); + var field_cell = $(this.getCell($prefix, $field_name, 'field')); + var status_cell = $(this.getCell($prefix, $field_name, 'status')); if ( $error_msg === undefined || !$error_msg ) { $error_msg = ''; } - if ( !field_cell ) { + if ( field_cell.length == 0 ) { if (!this.errors[$prefix]) { this.errors[$prefix] = {}; } @@ -294,8 +327,8 @@ if ($error_msg === undefined || !$error_msg) { // show OK - $(field_cell).parents('tr:first').removeClass('error').addClass('ok'); - $(status_cell).removeClass('field-error').html(this.noErrorsHTML); + field_cell.parents('tr:first').removeClass('error').addClass('ok'); + status_cell.removeClass('field-error').html(this.noErrorsHTML); var $fields = this.fields[$prefix]; @@ -307,16 +340,16 @@ } else { // show error message - $(field_cell).parents('tr:first').removeClass('ok').addClass('error'); - $(status_cell).addClass('field-error').html($error_msg); + field_cell.parents('tr:first').removeClass('ok').addClass('error'); + status_cell.addClass('field-error').html($error_msg); } -} +}; FormManager.fieldHasError = function ($prefix, $field) { var status_cell = this.getField($prefix, $field, undefined, '_status_cell'); return $.trim( $(status_cell).html() ) != $.trim( this.noErrorsHTML ); -} +}; FormManager.checkField = function ($input, $delayed) { if ( !$input.id.match(/^(.*?)\[.*?\]\[(.*?)\].*?$/) ) { @@ -343,7 +376,7 @@ }, ($delayed === true ? this.checkTimeout : 0) ); -} +}; FormManager.validateField = function ($prefix, $field, $input) { var $me = this; @@ -354,6 +387,7 @@ function ($data) { $data = eval('(' + $data + ')'); $me.setFieldStatus($prefix, $field, $data.status == 'OK' ? undefined : $data.status); + $me.processUploadFields($prefix, $data); // show/hide general error notice $('#' + $prefix + '_error_message').toggle(!$.isArray($data.other_errors)); @@ -363,6 +397,21 @@ this.xhrRequests.push($request); }; +FormManager.processUploadFields = function ($prefix, $response) { + if ( $response['uploader_info'] === undefined || $.isArray($response['uploader_info']) ) { + // no data (event don't support that) OR empty array (no uploader fields on form) + return; + } + + var $field_mask = this.getFieldMask($prefix); + + $.each($response['uploader_info'], function ($field_name, $field_data) { + var $uploader_id = $field_mask.replace('#FIELD_NAME#', $field_name); + + $(document).trigger('UploadsManager.Uploader.' + crc32($uploader_id), ['refreshQueue', $field_data]); + }); +}; + FormManager.form_param = function ($prefix, $param, $value) { if ( this.forms[$prefix] === undefined ) { return ''; @@ -373,38 +422,30 @@ } this.forms[$prefix][$param] = $value; -} +}; FormManager.getFormParamOverride = function ($prefix, $param, $overrides) { if ( $overrides[$param] !== undefined ) { return $overrides[$param]; } return this.form_param($prefix, $param); -} +}; /* === related to form opening/closing/submitting === */ FormManager.openForm = function ($prefix, $template, $width, $height, $source_form, $params) { var $url = this.getURL($prefix, $template, undefined, $params); - $url += ($url.indexOf('?') == -1 ? '?' : '&') + 'width=' + $width + '&height=' + $height + '&modal=true'; + this.windowManager.open($url, $width, $height, $source_form); +}; - var $tb_settings = {url: $url}; - - if ($source_form !== undefined) { - $tb_settings.postParams = $($source_form).serialize(); - } - - TB.show($tb_settings); -} - FormManager.validateAll = function ($prefix, $status) { var $fields = this.fields[$prefix]; for (var $i = 0; $i < $fields.length; $i++) { this.setFieldStatus($prefix, $fields[$i], $status); } -} +}; FormManager.closeForm = function ($prefix, $data, $add_params) { if ( $data === undefined ) { @@ -428,8 +469,8 @@ } } - TB.remove(); -} + this.windowManager.close(); +}; FormManager._getFormFields = function ($prefix) { var $old_values = {}, @@ -453,8 +494,7 @@ } } - var form = document.getElementById( this.form_param($prefix, 'form_id')), - $form_fields = $(form).serialize(); + var $form_fields = this.getForm($prefix).serialize(); // restore original values into input fields for (var $i = 0; $i < $fields.length; $i++) { @@ -466,8 +506,14 @@ } return $form_fields; -} +}; +FormManager.getForm = function ($prefix) { + var $form_id = this.form_param($prefix, 'form_id'); + + return $('#' + jq($form_id)); +}; + FormManager.enableForm = function ($prefix, $enabled) { if ($enabled === undefined) { $enabled = true; @@ -493,13 +539,13 @@ } this.form_param($prefix, 'enabled', $enabled); -} +}; FormManager.cancelXHRRequests = function () { while ( this.xhrRequests.length > 0 ) { this.xhrRequests.shift().abort(); } -} +}; FormManager.submitForm = function ($prefix, $add_params) { if ( !this.form_param($prefix, 'enabled') ) { @@ -516,7 +562,7 @@ this.getURL( $prefix, undefined, this.form_param($prefix, 'save_event') ), this._getFormFields($prefix), function ($data) { - var $redirect = TB.parseRedirect($data); + var $redirect = FormManager.parseRedirect($data); if ( $redirect !== false ) { window.location.href = $redirect; @@ -527,7 +573,7 @@ $me.processResponse($prefix, eval('(' + $data + ')'), $add_params); } ) -} +}; FormManager.beforeClose = function () { this.cancelXHRRequests(); @@ -541,4 +587,280 @@ $before_close.call(this, {}, {}); } } +}; + +FormManager.parseRedirect = function ($data) { + var $match_redirect = new RegExp('^#redirect#(.*?)($|\\s.*)').exec($data); + + if ( $match_redirect != null ) { + // redirect to external template requested + return $match_redirect[1]; + } + + return false; +}; + +FormManager.parseQueryString = function ($url) { + var $query_string = {}; + + $url.replace( + new RegExp('([^?=&]+)(=([^&]*))?', 'g'), + function($0, $1, $2, $3) { + $query_string[$1] = decodeURIComponent($3); + } + ); + + return $query_string; +}; + +/* ==================================================================== */ + +function FormManager_WindowManagerExample() { + } + +FormManager_WindowManagerExample.prototype.init = function ($window_scope, $context) { + throw 'FormManager_WindowManagerExample: Please use other window manager.'; +}; + +FormManager_WindowManagerExample.prototype.open = function ($url, $width, $height, $source_form) { + +}; + +FormManager_WindowManagerExample.prototype.getDefaultOptions = function ($url, $width, $height) { + +}; + +FormManager_WindowManagerExample.prototype.close = function () { + +}; + +FormManager_WindowManagerExample.prototype.getContentSelector = function () { + +}; + +/* ==================================================================== */ + +function FormManager_WindowManagerThickBox() { + this.lastWindowScope = ''; +} + +FormManager_WindowManagerThickBox.prototype.init = function ($window_scope, $context) { + var $me = this; + + $(this.getWindowScope($window_scope), $context).click(function ($e) { + var $options = $me.getDefaultOptions(this.href || this.alt); + + $.extend($options, { + caption: this.title || this.name || null, + imageGroup: this.rel || false + }); + + TB.show($options); + this.blur(); + + $e.preventDefault(); + }); +}; + +FormManager_WindowManagerThickBox.prototype.getWindowScope = function ($window_scope) { + if ( $window_scope !== undefined ) { + this.lastWindowScope = $window_scope; + + return $window_scope; + } + + return this.lastWindowScope; +}; + +FormManager_WindowManagerThickBox.prototype.open = function ($url, $width, $height, $source_form) { + $url += ($url.indexOf('?') == -1 ? '?' : '&') + 'width=' + $width + '&height=' + $height + '&modal=true'; + + var $options = this.getDefaultOptions($url, $width, $height); + + if ( $source_form !== undefined ) { + $options.postParams = $($source_form).serialize(); + } + + TB.show($options); +}; + +FormManager_WindowManagerThickBox.prototype.getDefaultOptions = function ($url, $width, $height) { + var $me = this; + + return { + url: $url, + onAfterShow: function () { + $me.init(undefined, $me.getContentSelector()); + + // document.ready equivalent for ajax loaded windows + $(document).trigger('FormManager.WindowManager.Ready'); + } + }; +}; + +FormManager_WindowManagerThickBox.prototype.close = function () { + TB.remove(); +}; + +FormManager_WindowManagerThickBox.prototype.getContentSelector = function () { + return '#TB_ajaxContent'; +}; + +/* ==================================================================== */ + +function FormManager_WindowManagerColorBox() { + this.lastWindowScope = ''; +} + +FormManager_WindowManagerColorBox.prototype.init = function ($window_scope, $context) { + var $me = this; + + $(this.getWindowScope($window_scope), $context).each(function () { + var $url = this.href || this.alt, + $query_string = FormManager.parseQueryString($url), + $options = $me.getDefaultOptions( + this.href || this.alt, + $query_string['width'] !== undefined ? $query_string['width'] : false, + $query_string['height'] !== undefined ? $query_string['height'] : false + ); + + $.extend($options, { + title: this.title || this.name || false + }); + + $(this).colorbox($options); + }); +}; + +FormManager_WindowManagerColorBox.prototype.getWindowScope = function ($window_scope) { + if ( $window_scope !== undefined ) { + this.lastWindowScope = $window_scope; + + return $window_scope; + } + + return this.lastWindowScope; +}; + +FormManager_WindowManagerColorBox.prototype.open = function ($url, $width, $height, $source_form) { + var $options = this.getDefaultOptions($url, $width, $height); + + $.extend($options, { + // modal analog + escKey: false, + overlayClose: false + }); + + if ( $source_form !== undefined ) { + $options.data = $($source_form).serialize(); + } + + $.colorbox($options); +}; + +FormManager_WindowManagerColorBox.prototype.getDefaultOptions = function ($url, $width, $height) { + var $me = this; + + return { + href: $url, + + innerWidth: $width, + innerHeight: $height, + + onComplete: function () { + $me.init(undefined, $me.getContentSelector()); + + // document.ready equivalent for ajax loaded windows + $(document).trigger('FormManager.WindowManager.Ready'); + } + }; +}; + +FormManager_WindowManagerColorBox.prototype.close = function () { + $.colorbox.close(); +}; + +FormManager_WindowManagerColorBox.prototype.getContentSelector = function () { + return '#cboxLoadedContent'; +}; + +/* ==================================================================== */ + +function FormManager_WindowManagerFancyBox() { + this.lastWindowScope = ''; +} + +FormManager_WindowManagerFancyBox.prototype.init = function ($window_scope, $context) { + var $me = this; + + $(this.getWindowScope($window_scope), $context).each(function () { + var $url = this.href || this.alt, + $query_string = FormManager.parseQueryString($url), + $options = $me.getDefaultOptions( + $url, + $query_string['width'] !== undefined ? $query_string['width'] : false, + $query_string['height'] !== undefined ? $query_string['height'] : false + ); + + $.extend($options, { + title: this.title || this.name || false + }); + + $(this).fancybox($options); + }); +}; + +FormManager_WindowManagerFancyBox.prototype.getWindowScope = function ($window_scope) { + if ( $window_scope !== undefined ) { + this.lastWindowScope = $window_scope; + + return $window_scope; + } + + return this.lastWindowScope; +}; + +FormManager_WindowManagerFancyBox.prototype.open = function ($url, $width, $height, $source_form) { + var $options = this.getDefaultOptions($url, $width, $height); + + $.extend($options, { + modal: true + }); + + if ($source_form !== undefined) { + $options['ajax'] = { + data: $($source_form).serialize() + }; + } + + $.fancybox.open($options); +}; + +FormManager_WindowManagerFancyBox.prototype.getDefaultOptions = function ($url, $width, $height) { + var $me = this; + + return { + href: $url, + type : $.fancybox.isImage($url) ? 'image' : 'ajax', + + width: $width, + height: $height, + autoSize: false, + + afterShow: function () { + $me.init(undefined, $me.getContentSelector()); + + // document.ready equivalent for ajax loaded windows + $(document).trigger('FormManager.WindowManager.Ready'); + } + }; +}; + +FormManager_WindowManagerFancyBox.prototype.close = function () { + $.fancybox.close(); +}; + +FormManager_WindowManagerFancyBox.prototype.getContentSelector = function () { + return '.fancybox-inner'; +};