Вход Регистрация
Файл: framework/admin/javascript/LeftAndMain.EditForm.js
Строк: 565
<?php
/**
 * File: LeftAndMain.EditForm.js
 */
(function($) {
    
    
// Can't bind this through jQuery
    
window.onbeforeunload = function(e) {
        var 
form = $('.cms-edit-form');
        
form.trigger('beforesubmitform');
        if(
form.is('.changed')) return ss.i18n._t('LeftAndMain.CONFIRMUNSAVEDSHORT');
    };

    $.
entwine('ss', function($){

        
/**
         * Class: .cms-edit-form
         * 
         * Base edit form, provides ajaxified saving
         * and reloading itself through the ajax return values.
         * Takes care of resizing tabsets within the layout container.
         *
         * Change tracking is enabled on all fields within the form. If you want
         * to disable change tracking for a specific field, add a "no-change-track"
         * class to it.
         *
         * @name ss.Form_EditForm
         * @require jquery.changetracker
         * 
         * Events:
         *  ajaxsubmit - Form is about to be submitted through ajax
         *  validate - Contains validation result
         *  load - Form is about to be loaded through ajax
         */
        
$('.cms-edit-form').entwine(/** @lends ss.Form_EditForm */{    
            
/**
             * Variable: PlaceholderHtml
             * (String_ HTML text to show when no form content is chosen.
             * Will show inside the <form> tag.
             */
            
PlaceholderHtml'',
        
            
/**
             * Variable: ChangeTrackerOptions
             * (Object)
             */
            
ChangeTrackerOptions: {
                
ignoreFieldSelector'.no-change-track, .ss-upload :input, .cms-navigator :input'
            
},
        
            
/**
             * Constructor: onmatch
             */
            
onadd: function() {
                var 
self this;

                
// Turn off autocomplete to fix the access tab randomly switching radio buttons in Firefox
                // when refresh the page with an anchor tag in the URL. E.g: /admin#Root_Access.
                // Autocomplete in the CMS also causes strangeness in other browsers,
                // filling out sections of the form that the user does not want to be filled out,
                // so this turns it off for all browsers.
                // See the following page for demo and explanation of the Firefox bug:
                //  http://www.ryancramer.com/journal/entries/radio_buttons_firefox/
                
this.attr("autocomplete""off");
            
                
this._setupChangeTracker();

                
// Catch navigation events before they reach handleStateChange(),
                // in order to avoid changing the menu state if the action is cancelled by the user
                // $('.cms-menu')
                
                // Optionally get the form attributes from embedded fields, see Form->formHtmlContent()
                
for(var overrideAttr in {'action':true,'method':true,'enctype':true,'name':true}) {
                    var 
el this.find(':input[name=''_form_' overrideAttr ']');
                    if(
el) {
                        
this.attr(overrideAttrel.val());
                        
el.remove();
                    }
                }

                
// TODO
                // // Rewrite # links
                // html = html.replace(/(<a[^>]+href *= *")#/g, '$1' + window.location.href.replace(/#.*$/,'') + '#');
                // 
                // // Rewrite iframe links (for IE)
                // html = html.replace(/(<iframe[^>]*src=")([^"]+)("[^>]*>)/g, '$1' + $('base').attr('href') + '$2$3');
                
                // Show validation errors if necessary
                
if(this.hasClass('validationerror')) {
                    
// Ensure the first validation error is visible
                    
var tabError this.find('.message.validation, .message.required').first().closest('.tab');
                    $(
'.cms-container').clearCurrentTabState(); // clear state to avoid override later on
                    
tabError.closest('.ss-tabset').tabs('option''active'tabError.index('.tab'));
                }

                
this._super();
            },
            
onremove: function() {
                
this.changetracker('destroy');
                
this._super();
            },
            
onmatch: function() {
                
this._super();
            },
            
onunmatch: function() {
                
this._super();
            },
            
redraw: function() {
                if(
window.debugconsole.log('redraw'this.attr('class'), this.get(0));
                
                
// Force initialization of tabsets to avoid layout glitches
                
this.add(this.find('.cms-tabset')).redrawTabs();
                
this.find('.cms-content-header').redraw();
            },

            
/**
             * Function: _setupChangeTracker
             */
            
_setupChangeTracker: function() {
                
// Don't bind any events here, as we dont replace the
                // full <form> tag by any ajax updates they won't automatically reapply
                
this.changetracker(this.getChangeTrackerOptions());
            },
        
            
/**
             * Function: confirmUnsavedChanges
             * 
             * Checks the jquery.changetracker plugin status for this form,
             * and asks the user for confirmation via a browser dialog if changes are detected.
             * Doesn't cancel any unload or form removal events, you'll need to implement this based on the return
             * value of this message.
             * 
             * If changes are confirmed for discard, the 'changed' flag is reset.
             * 
             * Returns:
             *  (Boolean) FALSE if the user wants to abort with changes present, TRUE if no changes are detected 
             *  or the user wants to discard them.
             */
            
confirmUnsavedChanges: function() {
                
this.trigger('beforesubmitform');
                if(!
this.is('.changed')) {
                    return 
true;
                }
                var 
confirmed confirm(ss.i18n._t('LeftAndMain.CONFIRMUNSAVED'));
                if(
confirmed) {
                    
// confirm discard changes
                    
this.removeClass('changed');
                }
                return 
confirmed;
            },

            
/**
             * Function: onsubmit
             * 
             * Suppress submission unless it is handled through ajaxSubmit().
             */
            
onsubmit: function(ebutton) {
                
// Only submit if a button is present.
                // This supressed submits from ENTER keys in input fields,
                // which means the browser auto-selects the first available form button.
                // This might be an unrelated button of the form field,
                // or a destructive action (if "save" is not available, or not on first position).
                
if(this.prop("target") != "_blank") {
                    if(
buttonthis.closest('.cms-container').submitForm(thisbutton);
                    return 
false;
                }
            },

            
/**
             * Function: validate
             * 
             * Hook in (optional) validation routines.
             * Currently clientside validation is not supported out of the box in the CMS.
             * 
             * Todo:
             *  Placeholder implementation
             * 
             * Returns:
             *  {boolean}
             */
            
validate: function() {
                var 
isValid true;
                
this.trigger('validate', {isValidisValid});
    
                return 
isValid;
            },
            
/*
             * Track focus on htmleditor fields
             */
            
'from .htmleditor': {
                
oneditorinit: function(e){
                    var 
self this,
                        
field = $(e.target).closest('.field.htmleditor'),
                        
editor field.find('textarea.htmleditor').getEditor().getInstance();

                    
// TinyMCE 4 will add a focus event, but for now, use click
                    
editor.onClick.add(function(e){
                        
self.saveFieldFocus(field.attr('id'));
                    });
                }
            },
            
/*
             * Track focus on inputs
             */
            
'from .cms-edit-form :input:not(:submit)': {
                
onclick: function(e){
                    
this.saveFieldFocus($(e.target).attr('id'));
                },
                
onfocus: function(e){
                    
this.saveFieldFocus($(e.target).attr('id'));
                }
            },
            
/*
             * Track focus on treedropdownfields. 
             */
            
'from .cms-edit-form .treedropdown *': {
                
onfocusin: function(e){
                    var 
field = $(e.target).closest('.field.treedropdown');
                    
this.saveFieldFocus(field.attr('id'));
                }
            },
            
/*
             * Track focus on chosen selects
             */
            
'from .cms-edit-form .dropdown .chzn-container a': {
                
onfocusin: function(e){
                    var 
field = $(e.target).closest('.field.dropdown');
                    
this.saveFieldFocus(field.attr('id'));
                }
            },
            
/*
             * Restore fields after tabs are restored
             */
            
'from .cms-container': {
                
ontabstaterestored: function(e){
                    
this.restoreFieldFocus();
                }
            },
            
/*
             * Saves focus in Window session storage so it that can be restored on page load
             */
            
saveFieldFocus: function(selected){
                if(
typeof(window.sessionStorage)=="undefined" || window.sessionStorage === null) return;
                
                var 
id = $(this).attr('id'),
                    
focusElements = [];

                
focusElements.push({
                    
id:id
                    
selected:selected
                
});

                if(
focusElements) {
                    try {
                        
window.sessionStorage.setItem(idJSON.stringify(focusElements));
                    } catch(
err) {
                        if (
err.code === DOMException.QUOTA_EXCEEDED_ERR && window.sessionStorage.length === 0) {
                            
// If this fails we ignore the error as the only issue is that it 
                            // does not remember the focus state.
                            // This is a Safari bug which happens when private browsing is enabled.
                            
return;
                        } else {
                            throw 
err;
                        }
                    }
                }
            },
            
/**
             * Set focus or window to previously saved fields.
             * Requires HTML5 sessionStorage support.
             *
             * Must follow tab restoration, as reliant on active tab
             */
            
restoreFieldFocus: function(){
                if(
typeof(window.sessionStorage)=="undefined" || window.sessionStorage === null) return;
            
                var 
self this,
                    
hasSessionStorage = (typeof(window.sessionStorage)!=="undefined" && window.sessionStorage),
                    
sessionData hasSessionStorage window.sessionStorage.getItem(this.attr('id')) : null,
                    
sessionStates sessionData JSON.parse(sessionData) : false,
                    
elementID,
                    
tabbed = (this.find('.ss-tabset').length !== 0),
                    
activeTab,
                    
elementTab,
                    
toggleComposite,
                    
scrollY;

                if(
hasSessionStorage && sessionStates.length 0){
                    $.
each(sessionStates, function(isessionState) {
                        if(
self.is('#' sessionState.id)){
                            
elementID = $('#' sessionState.selected);
                        }
                    });

                    
// If the element IDs saved in session states don't match up to anything in this particular form
                    // that probably means we haven't encountered this form yet, so focus on the first input
                    
if($(elementID).length 1){
                        
this.focusFirstInput();
                        return;
                    }

                    
activeTab = $(elementID).closest('.ss-tabset').find('.ui-tabs-nav .ui-tabs-active .ui-tabs-anchor').attr('id');
                    
elementTab  'tab-' + $(elementID).closest('.ss-tabset .ui-tabs-panel').attr('id');

                    
// Last focussed element differs to last selected tab, do nothing
                    
if(tabbed && elementTab !== activeTab){
                        return;
                    }

                    
toggleComposite = $(elementID).closest('.togglecomposite');

                    
//Reopen toggle fields
                    
if(toggleComposite.length 0){
                        
toggleComposite.accordion('activate'toggleComposite.find('.ui-accordion-header'));
                    }

                    
//Calculate position for scroll
                    
scrollY = $(elementID).position().top;

                    
//Fall back to nearest visible element if hidden (for select type fields)
                    
if(!$(elementID).is(':visible')){
                        
elementID '#' + $(elementID).closest('.field').attr('id');
                        
scrollY = $(elementID).position().top;
                    }

                    
//set focus to focus variable if element focusable
                    
$(elementID).focus();

                    
// Scroll fallback when element is not focusable
                    // Only scroll if element at least half way down window
                    
if(scrollY > $(window).height() / 2){
                        
self.find('.cms-content-fields').scrollTop(scrollY);
                    }
                
                } else {
                    
// If session storage is not supported or there is nothing stored yet, focus on the first input 
                    
this.focusFirstInput();
                }
            },
            
/**
             * Skip if an element in the form is already focused. Exclude elements which specifically
             * opt-out of this behaviour via "data-skip-autofocus". This opt-out is useful if the
             * first visible field is shown far down a scrollable area, for example for the pagination
             * input field after a long GridField listing.
             */
            
focusFirstInput: function() {
                
this.find(':input:not(:submit)[data-skip-autofocus!="true"]').filter(':visible:first').focus();
            }
        });

        
/**
         * Class: .cms-edit-form .Actions :submit
         * 
         * All buttons in the right CMS form go through here by default.
         * We need this onclick overloading because we can't get to the
         * clicked button from a form.onsubmit event.
         */
        
$('.cms-edit-form .Actions input.action[type=submit], .cms-edit-form .Actions button.action').entwine({
            
/**
             * Function: onclick
             */
            
onclick: function(e) {
                
// Confirmation on delete. 
                
if(
                    
this.hasClass('gridfield-button-delete')
                    && !
confirm(ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE'))
                ) {
                    
e.preventDefault();
                    return 
false;
                }

                if(!
this.is(':disabled')) {
                    
this.parents('form').trigger('submit', [this]);
                }
                
e.preventDefault();
                return 
false;
            }
        });

        
/**
         * If we've a history state to go back to, go back, otherwise fall back to
         * submitting the form with the 'doCancel' action.
         */
        
$('.cms-edit-form .Actions input.action[type=submit].ss-ui-action-cancel, .cms-edit-form .Actions button.action.ss-ui-action-cancel').entwine({
            
onclick: function(e) {
                if (
History.getStateByIndex(1)) {
                    
History.back();
                } else {
                    
this.parents('form').trigger('submit', [this]);
                }
                
e.preventDefault();
            }
        });

        
/**
         * Hide tabs when only one is available.
         * Special case is actiontabs - tabs between buttons, where we want to have
         * extra options hidden within a tab (even if only one) by default.
         */
        
$('.cms-edit-form .ss-tabset').entwine({
            
onmatch: function() {
                if (!
this.hasClass('ss-ui-action-tabset')) {
                    var 
tabs this.find("> ul:first");

                    if(
tabs.children("li").length == 1) {
                        
tabs.hide().parent().addClass("ss-tabset-tabshidden");
                    }
                }

                
this._super();
            },
            
onunmatch: function() {
                
this._super();
            }
        });

    });

}(
jQuery));
?>
Онлайн: 0
Реклама