diff --git a/javascript/dist/AssetAdmin.js b/javascript/dist/AssetAdmin.js index 9b24d794..fdbfe43c 100644 --- a/javascript/dist/AssetAdmin.js +++ b/javascript/dist/AssetAdmin.js @@ -23,17 +23,45 @@ }; } + /** + * File: AssetAdmin.js + */ + _jQuery2.default.entwine('ss', function ($) { + /** + * Delete selected folders through "batch actions" tab. + */ + /* assets don't currently have batch actions; disabling for now + $(document).ready(function() { + $('#Form_BatchActionsForm').entwine('.ss.tree').register( + // TODO Hardcoding of base URL + 'admin/assets/batchactions/delete', + function(ids) { + var confirmed = confirm( + i18n.sprintf( + i18n._t('AssetAdmin.BATCHACTIONSDELETECONFIRM'), + ids.length + ) + ); + return (confirmed) ? ids : false; + } + ); + }); + */ + + /** + * Load folder detail view via controller methods + * rather than built-in GridField view (which is only geared towards showing files). + */ $('.AssetAdmin.cms-edit-form .ss-gridfield-item').entwine({ onclick: function onclick(e) { + // Let actions do their own thing if ($(e.target).closest('.action').length) { this._super(e); - return; } var grid = this.closest('.ss-gridfield'); - if (this.data('class') == 'Folder') { var url = grid.data('urlFolderTemplate').replace('%s', this.data('id')); $('.cms-container').loadPanel(url); @@ -43,41 +71,56 @@ this._super(e); } }); + $('.AssetAdmin.cms-edit-form .ss-gridfield .col-buttons .action.gridfield-button-delete, .AssetAdmin.cms-edit-form .Actions button.action.action-delete').entwine({ onclick: function onclick(e) { var msg; - if (this.closest('.ss-gridfield-item').data('class') == 'Folder') { msg = _i18n2.default._t('AssetAdmin.ConfirmDelete'); } else { msg = _i18n2.default._t('TABLEFIELD.DELETECONFIRMMESSAGE'); } - if (!confirm(msg)) return false; - this.getGridField().reload({ - data: [{ - name: this.attr('name'), - value: this.val() - }] - }); + + this.getGridField().reload({ data: [{ name: this.attr('name'), value: this.val() }] }); e.preventDefault(); return false; } }); + $('.AssetAdmin.cms-edit-form :submit[name=action_delete]').entwine({ onclick: function onclick(e) { if (!confirm(_i18n2.default._t('AssetAdmin.ConfirmDelete'))) return false;else this._super(e); } }); + + /** + * Prompt for a new foldername, rather than using dedicated form. + * Better usability, but less flexibility in terms of inputs and validation. + * Mainly necessary because AssetAdmin->AddForm() returns don't play nicely + * with the nested AssetAdmin->EditForm() DOM structures. + */ $('.AssetAdmin .cms-add-folder-link').entwine({ onclick: function onclick(e) { var name = prompt(_i18n2.default._t('Folder.Name')); if (!name) return false; + this.closest('.cms-container').loadPanel(this.data('url') + '&Name=' + name); return false; } }); + + /** + * Class: #Form_SyncForm + */ $('#Form_SyncForm').entwine({ + + /** + * Function: onsubmit + * + * Parameters: + * (Event) e + */ onsubmit: function onsubmit(e) { var button = jQuery(this).find(':submit:first'); button.addClass('loading'); @@ -86,27 +129,32 @@ data: this.serializeArray(), success: function success() { button.removeClass('loading'); + // reload current form and tree var currNode = $('.cms-tree')[0].firstSelected(); - if (currNode) { var url = $(currNode).find('a').attr('href'); $('.cms-content').loadPanel(url); } - $('.cms-tree')[0].setCustomURL('admin/assets/getsubtree'); - $('.cms-tree')[0].reload({ - onSuccess: function onSuccess() {} - }); + $('.cms-tree')[0].reload({ onSuccess: function onSuccess() { + // TODO Reset current tree node + } }); } }); + return false; } }); + + /** + * Reload the gridfield to show the user the file has been added + */ $('.AssetAdmin.cms-edit-form .ss-uploadfield-item-progress').entwine({ onunmatch: function onunmatch() { $('.AssetAdmin.cms-edit-form .ss-gridfield').reload(); } }); + $('.AssetAdmin .grid-levelup').entwine({ onmatch: function onmatch() { this.closest('.ui-tabs-panel').find('.cms-actions-row').prepend(this); diff --git a/javascript/dist/CMSMain.AddForm.js b/javascript/dist/CMSMain.AddForm.js index cbf76958..25cae0a7 100644 --- a/javascript/dist/CMSMain.AddForm.js +++ b/javascript/dist/CMSMain.AddForm.js @@ -22,6 +22,10 @@ } _jQuery2.default.entwine('ss', function ($) { + /** + * Reset the parent node selection if the type is + * set back to "toplevel page", to avoid submitting inconsistent state. + */ $(".cms-add-form .parent-mode :input").entwine({ onclick: function onclick(e) { if (this.val() == 'top') { @@ -31,9 +35,10 @@ } } }); + $(".cms-add-form").entwine({ - ParentID: 0, - ParentCache: {}, + ParentID: 0, // Last selected parentID + ParentCache: {}, // Cache allowed children for each selected page onadd: function onadd() { var self = this; this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField').bind('change', function () { @@ -53,6 +58,12 @@ cache[parentID] = children; this.setParentCache(cache); }, + /** + * Limit page type selection based on parent selection. + * Select of root classes is pre-computed, but selections with a given parent + * are updated on-demand. + * Similar implementation to LeftAndMain.Tree.js. + */ updateTypeList: function updateTypeList() { var hints = this.data('hints'), parentTree = this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField'), @@ -67,24 +78,26 @@ disallowedChildren = []; if (id) { + // Prevent interface operations if (this.hasClass('loading')) return; this.addClass('loading'); + + // Enable last parent ID to be re-selected from memory this.setParentID(id); if (!parentTree.getValue()) parentTree.setValue(id); - disallowedChildren = this.loadCachedChildren(id); + // Use cached data if available + disallowedChildren = this.loadCachedChildren(id); if (disallowedChildren !== null) { this.updateSelectionFilter(disallowedChildren, defaultChildClass); this.removeClass('loading'); return; } - $.ajax({ url: self.data('childfilter'), - data: { - 'ParentID': id - }, + data: { 'ParentID': id }, success: function success(data) { + // reload current form and tree self.saveCachedChildren(id, data); self.updateSelectionFilter(data, defaultChildClass); }, @@ -92,41 +105,53 @@ self.removeClass('loading'); } }); + return false; } else { disallowedChildren = hint && typeof hint.disallowedChildren !== 'undefined' ? hint.disallowedChildren : [], this.updateSelectionFilter(disallowedChildren, defaultChildClass); } }, + /** + * Update the selection filter with the given blacklist and default selection + * + * @param array disallowedChildren + * @param string defaultChildClass + */ updateSelectionFilter: function updateSelectionFilter(disallowedChildren, defaultChildClass) { - var allAllowed = null; + // Limit selection + var allAllowed = null; // troolian this.find('#Form_AddForm_PageType li').each(function () { var className = $(this).find('input').val(), isAllowed = $.inArray(className, disallowedChildren) === -1; + $(this).setEnabled(isAllowed); if (!isAllowed) $(this).setSelected(false); if (allAllowed === null) allAllowed = isAllowed;else allAllowed = allAllowed && isAllowed; }); + // Set default child selection, or fall back to first available option if (defaultChildClass) { var selectedEl = this.find('#Form_AddForm_PageType li input[value=' + defaultChildClass + ']').parents('li:first'); } else { var selectedEl = this.find('#Form_AddForm_PageType li:not(.disabled):first'); } - selectedEl.setSelected(true); selectedEl.siblings().setSelected(false); + + // Disable the "Create" button if none of the pagetypes are available var buttonState = this.find('#Form_AddForm_PageType li:not(.disabled)').length ? 'enable' : 'disable'; this.find('button[name=action_doAdd]').button(buttonState); + this.find('.message-restricted')[allAllowed ? 'hide' : 'show'](); } }); + $(".cms-add-form #Form_AddForm_PageType li").entwine({ onclick: function onclick(e) { this.setSelected(true); }, setSelected: function setSelected(bool) { var input = this.find('input'); - if (bool && !input.is(':disabled')) { this.siblings().setSelected(false); this.toggleClass('selected', true); @@ -141,12 +166,14 @@ if (!bool) $(this).find('input').attr('disabled', 'disabled').removeAttr('checked');else $(this).find('input').removeAttr('disabled'); } }); + $(".cms-page-add-button").entwine({ onclick: function onclick(e) { var tree = $('.cms-tree'), list = $('.cms-list'), parentId = 0; + // Choose parent ID either from tree or list view, depending which is visible if (tree.is(':visible')) { var selected = tree.jstree('get_selected'); parentId = selected ? $(selected[0]).data('id') : null; @@ -155,12 +182,8 @@ if (state) parentId = parseInt(JSON.parse(state).ParentID, 10); } - var data = { - selector: this.data('targetPanel'), - pjax: this.data('pjax') - }, + var data = { selector: this.data('targetPanel'), pjax: this.data('pjax') }, url; - if (parentId) { extraParams = this.data('extraParams') ? this.data('extraParams') : ''; url = $.path.addSearchParams(i18n.sprintf(this.data('urlAddpage'), parentId), extraParams); @@ -170,7 +193,12 @@ $('.cms-container').loadPanel(url, null, data); e.preventDefault(); + + // Remove focussed state from button this.blur(); + + // $('.cms-page-add-form-dialog').dialog('open'); + // e.preventDefault(); } }); }); diff --git a/javascript/dist/CMSMain.EditForm.js b/javascript/dist/CMSMain.EditForm.js index 050e879f..035d9935 100644 --- a/javascript/dist/CMSMain.EditForm.js +++ b/javascript/dist/CMSMain.EditForm.js @@ -23,28 +23,48 @@ }; } + /** + * File: CMSMain.EditForm.js + */ + + _jQuery2.default.entwine('ss', function ($) { + /** + * Class: .cms-edit-form :input[name=ClassName] + * Alert the user on change of page-type. This might have implications + * on the available form fields etc. + */ $('.cms-edit-form :input[name=ClassName]').entwine({ + // Function: onchange onchange: function onchange() { alert(_i18n2.default._t('CMSMAIN.ALERTCLASSNAME')); } }); + + /** + * Class: .cms-edit-form input[name=Title] + * + * Input validation on the Title field + */ $('.cms-edit-form input[name=Title]').entwine({ + // Constructor: onmatch onmatch: function onmatch() { var self = this; + self.data('OrigVal', self.val()); + var form = self.closest('form'); var urlSegmentInput = $('input:text[name=URLSegment]', form); var liveLinkInput = $('input[name=LiveLink]', form); if (urlSegmentInput.length > 0) { self._addActions(); - this.bind('change', function (e) { var origTitle = self.data('OrigVal'); var title = self.val(); self.data('OrigVal', title); + // Criteria for defining a "new" page if (urlSegmentInput.val().indexOf(urlSegmentInput.data('defaultUrl')) === 0 && liveLinkInput.val() == '') { self.updateURLSegment(title); } else { @@ -61,37 +81,67 @@ onunmatch: function onunmatch() { this._super(); }, + + /** + * Function: updateRelatedFields + * + * Update the related fields if appropriate + * (String) title The new title + * (Stirng) origTitle The original title + */ updateRelatedFields: function updateRelatedFields(title, origTitle) { + // Update these fields only if their value was originally the same as the title this.parents('form').find('input[name=MetaTitle], input[name=MenuTitle]').each(function () { var $this = $(this); - if ($this.val() == origTitle) { $this.val(title); + // Onchange bubbling didn't work in IE8, so .trigger('change') couldn't be used if ($this.updatedRelatedFields) $this.updatedRelatedFields(); } }); }, + + /** + * Function: updateURLSegment + * + * Update the URLSegment + * (String) title + */ updateURLSegment: function updateURLSegment(title) { var urlSegmentInput = $('input:text[name=URLSegment]', this.closest('form')); var urlSegmentField = urlSegmentInput.closest('.field.urlsegment'); var updateURLFromTitle = $('.update', this.parent()); urlSegmentField.update(title); - if (updateURLFromTitle.is(':visible')) { updateURLFromTitle.hide(); } }, + + /** + * Function: updateBreadcrumbLabel + * + * Update the breadcrumb + * (String) title + */ updateBreadcrumbLabel: function updateBreadcrumbLabel(title) { var pageID = $('.cms-edit-form input[name=ID]').val(); var panelCrumb = $('span.cms-panel-link.crumb'); - if (title && title != "") { panelCrumb.text(title); } }, + + /** + * Function: _addActions + * + * Utility to add update from title action + * + */ _addActions: function _addActions() { var self = this; var updateURLFromTitle; + + // update button updateURLFromTitle = $('