mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
BUGFIX: put all CMS JS code into 'ss' namespace.
Conflicts: admin/javascript/LeftAndMain.js javascript/GridField.js
This commit is contained in:
parent
3412a0e58d
commit
3d0876c8f5
@ -89,7 +89,7 @@
|
|||||||
data.push({name:button.attr('name'),value:button.val()});
|
data.push({name:button.attr('name'),value:button.val()});
|
||||||
|
|
||||||
// TODO Should be set by hiddenfield already
|
// TODO Should be set by hiddenfield already
|
||||||
jQuery('.cms-content').entwine('ss').submitForm(
|
jQuery('.cms-content').submitForm(
|
||||||
this.attr('action'),
|
this.attr('action'),
|
||||||
null,
|
null,
|
||||||
function() {
|
function() {
|
||||||
|
@ -282,83 +282,83 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class: #Form_BatchActionsForm :select[name=Action]
|
|
||||||
*/
|
|
||||||
$('#Form_BatchActionsForm select[name=Action]').entwine({
|
|
||||||
|
|
||||||
onmatch: function() {
|
|
||||||
this.trigger('change');
|
|
||||||
this._super();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: onchange
|
* Class: #Form_BatchActionsForm :select[name=Action]
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* (Event) e
|
|
||||||
*/
|
*/
|
||||||
onchange: function(e) {
|
$('#Form_BatchActionsForm select[name=Action]').entwine({
|
||||||
var form = $(e.target.form), btn = form.find(':submit');
|
|
||||||
if($(e.target).val() == -1) {
|
onmatch: function() {
|
||||||
btn.attr('disabled', 'disabled').button('refresh');
|
this.trigger('change');
|
||||||
} else {
|
this._super();
|
||||||
btn.removeAttr('disabled').button('refresh');
|
},
|
||||||
// form.submit();
|
|
||||||
|
/**
|
||||||
|
* Function: onchange
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (Event) e
|
||||||
|
*/
|
||||||
|
onchange: function(e) {
|
||||||
|
var form = $(e.target.form), btn = form.find(':submit');
|
||||||
|
if($(e.target).val() == -1) {
|
||||||
|
btn.attr('disabled', 'disabled').button('refresh');
|
||||||
|
} else {
|
||||||
|
btn.removeAttr('disabled').button('refresh');
|
||||||
|
// form.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Should work by triggering change() along, but doesn't - entwine event bubbling?
|
||||||
|
this.trigger("liszt:updated");
|
||||||
|
|
||||||
|
this._super(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Should work by triggering change() along, but doesn't - entwine event bubbling?
|
|
||||||
this.trigger("liszt:updated");
|
|
||||||
|
|
||||||
this._super(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
/**
|
|
||||||
* Publish selected pages action
|
|
||||||
*/
|
|
||||||
$('#Form_BatchActionsForm').entwine('ss').register('admin/batchactions/publish', function(ids) {
|
|
||||||
var confirmed = confirm(
|
|
||||||
"You have " + ids.length + " pages selected.\n\n"
|
|
||||||
+ "Do your really want to publish?"
|
|
||||||
);
|
|
||||||
return (confirmed) ? ids : false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
$(document).ready(function() {
|
||||||
* Unpublish selected pages action
|
/**
|
||||||
*/
|
* Publish selected pages action
|
||||||
$('#Form_BatchActionsForm').entwine('ss').register('admin/batchactions/unpublish', function(ids) {
|
*/
|
||||||
var confirmed = confirm(
|
$('#Form_BatchActionsForm').register('admin/batchactions/publish', function(ids) {
|
||||||
"You have " + ids.length + " pages selected.\n\n"
|
var confirmed = confirm(
|
||||||
+ "Do your really want to unpublish?"
|
"You have " + ids.length + " pages selected.\n\n"
|
||||||
);
|
+ "Do your really want to publish?"
|
||||||
return (confirmed) ? ids : false;
|
);
|
||||||
});
|
return (confirmed) ? ids : false;
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete selected pages action
|
* Unpublish selected pages action
|
||||||
*/
|
*/
|
||||||
$('#Form_BatchActionsForm').entwine('ss').register('admin/batchactions/delete', function(ids) {
|
$('#Form_BatchActionsForm').register('admin/batchactions/unpublish', function(ids) {
|
||||||
var confirmed = confirm(
|
var confirmed = confirm(
|
||||||
"You have " + ids.length + " pages selected.\n\n"
|
"You have " + ids.length + " pages selected.\n\n"
|
||||||
+ "Do your really want to delete?"
|
+ "Do your really want to unpublish?"
|
||||||
);
|
);
|
||||||
return (confirmed) ? ids : false;
|
return (confirmed) ? ids : false;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete selected pages from live action
|
* Delete selected pages action
|
||||||
*/
|
*/
|
||||||
$('#Form_BatchActionsForm').entwine('ss').register('admin/batchactions/deletefromlive', function(ids) {
|
$('#Form_BatchActionsForm').register('admin/batchactions/delete', function(ids) {
|
||||||
var confirmed = confirm(
|
var confirmed = confirm(
|
||||||
"You have " + ids.length + " pages selected.\n\n"
|
"You have " + ids.length + " pages selected.\n\n"
|
||||||
+ "Do your really want to delete these pages from live?"
|
+ "Do your really want to delete?"
|
||||||
);
|
);
|
||||||
return (confirmed) ? ids : false;
|
return (confirmed) ? ids : false;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete selected pages from live action
|
||||||
|
*/
|
||||||
|
$('#Form_BatchActionsForm').register('admin/batchactions/deletefromlive', function(ids) {
|
||||||
|
var confirmed = confirm(
|
||||||
|
"You have " + ids.length + " pages selected.\n\n"
|
||||||
|
+ "Do your really want to delete these pages from live?"
|
||||||
|
);
|
||||||
|
return (confirmed) ? ids : false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -185,60 +185,60 @@
|
|||||||
this.removeClass('changed');
|
this.removeClass('changed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load edit form for the selected node when its clicked.
|
* Load edit form for the selected node when its clicked.
|
||||||
*/
|
*/
|
||||||
$('.cms-content .cms-tree').entwine({
|
$('.cms-content .cms-tree').entwine({
|
||||||
onmatch: function() {
|
onmatch: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
this.bind('select_node.jstree', function(e, data) {
|
this.bind('select_node.jstree', function(e, data) {
|
||||||
var node = data.rslt.obj, loadedNodeID = self.find(':input[name=ID]').val(), origEvent = data.args[2], container = $('.cms-container');
|
var node = data.rslt.obj, loadedNodeID = self.find(':input[name=ID]').val(), origEvent = data.args[2], container = $('.cms-container');
|
||||||
|
|
||||||
// Don't trigger unless coming from a click event.
|
// Don't trigger unless coming from a click event.
|
||||||
// Avoids problems with automated section switches from tree to detail view
|
// Avoids problems with automated section switches from tree to detail view
|
||||||
// when JSTree auto-selects elements on first load.
|
// when JSTree auto-selects elements on first load.
|
||||||
if(!origEvent) {
|
if(!origEvent) {
|
||||||
return false;
|
return false;
|
||||||
}else if($(origEvent.target).hasClass('jstree-icon') || $(origEvent.target).hasClass('jstree-pageicon')){
|
}else if($(origEvent.target).hasClass('jstree-icon') || $(origEvent.target).hasClass('jstree-pageicon')){
|
||||||
// in case the click is not on the node title, ie on pageicon or dragicon,
|
// in case the click is not on the node title, ie on pageicon or dragicon,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow checking disabled nodes
|
// Don't allow checking disabled nodes
|
||||||
if($(node).hasClass('disabled')) return false;
|
if($(node).hasClass('disabled')) return false;
|
||||||
|
|
||||||
// Don't allow reloading of currently selected node,
|
// Don't allow reloading of currently selected node,
|
||||||
// mainly to avoid doing an ajax request on initial page load
|
// mainly to avoid doing an ajax request on initial page load
|
||||||
if($(node).data('id') == loadedNodeID) return;
|
if($(node).data('id') == loadedNodeID) return;
|
||||||
|
|
||||||
var url = $(node).find('a:first').attr('href');
|
var url = $(node).find('a:first').attr('href');
|
||||||
if(url && url != '#') {
|
if(url && url != '#') {
|
||||||
|
|
||||||
// Ensure URL is absolute (important for IE)
|
// Ensure URL is absolute (important for IE)
|
||||||
if($.path.isExternal($(node).find('a:first'))) url = url = $.path.makeUrlAbsolute(url, $('base').attr('href'));
|
if($.path.isExternal($(node).find('a:first'))) url = url = $.path.makeUrlAbsolute(url, $('base').attr('href'));
|
||||||
// Retain search parameters
|
// Retain search parameters
|
||||||
if(document.location.search) url = $.path.addSearchParams(url, document.location.search.replace(/^\?/, ''));
|
if(document.location.search) url = $.path.addSearchParams(url, document.location.search.replace(/^\?/, ''));
|
||||||
// Load new page
|
// Load new page
|
||||||
container.entwine('ss').loadPanel(url);
|
container.loadPanel(url);
|
||||||
} else {
|
} else {
|
||||||
self.removeForm();
|
self.removeForm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.cms-content.loading,.cms-edit-form.loading,.cms-content-fields.loading,.cms-content-view.loading').entwine({
|
$('.cms-content.loading,.cms-edit-form.loading,.cms-content-fields.loading,.cms-content-view.loading').entwine({
|
||||||
onmatch: function() {
|
onmatch: function() {
|
||||||
this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>');
|
this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>');
|
||||||
},
|
},
|
||||||
onunmatch: function() {
|
onunmatch: function() {
|
||||||
this.find('.cms-content-loading-overlay,.cms-content-loading-spinner').remove();
|
this.find('.cms-content-loading-overlay,.cms-content-loading-spinner').remove();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
@ -420,36 +420,36 @@ jQuery.noConflict();
|
|||||||
* Add styling to all contained buttons, and create buttonsets if required.
|
* Add styling to all contained buttons, and create buttonsets if required.
|
||||||
*/
|
*/
|
||||||
$('.cms .Actions').entwine({
|
$('.cms .Actions').entwine({
|
||||||
onmatch: function() {
|
onmatch: function() {
|
||||||
this.find('.ss-ui-button').click(function() {
|
this.find('.ss-ui-button').click(function() {
|
||||||
var form = this.form;
|
var form = this.form;
|
||||||
// forms don't natively store the button they've been triggered with
|
// forms don't natively store the button they've been triggered with
|
||||||
if(form) {
|
if(form) {
|
||||||
form.clickedButton = this;
|
form.clickedButton = this;
|
||||||
// Reset the clicked button shortly after the onsubmit handlers
|
// Reset the clicked button shortly after the onsubmit handlers
|
||||||
// have fired on the form
|
// have fired on the form
|
||||||
setTimeout(function() {form.clickedButton = null;}, 10);
|
setTimeout(function() {form.clickedButton = null;}, 10);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.redraw();
|
||||||
|
this._super();
|
||||||
|
},
|
||||||
|
redraw: function() {
|
||||||
|
// Remove whitespace to avoid gaps with inline elements
|
||||||
|
this.contents().filter(function() {
|
||||||
|
return (this.nodeType == 3 && !/\S/.test(this.nodeValue));
|
||||||
|
}).remove();
|
||||||
|
|
||||||
|
// Init buttons if required
|
||||||
|
this.find('.ss-ui-button').each(function() {
|
||||||
|
if(!$(this).data('button')) $(this).button();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.redraw();
|
// Mark up buttonsets
|
||||||
this._super();
|
this.find('.ss-ui-buttonset').buttonset();
|
||||||
},
|
}
|
||||||
redraw: function() {
|
});
|
||||||
// Remove whitespace to avoid gaps with inline elements
|
|
||||||
this.contents().filter(function() {
|
|
||||||
return (this.nodeType == 3 && !/\S/.test(this.nodeValue));
|
|
||||||
}).remove();
|
|
||||||
|
|
||||||
// Init buttons if required
|
|
||||||
this.find('.ss-ui-button').each(function() {
|
|
||||||
if(!$(this).data('button')) $(this).button();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Mark up buttonsets
|
|
||||||
this.find('.ss-ui-buttonset').buttonset();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicates functionality in DateField.js, but due to using entwine we can match
|
* Duplicates functionality in DateField.js, but due to using entwine we can match
|
||||||
@ -508,166 +508,166 @@ jQuery.noConflict();
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overload the default GridField behaviour (open a new URL in the browser)
|
|
||||||
* with the CMS-specific ajax loading.
|
|
||||||
*/
|
|
||||||
$('.cms .ss-gridfield').entwine({
|
|
||||||
showDetailView: function(url) {
|
|
||||||
// Include any GET parameters from the current URL, as the view state might depend on it.
|
|
||||||
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
|
||||||
if(window.location.search) url += window.location.search;
|
|
||||||
$('.cms-container').entwine('ss').loadPanel(url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic search form in the CMS, often hooked up to a GridField results display.
|
|
||||||
*/
|
|
||||||
$('.cms-search-form').entwine({
|
|
||||||
|
|
||||||
onsubmit: function() {
|
|
||||||
// Remove empty elements and make the URL prettier
|
|
||||||
var nonEmptyInputs = this.find(':input:not(:submit)').filter(function() {
|
|
||||||
// Use fieldValue() from jQuery.form plugin rather than jQuery.val(),
|
|
||||||
// as it handles checkbox values more consistently
|
|
||||||
var vals = $.grep($(this).fieldValue(), function(val) { return (val);});
|
|
||||||
return (vals.length);
|
|
||||||
});
|
|
||||||
var url = this.attr('action');
|
|
||||||
if(nonEmptyInputs.length) url = $.path.addSearchParams(url, nonEmptyInputs.serialize());
|
|
||||||
|
|
||||||
var container = this.closest('.cms-container');
|
|
||||||
container.find('.cms-edit-form').tabs('select',0); //always switch to the first tab (list view) when searching
|
|
||||||
container .entwine('ss').loadPanel(url);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets are processed on the serverside, so need to trigger a submit.
|
* Overload the default GridField behaviour (open a new URL in the browser)
|
||||||
|
* with the CMS-specific ajax loading.
|
||||||
*/
|
*/
|
||||||
onreset: function(e) {
|
$('.cms .ss-gridfield').entwine({
|
||||||
this.clearForm();
|
showDetailView: function(url) {
|
||||||
this.submit();
|
// Include any GET parameters from the current URL, as the view state might depend on it.
|
||||||
}
|
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
||||||
|
if(window.location.search) url += window.location.search;
|
||||||
|
$('.cms-container').loadPanel(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple toggle link, which points to a DOm element by its ID selector
|
* Generic search form in the CMS, often hooked up to a GridField results display.
|
||||||
* in the href attribute (which doubles as an anchor link to that element).
|
*/
|
||||||
*/
|
$('.cms-search-form').entwine({
|
||||||
$('.cms .cms-help-toggle').entwine({
|
|
||||||
onmatch: function() {
|
|
||||||
this._super();
|
|
||||||
|
|
||||||
$(this.attr('href')).hide();
|
onsubmit: function() {
|
||||||
},
|
// Remove empty elements and make the URL prettier
|
||||||
onclick: function(e) {
|
var nonEmptyInputs = this.find(':input:not(:submit)').filter(function() {
|
||||||
$(this.attr('href')).toggle();
|
// Use fieldValue() from jQuery.form plugin rather than jQuery.val(),
|
||||||
e.preventDefault();
|
// as it handles checkbox values more consistently
|
||||||
}
|
var vals = $.grep($(this).fieldValue(), function(val) { return (val);});
|
||||||
});
|
return (vals.length);
|
||||||
|
});
|
||||||
|
var url = this.attr('action');
|
||||||
|
if(nonEmptyInputs.length) url = $.path.addSearchParams(url, nonEmptyInputs.serialize());
|
||||||
|
|
||||||
/**
|
var container = this.closest('.cms-container');
|
||||||
* Allows to lazy load a panel, by leaving it empty
|
container.find('.cms-edit-form').tabs('select',0); //always switch to the first tab (list view) when searching
|
||||||
* and declaring a URL to load its content via a 'url' HTML5 data attribute.
|
container.loadPanel(url);
|
||||||
* The loaded HTML is cached, with cache key being the 'url' attribute.
|
return false;
|
||||||
* In order for this to work consistently, we assume that the responses are stateless.
|
},
|
||||||
* To avoid caching, add a 'deferred-no-cache' to the node.
|
|
||||||
*/
|
|
||||||
window._panelDeferredCache = {};
|
|
||||||
$('.cms-panel-deferred').entwine({
|
|
||||||
onmatch: function() {
|
|
||||||
this._super();
|
|
||||||
this.redraw();
|
|
||||||
},
|
|
||||||
onunmatch: function() {
|
|
||||||
// Save the HTML state at the last possible moment.
|
|
||||||
// Don't store the DOM to avoid memory leaks.
|
|
||||||
if(!this.data('deferredNoCache')) window._panelDeferredCache[this.data('url')] = this.html();
|
|
||||||
this._super();
|
|
||||||
},
|
|
||||||
redraw: function() {
|
|
||||||
var self = this, url = this.data('url');
|
|
||||||
if(!url) throw 'Elements of class .cms-panel-deferred need a "data-url" attribute';
|
|
||||||
|
|
||||||
this._super();
|
/**
|
||||||
|
* Resets are processed on the serverside, so need to trigger a submit.
|
||||||
|
*/
|
||||||
|
onreset: function(e) {
|
||||||
|
this.clearForm();
|
||||||
|
this.submit();
|
||||||
|
}
|
||||||
|
|
||||||
// If the node is empty, try to either load it from cache or via ajax.
|
});
|
||||||
if(!this.children().length) {
|
|
||||||
if(!this.data('deferredNoCache') && typeof window._panelDeferredCache[url] !== 'undefined') {
|
/**
|
||||||
this.html(window._panelDeferredCache[url]);
|
* Simple toggle link, which points to a DOm element by its ID selector
|
||||||
} else {
|
* in the href attribute (which doubles as an anchor link to that element).
|
||||||
this.addClass('loading');
|
*/
|
||||||
$.ajax({
|
$('.cms .cms-help-toggle').entwine({
|
||||||
url: url,
|
onmatch: function() {
|
||||||
complete: function() {
|
this._super();
|
||||||
self.removeClass('loading');
|
|
||||||
},
|
$(this.attr('href')).hide();
|
||||||
success: function(data, status, xhr) {
|
},
|
||||||
self.html(data);
|
onclick: function(e) {
|
||||||
}
|
$(this.attr('href')).toggle();
|
||||||
});
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to lazy load a panel, by leaving it empty
|
||||||
|
* and declaring a URL to load its content via a 'url' HTML5 data attribute.
|
||||||
|
* The loaded HTML is cached, with cache key being the 'url' attribute.
|
||||||
|
* In order for this to work consistently, we assume that the responses are stateless.
|
||||||
|
* To avoid caching, add a 'deferred-no-cache' to the node.
|
||||||
|
*/
|
||||||
|
window._panelDeferredCache = {};
|
||||||
|
$('.cms-panel-deferred').entwine({
|
||||||
|
onmatch: function() {
|
||||||
|
this._super();
|
||||||
|
this.redraw();
|
||||||
|
},
|
||||||
|
onunmatch: function() {
|
||||||
|
// Save the HTML state at the last possible moment.
|
||||||
|
// Don't store the DOM to avoid memory leaks.
|
||||||
|
if(!this.data('deferredNoCache')) window._panelDeferredCache[this.data('url')] = this.html();
|
||||||
|
this._super();
|
||||||
|
},
|
||||||
|
redraw: function() {
|
||||||
|
var self = this, url = this.data('url');
|
||||||
|
if(!url) throw 'Elements of class .cms-panel-deferred need a "data-url" attribute';
|
||||||
|
|
||||||
|
this._super();
|
||||||
|
|
||||||
|
// If the node is empty, try to either load it from cache or via ajax.
|
||||||
|
if(!this.children().length) {
|
||||||
|
if(!this.data('deferredNoCache') && typeof window._panelDeferredCache[url] !== 'undefined') {
|
||||||
|
this.html(window._panelDeferredCache[url]);
|
||||||
|
} else {
|
||||||
|
this.addClass('loading');
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
complete: function() {
|
||||||
|
self.removeClass('loading');
|
||||||
|
},
|
||||||
|
success: function(data, status, xhr) {
|
||||||
|
self.html(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lightweight wrapper around jQuery UI tabs.
|
|
||||||
* Ensures that anchor links are set properly,
|
|
||||||
* and any nested tabs are scrolled if they have
|
|
||||||
* their height explicitly set. This is important
|
|
||||||
* for forms inside the CMS layout.
|
|
||||||
*/
|
|
||||||
$('.cms-tabset').entwine({
|
|
||||||
onmatch: function() {
|
|
||||||
// Can't name redraw() as it clashes with other CMS entwine classes
|
|
||||||
this.redrawTabs();
|
|
||||||
this._super();
|
|
||||||
},
|
|
||||||
|
|
||||||
redrawTabs: function() {
|
|
||||||
this.rewriteHashlinks();
|
|
||||||
|
|
||||||
var id = this.attr('id'), cookieId = 'ui-tabs-' + id,
|
|
||||||
selectedTab = this.find('ul:first .ui-state-selected');
|
|
||||||
|
|
||||||
// Fix for wrong cookie storage of deselected tabs
|
|
||||||
if($.cookie && id && $.cookie(cookieId) == -1) $.cookie(cookieId, 0);
|
|
||||||
this.tabs({
|
|
||||||
cookie: ($.cookie && id) ? { expires: 30, path: '/', name: cookieId } : false,
|
|
||||||
ajaxOptions: {
|
|
||||||
// Overwrite ajax loading to use CMS logic instead
|
|
||||||
beforeSend: function(xhr, settings) {
|
|
||||||
var makeAbs = $.path.makeUrlAbsolute,
|
|
||||||
baseUrl = $('base').attr('href'),
|
|
||||||
isSame = (makeAbs(settings.url, baseUrl) == makeAbs(document.location.href));
|
|
||||||
|
|
||||||
if(!isSame) $('.cms-container').entwine('ss').loadPanel(settings.url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selected: (selectedTab.index() != -1) ? selectedTab.index() : 0
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace prefixes for all hashlinks in tabs.
|
* Lightweight wrapper around jQuery UI tabs.
|
||||||
* SSViewer rewrites them from "#Root_MyTab" to
|
* Ensures that anchor links are set properly,
|
||||||
* e.g. "/admin/#Root_MyTab" which makes them
|
* and any nested tabs are scrolled if they have
|
||||||
* unusable for jQuery UI.
|
* their height explicitly set. This is important
|
||||||
|
* for forms inside the CMS layout.
|
||||||
*/
|
*/
|
||||||
rewriteHashlinks: function() {
|
$('.cms-tabset').entwine({
|
||||||
$(this).find('ul a').each(function() {
|
onmatch: function() {
|
||||||
var href = $(this).attr('href').replace(/.*(#.*)/, '$1');
|
// Can't name redraw() as it clashes with other CMS entwine classes
|
||||||
if(href) $(this).attr('href', href);
|
this.redrawTabs();
|
||||||
});
|
this._super();
|
||||||
}
|
},
|
||||||
|
|
||||||
|
redrawTabs: function() {
|
||||||
|
this.rewriteHashlinks();
|
||||||
|
|
||||||
|
var id = this.attr('id'), cookieId = 'ui-tabs-' + id,
|
||||||
|
selectedTab = this.find('ul:first .ui-state-selected');
|
||||||
|
|
||||||
|
// Fix for wrong cookie storage of deselected tabs
|
||||||
|
if($.cookie && id && $.cookie(cookieId) == -1) $.cookie(cookieId, 0);
|
||||||
|
this.tabs({
|
||||||
|
cookie: ($.cookie && id) ? { expires: 30, path: '/', name: cookieId } : false,
|
||||||
|
ajaxOptions: {
|
||||||
|
// Overwrite ajax loading to use CMS logic instead
|
||||||
|
beforeSend: function(xhr, settings) {
|
||||||
|
var makeAbs = $.path.makeUrlAbsolute,
|
||||||
|
baseUrl = $('base').attr('href'),
|
||||||
|
isSame = (makeAbs(settings.url, baseUrl) == makeAbs(document.location.href));
|
||||||
|
|
||||||
|
if(!isSame) $('.cms-container').loadPanel(settings.url);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selected: (selectedTab.index() != -1) ? selectedTab.index() : 0
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace prefixes for all hashlinks in tabs.
|
||||||
|
* SSViewer rewrites them from "#Root_MyTab" to
|
||||||
|
* e.g. "/admin/#Root_MyTab" which makes them
|
||||||
|
* unusable for jQuery UI.
|
||||||
|
*/
|
||||||
|
rewriteHashlinks: function() {
|
||||||
|
$(this).find('ul a').each(function() {
|
||||||
|
var href = $(this).attr('href').replace(/.*(#.*)/, '$1');
|
||||||
|
if(href) $(this).attr('href', href);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}(jQuery));
|
}(jQuery));
|
||||||
|
@ -1,34 +1,36 @@
|
|||||||
(function($) {
|
(function($) {
|
||||||
|
|
||||||
/**
|
$.entwine('ss', function($) {
|
||||||
* Creates a jQuery UI tab navigation bar, detached from the container DOM structure.
|
/**
|
||||||
*/
|
* Creates a jQuery UI tab navigation bar, detached from the container DOM structure.
|
||||||
$('.ss-ui-tabs-nav').entwine({
|
*/
|
||||||
onmatch: function() {
|
$('.ss-ui-tabs-nav').entwine({
|
||||||
this.redraw();
|
onmatch: function() {
|
||||||
|
this.redraw();
|
||||||
|
|
||||||
this._super();
|
this._super();
|
||||||
},
|
},
|
||||||
|
|
||||||
redraw: function() {
|
redraw: function() {
|
||||||
this.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-panel ui-corner-bottom');
|
this.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-panel ui-corner-bottom');
|
||||||
this.find('ul').addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
|
this.find('ul').addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
|
||||||
this.find('li').addClass('ui-state-default ui-corner-top');
|
this.find('li').addClass('ui-state-default ui-corner-top');
|
||||||
// TODO Figure out selected tab
|
// TODO Figure out selected tab
|
||||||
var selected = this.find('li.current');
|
var selected = this.find('li.current');
|
||||||
if(!selected.length) selected = this.find('li:first');
|
if(!selected.length) selected = this.find('li:first');
|
||||||
selected.selectIt();
|
selected.selectIt();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.ss-ui-tabs-nav li').entwine({
|
$('.ss-ui-tabs-nav li').entwine({
|
||||||
onclick: function() {
|
onclick: function() {
|
||||||
this.selectIt();
|
this.selectIt();
|
||||||
},
|
},
|
||||||
selectIt: function() {
|
selectIt: function() {
|
||||||
var cls = 'ui-tabs-selected ui-state-active';
|
var cls = 'ui-tabs-selected ui-state-active';
|
||||||
this.addClass(cls).siblings().not(this).removeClass(cls);
|
this.addClass(cls).siblings().not(this).removeClass(cls);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,335 +1,338 @@
|
|||||||
(function($){
|
(function($){
|
||||||
|
|
||||||
$('.ss-gridfield').entwine({
|
$.entwine('ss', function($) {
|
||||||
/**
|
$('.ss-gridfield').entwine({
|
||||||
* @param {Object} Additional options for jQuery.ajax() call
|
/**
|
||||||
* @param {successCallback} callback to call after reloading succeeded.
|
* @param {Object} Additional options for jQuery.ajax() call
|
||||||
*/
|
* @param {successCallback} callback to call after reloading succeeded.
|
||||||
|
*/
|
||||||
|
|
||||||
reload: function(ajaxOpts, successCallback) {
|
reload: function(ajaxOpts, successCallback) {
|
||||||
var self = this, form = this.closest('form'),
|
var self = this, form = this.closest('form'),
|
||||||
focusedElName = this.find(':input:focus').attr('name'), // Save focused element for restoring after refresh
|
focusedElName = this.find(':input:focus').attr('name'), // Save focused element for restoring after refresh
|
||||||
data = form.find(':input').serializeArray();
|
data = form.find(':input').serializeArray();
|
||||||
|
|
||||||
if(!ajaxOpts) ajaxOpts = {};
|
if(!ajaxOpts) ajaxOpts = {};
|
||||||
if(!ajaxOpts.data) ajaxOpts.data = [];
|
if(!ajaxOpts.data) ajaxOpts.data = [];
|
||||||
ajaxOpts.data = ajaxOpts.data.concat(data);
|
ajaxOpts.data = ajaxOpts.data.concat(data);
|
||||||
|
|
||||||
|
|
||||||
// Include any GET parameters from the current URL, as the view state might depend on it.
|
// Include any GET parameters from the current URL, as the view state might depend on it.
|
||||||
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
||||||
if(window.location.search) {
|
if(window.location.search) {
|
||||||
ajaxOpts.data = window.location.search.replace(/^\?/, '') + '&' + $.param(ajaxOpts.data);
|
ajaxOpts.data = window.location.search.replace(/^\?/, '') + '&' + $.param(ajaxOpts.data);
|
||||||
}
|
|
||||||
|
|
||||||
form.addClass('loading');
|
|
||||||
|
|
||||||
$.ajax($.extend({}, {
|
|
||||||
headers: {"X-Pjax" : 'CurrentField'},
|
|
||||||
type: "POST",
|
|
||||||
url: this.data('url'),
|
|
||||||
dataType: 'html',
|
|
||||||
success: function(data) {
|
|
||||||
// Replace the grid field with response, not the form.
|
|
||||||
// TODO Only replaces all its children, to avoid replacing the current scope
|
|
||||||
// of the executing method. Means that it doesn't retrigger the onmatch() on the main container.
|
|
||||||
self.empty().append($(data).children());
|
|
||||||
|
|
||||||
// Refocus previously focused element. Useful e.g. for finding+adding
|
|
||||||
// multiple relationships via keyboard.
|
|
||||||
if(focusedElName) self.find(':input[name="' + focusedElName + '"]').focus();
|
|
||||||
|
|
||||||
var content;
|
|
||||||
if(ajaxOpts.data[0].filter=="show"){
|
|
||||||
content = '<span class="non-sortable"></span>';
|
|
||||||
self.addClass('show-filter').find('.filter-header').show();
|
|
||||||
}else{
|
|
||||||
content = '<button name="showFilter" class="ss-gridfield-button-filter trigger"></button>';
|
|
||||||
self.removeClass('show-filter').find('.filter-header').hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.find('.sortable-header th:last').html(content);
|
|
||||||
|
|
||||||
form.removeClass('loading');
|
|
||||||
if(successCallback) successCallback.apply(this, arguments);
|
|
||||||
self.trigger('reload', self);
|
|
||||||
},
|
|
||||||
error: function(e) {
|
|
||||||
alert(ss.i18n._t('GRIDFIELD.ERRORINTRANSACTION'));
|
|
||||||
form.removeClass('loading');
|
|
||||||
}
|
}
|
||||||
}, ajaxOpts));
|
|
||||||
},
|
|
||||||
showDetailView: function(url) {
|
|
||||||
window.location.href = url;
|
|
||||||
},
|
|
||||||
getItems: function() {
|
|
||||||
return this.find('.ss-gridfield-item');
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @param {String}
|
|
||||||
* @param {Mixed}
|
|
||||||
*/
|
|
||||||
setState: function(k, v) {
|
|
||||||
var state = this.getState();
|
|
||||||
state[k] = v;
|
|
||||||
this.find(':input[name="' + this.data('name') + '[GridState]"]').val(JSON.stringify(state));
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @return {Object}
|
|
||||||
*/
|
|
||||||
getState: function() {
|
|
||||||
return JSON.parse(this.find(':input[name="' + this.data('name') + '[GridState]"]').val());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.ss-gridfield *').entwine({
|
form.addClass('loading');
|
||||||
getGridField: function() {
|
|
||||||
return this.closest('.ss-gridfield');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
$.ajax($.extend({}, {
|
||||||
|
headers: {"X-Pjax" : 'CurrentField'},
|
||||||
|
type: "POST",
|
||||||
|
url: this.data('url'),
|
||||||
|
dataType: 'html',
|
||||||
|
success: function(data) {
|
||||||
|
// Replace the grid field with response, not the form.
|
||||||
|
// TODO Only replaces all its children, to avoid replacing the current scope
|
||||||
|
// of the executing method. Means that it doesn't retrigger the onmatch() on the main container.
|
||||||
|
self.empty().append($(data).children());
|
||||||
|
|
||||||
|
// Refocus previously focused element. Useful e.g. for finding+adding
|
||||||
|
// multiple relationships via keyboard.
|
||||||
|
if(focusedElName) self.find(':input[name="' + focusedElName + '"]').focus();
|
||||||
|
|
||||||
$('.ss-gridfield :button[name=showFilter]').entwine({
|
var content;
|
||||||
onclick: function(e) {
|
if(ajaxOpts.data[0].filter=="show"){
|
||||||
$('.filter-header')
|
content = '<span class="non-sortable"></span>';
|
||||||
.show('slow') // animate visibility
|
self.addClass('show-filter').find('.filter-header').show();
|
||||||
.find(':input:first').focus(); // focus first search field
|
}else{
|
||||||
this.closest('.ss-gridfield').addClass('show-filter');
|
content = '<button name="showFilter" class="ss-gridfield-button-filter trigger"></button>';
|
||||||
this.parent().html('<span class="non-sortable"></span>');
|
self.removeClass('show-filter').find('.filter-header').hide();
|
||||||
e.preventDefault();
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
self.find('.sortable-header th:last').html(content);
|
||||||
|
|
||||||
$('.ss-gridfield .ss-gridfield-item').entwine({
|
form.removeClass('loading');
|
||||||
onclick: function(e) {
|
if(successCallback) successCallback.apply(this, arguments);
|
||||||
if($(e.target).closest('.action').length) {
|
self.trigger('reload', self);
|
||||||
this._super(e);
|
},
|
||||||
return false;
|
error: function(e) {
|
||||||
|
alert(ss.i18n._t('GRIDFIELD.ERRORINTRANSACTION'));
|
||||||
|
form.removeClass('loading');
|
||||||
|
}
|
||||||
|
}, ajaxOpts));
|
||||||
|
},
|
||||||
|
showDetailView: function(url) {
|
||||||
|
window.location.href = url;
|
||||||
|
},
|
||||||
|
getItems: function() {
|
||||||
|
return this.find('.ss-gridfield-item');
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @param {String}
|
||||||
|
* @param {Mixed}
|
||||||
|
*/
|
||||||
|
setState: function(k, v) {
|
||||||
|
var state = this.getState();
|
||||||
|
state[k] = v;
|
||||||
|
this.find(':input[name="' + this.data('name') + '[GridState]"]').val(JSON.stringify(state));
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
getState: function() {
|
||||||
|
return JSON.parse(this.find(':input[name="' + this.data('name') + '[GridState]"]').val());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var editLink = this.find('.edit-link');
|
$('.ss-gridfield *').entwine({
|
||||||
if(editLink.length) this.getGridField().showDetailView(editLink.prop('href'));
|
getGridField: function() {
|
||||||
},
|
return this.closest('.ss-gridfield');
|
||||||
onmouseover: function() {
|
|
||||||
if(this.find('.edit-link').length) this.css('cursor', 'pointer');
|
|
||||||
},
|
|
||||||
onmouseout: function() {
|
|
||||||
this.css('cursor', 'default');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.ss-gridfield .action').entwine({
|
|
||||||
onclick: function(e){
|
|
||||||
var filterState='show'; //filterstate should equal current state.
|
|
||||||
|
|
||||||
if(this.hasClass('ss-gridfield-button-close') || !(this.closest('.ss-gridfield').hasClass('show-filter'))){
|
|
||||||
filterState='hidden';
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.getGridField().reload({data: [{name: this.attr('name'), value: this.val(), filter: filterState}]});
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.ss-gridfield .action.gridfield-button-delete').entwine({
|
|
||||||
onclick: function(e){
|
$('.ss-gridfield :button[name=showFilter]').entwine({
|
||||||
if(!confirm(ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE'))) {
|
onclick: function(e) {
|
||||||
|
$('.filter-header')
|
||||||
|
.show('slow') // animate visibility
|
||||||
|
.find(':input:first').focus(); // focus first search field
|
||||||
|
this.closest('.ss-gridfield').addClass('show-filter');
|
||||||
|
this.parent().html('<span class="non-sortable"></span>');
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
this._super(e);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
$('.ss-gridfield .action.gridfield-button-print').entwine({
|
|
||||||
UUID: null,
|
|
||||||
onmatch: function() {
|
|
||||||
this._super();
|
|
||||||
this.setUUID(new Date().getTime());
|
|
||||||
},
|
|
||||||
onclick: function(e){
|
|
||||||
var btn = this.closest(':button'), grid = this.getGridField(),
|
|
||||||
form = this.closest('form'), data = form.find(':input').serialize();
|
|
||||||
|
|
||||||
// Add current button
|
$('.ss-gridfield .ss-gridfield-item').entwine({
|
||||||
data += '&' + encodeURIComponent(btn.attr('name')) + '=' + encodeURIComponent(btn.val());
|
onclick: function(e) {
|
||||||
|
if($(e.target).closest('.action').length) {
|
||||||
|
this._super(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Include any GET parameters from the current URL, as the view state might depend on it.
|
var editLink = this.find('.edit-link');
|
||||||
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
if(editLink.length) this.getGridField().showDetailView(editLink.prop('href'));
|
||||||
if(window.location.search) data = window.location.search.replace(/^\?/, '') + '&' + data;
|
},
|
||||||
|
onmouseover: function() {
|
||||||
var url = $.path.makeUrlAbsolute(grid.data('url') + '?' + data, $('base').attr('href'));
|
if(this.find('.edit-link').length) this.css('cursor', 'pointer');
|
||||||
var newWindow = window.open(url);
|
},
|
||||||
|
onmouseout: function() {
|
||||||
return false;
|
this.css('cursor', 'default');
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.ss-gridfield-print-iframe').entwine({
|
|
||||||
onmatch: function(){
|
|
||||||
this.hide().bind('load', function()
|
|
||||||
{
|
|
||||||
this.focus();
|
|
||||||
var ifWin = this.contentWindow || this;
|
|
||||||
ifWin.print();
|
|
||||||
});;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents actions from causing an ajax reload of the field.
|
|
||||||
* Useful e.g. for actions which rely on HTTP response headers being interpreted nativel
|
|
||||||
* by the browser, like file download triggers.
|
|
||||||
*/
|
|
||||||
$('.ss-gridfield .action.no-ajax').entwine({
|
|
||||||
onclick: function(e){
|
|
||||||
var self = this, btn = this.closest(':button'), grid = this.getGridField(),
|
|
||||||
form = this.closest('form'), data = form.find(':input').serialize();
|
|
||||||
|
|
||||||
// Add current button
|
|
||||||
data += '&' + encodeURIComponent(btn.attr('name')) + '=' + encodeURIComponent(btn.val());
|
|
||||||
|
|
||||||
// Include any GET parameters from the current URL, as the view state might depend on it.
|
|
||||||
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
|
||||||
if(window.location.search) data = window.location.search.replace(/^\?/, '') + '&' + data;
|
|
||||||
|
|
||||||
window.location.href = $.path.makeUrlAbsolute(grid.data('url') + '?' + data, $('base').attr('href'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.ss-gridfield .action-detail').entwine({
|
|
||||||
onclick: function() {
|
|
||||||
this.getGridField().showDetailView($(this).prop('href'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows selection of one or more rows in the grid field.
|
|
||||||
* Purely clientside at the moment.
|
|
||||||
*/
|
|
||||||
$('.ss-gridfield[data-selectable]').entwine({
|
|
||||||
/**
|
|
||||||
* @return {jQuery} Collection
|
|
||||||
*/
|
|
||||||
getSelectedItems: function() {
|
|
||||||
return this.find('.ss-gridfield-item.ui-selected');
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @return {Array} Of record IDs
|
|
||||||
*/
|
|
||||||
getSelectedIDs: function() {
|
|
||||||
return $.map(this.getSelectedItems(), function(el) {return $(el).data('id');});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('.ss-gridfield[data-selectable] .ss-gridfield-items').entwine({
|
|
||||||
onmatch: function() {
|
|
||||||
this._super();
|
|
||||||
|
|
||||||
// TODO Limit to single selection
|
|
||||||
this.selectable();
|
|
||||||
},
|
|
||||||
onunmatch: function() {
|
|
||||||
this._super();
|
|
||||||
this.selectable('destroy');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Catch submission event in filter input fields, and submit the correct button
|
|
||||||
* rather than the whole form.
|
|
||||||
*/
|
|
||||||
$('.ss-gridfield .filter-header :input').entwine({
|
|
||||||
onmatch: function(){
|
|
||||||
var filterbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-filter'),
|
|
||||||
resetbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-reset');
|
|
||||||
|
|
||||||
if(this.val()) {
|
|
||||||
filterbtn.addClass('filtered');
|
|
||||||
resetbtn.addClass('filtered');
|
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
onkeydown: function(e) {
|
|
||||||
// Skip reset button events, they should trigger default submission
|
|
||||||
if(this.closest('.ss-gridfield-button-reset').length) return;
|
|
||||||
|
|
||||||
var filterbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-filter'),
|
$('.ss-gridfield .action').entwine({
|
||||||
resetbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-reset');
|
onclick: function(e){
|
||||||
|
|
||||||
if(e.keyCode == '13') {
|
|
||||||
var btns = this.closest('.filter-header').find('.ss-gridfield-button-filter');
|
|
||||||
var filterState='show'; //filterstate should equal current state.
|
var filterState='show'; //filterstate should equal current state.
|
||||||
if(this.hasClass('ss-gridfield-button-close')||!(this.closest('.ss-gridfield').hasClass('show-filter'))){
|
|
||||||
|
if(this.hasClass('ss-gridfield-button-close') || !(this.closest('.ss-gridfield').hasClass('show-filter'))){
|
||||||
filterState='hidden';
|
filterState='hidden';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getGridField().reload({data: [{name: btns.attr('name'), value: btns.val(), filter: filterState}]});
|
this.getGridField().reload({data: [{name: this.attr('name'), value: this.val(), filter: filterState}]});
|
||||||
return false;
|
e.preventDefault();
|
||||||
}else{
|
|
||||||
filterbtn.addClass('hover-alike');
|
|
||||||
resetbtn.addClass('hover-alike');
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
$(".ss-gridfield .relation-search").entwine({
|
$('.ss-gridfield .action.gridfield-button-delete').entwine({
|
||||||
onfocusin: function (event) {
|
onclick: function(e){
|
||||||
this.autocomplete({
|
if(!confirm(ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE'))) {
|
||||||
source: function(request, response){
|
e.preventDefault();
|
||||||
var searchField = $(this.element);
|
return false;
|
||||||
var form = $(this.element).closest("form");
|
} else {
|
||||||
// Due to some very weird behaviout of jquery.metadata, the url have to be double quoted
|
this._super(e);
|
||||||
var suggestionUrl = $(searchField).attr('data-search-url').substr(1,$(searchField).attr('data-search-url').length-2);
|
|
||||||
$.ajax({
|
|
||||||
headers: {
|
|
||||||
"X-Pjax" : 'Partial'
|
|
||||||
},
|
|
||||||
type: "GET",
|
|
||||||
url: suggestionUrl+'/'+request.term,
|
|
||||||
data: form.serialize()+'&'+escape(searchField.attr('name'))+'='+escape(searchField.val()),
|
|
||||||
success: function(data) {
|
|
||||||
response( $.map(JSON.parse(data), function( name, id ) {
|
|
||||||
return { label: name, value: name, id: id };
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
error: function(e) {
|
|
||||||
alert(ss.i18n._t('GRIDFIELD.ERRORINTRANSACTION', 'An error occured while fetching data from the server\n Please try again later.'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
select: function(event, ui) {
|
|
||||||
$(this).closest(".ss-gridfield").find("#action_gridfield_relationfind").replaceWith(
|
|
||||||
'<input type="hidden" name="relationID" value="'+ui.item.id+'" id="relationID"/>'
|
|
||||||
);
|
|
||||||
var addbutton = $(this).closest(".ss-gridfield").find("#action_gridfield_relationadd");
|
|
||||||
if(addbutton.data('button')){
|
|
||||||
addbutton.button('enable');
|
|
||||||
}else{
|
|
||||||
addbutton.removeAttr('disabled');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
$(".ss-gridfield .pagination-page-number input").entwine({
|
$('.ss-gridfield .action.gridfield-button-print').entwine({
|
||||||
onkeydown: function(event) {
|
UUID: null,
|
||||||
if(event.keyCode == 13) {
|
onmatch: function() {
|
||||||
var newpage = parseInt($(this).val(), 10);
|
this._super();
|
||||||
|
this.setUUID(new Date().getTime());
|
||||||
|
},
|
||||||
|
onclick: function(e){
|
||||||
|
var btn = this.closest(':button'), grid = this.getGridField(),
|
||||||
|
form = this.closest('form'), data = form.find(':input').serialize();
|
||||||
|
|
||||||
var gridfield = $(this).getGridField();
|
// Add current button
|
||||||
gridfield.setState('GridFieldPaginator', {currentPage: newpage});
|
data += '&' + encodeURIComponent(btn.attr('name')) + '=' + encodeURIComponent(btn.val());
|
||||||
gridfield.reload();
|
|
||||||
|
// Include any GET parameters from the current URL, as the view state might depend on it.
|
||||||
|
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
||||||
|
if(window.location.search) data = window.location.search.replace(/^\?/, '') + '&' + data;
|
||||||
|
|
||||||
|
var url = $.path.makeUrlAbsolute(grid.data('url') + '?' + data, $('base').attr('href'));
|
||||||
|
var newWindow = window.open(url);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
$('.ss-gridfield-print-iframe').entwine({
|
||||||
|
onmatch: function(){
|
||||||
|
this.hide().bind('load', function()
|
||||||
|
{
|
||||||
|
this.focus();
|
||||||
|
var ifWin = this.contentWindow || this;
|
||||||
|
ifWin.print();
|
||||||
|
});;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevents actions from causing an ajax reload of the field.
|
||||||
|
* Useful e.g. for actions which rely on HTTP response headers being interpreted nativel
|
||||||
|
* by the browser, like file download triggers.
|
||||||
|
*/
|
||||||
|
$('.ss-gridfield .action.no-ajax').entwine({
|
||||||
|
onclick: function(e){
|
||||||
|
var self = this, btn = this.closest(':button'), grid = this.getGridField(),
|
||||||
|
form = this.closest('form'), data = form.find(':input').serialize();
|
||||||
|
|
||||||
|
// Add current button
|
||||||
|
data += '&' + encodeURIComponent(btn.attr('name')) + '=' + encodeURIComponent(btn.val());
|
||||||
|
|
||||||
|
// Include any GET parameters from the current URL, as the view state might depend on it.
|
||||||
|
// For example, a list prefiltered through external search criteria might be passed to GridField.
|
||||||
|
if(window.location.search) data = window.location.search.replace(/^\?/, '') + '&' + data;
|
||||||
|
|
||||||
|
window.location.href = $.path.makeUrlAbsolute(grid.data('url') + '?' + data, $('base').attr('href'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.ss-gridfield .action-detail').entwine({
|
||||||
|
onclick: function() {
|
||||||
|
this.getGridField().showDetailView($(this).prop('href'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows selection of one or more rows in the grid field.
|
||||||
|
* Purely clientside at the moment.
|
||||||
|
*/
|
||||||
|
$('.ss-gridfield[data-selectable]').entwine({
|
||||||
|
/**
|
||||||
|
* @return {jQuery} Collection
|
||||||
|
*/
|
||||||
|
getSelectedItems: function() {
|
||||||
|
return this.find('.ss-gridfield-item.ui-selected');
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @return {Array} Of record IDs
|
||||||
|
*/
|
||||||
|
getSelectedIDs: function() {
|
||||||
|
return $.map(this.getSelectedItems(), function(el) {return $(el).data('id');});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('.ss-gridfield[data-selectable] .ss-gridfield-items').entwine({
|
||||||
|
onmatch: function() {
|
||||||
|
this._super();
|
||||||
|
|
||||||
|
// TODO Limit to single selection
|
||||||
|
this.selectable();
|
||||||
|
},
|
||||||
|
onunmatch: function() {
|
||||||
|
this._super();
|
||||||
|
this.selectable('destroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Catch submission event in filter input fields, and submit the correct button
|
||||||
|
* rather than the whole form.
|
||||||
|
*/
|
||||||
|
$('.ss-gridfield .filter-header :input').entwine({
|
||||||
|
onmatch: function(){
|
||||||
|
var filterbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-filter'),
|
||||||
|
resetbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-reset');
|
||||||
|
|
||||||
|
if(this.val()) {
|
||||||
|
filterbtn.addClass('filtered');
|
||||||
|
resetbtn.addClass('filtered');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onkeydown: function(e) {
|
||||||
|
// Skip reset button events, they should trigger default submission
|
||||||
|
if(this.closest('.ss-gridfield-button-reset').length) return;
|
||||||
|
|
||||||
|
var filterbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-filter'),
|
||||||
|
resetbtn = this.closest('.fieldgroup').find('.ss-gridfield-button-reset');
|
||||||
|
|
||||||
|
if(e.keyCode == '13') {
|
||||||
|
var btns = this.closest('.filter-header').find('.ss-gridfield-button-filter');
|
||||||
|
var filterState='show'; //filterstate should equal current state.
|
||||||
|
if(this.hasClass('ss-gridfield-button-close')||!(this.closest('.ss-gridfield').hasClass('show-filter'))){
|
||||||
|
filterState='hidden';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getGridField().reload({data: [{name: btns.attr('name'), value: btns.val(), filter: filterState}]});
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
filterbtn.addClass('hover-alike');
|
||||||
|
resetbtn.addClass('hover-alike');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".ss-gridfield .relation-search").entwine({
|
||||||
|
onfocusin: function (event) {
|
||||||
|
this.autocomplete({
|
||||||
|
source: function(request, response){
|
||||||
|
var searchField = $(this.element);
|
||||||
|
var form = $(this.element).closest("form");
|
||||||
|
// Due to some very weird behaviout of jquery.metadata, the url have to be double quoted
|
||||||
|
var suggestionUrl = $(searchField).attr('data-search-url').substr(1,$(searchField).attr('data-search-url').length-2);
|
||||||
|
$.ajax({
|
||||||
|
headers: {
|
||||||
|
"X-Pjax" : 'Partial'
|
||||||
|
},
|
||||||
|
type: "GET",
|
||||||
|
url: suggestionUrl+'/'+request.term,
|
||||||
|
data: form.serialize()+'&'+escape(searchField.attr('name'))+'='+escape(searchField.val()),
|
||||||
|
success: function(data) {
|
||||||
|
response( $.map(JSON.parse(data), function( name, id ) {
|
||||||
|
return { label: name, value: name, id: id };
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
error: function(e) {
|
||||||
|
alert(ss.i18n._t('GRIDFIELD.ERRORINTRANSACTION', 'An error occured while fetching data from the server\n Please try again later.'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
select: function(event, ui) {
|
||||||
|
$(this).closest(".ss-gridfield").find("#action_gridfield_relationfind").replaceWith(
|
||||||
|
'<input type="hidden" name="relationID" value="'+ui.item.id+'" id="relationID"/>'
|
||||||
|
);
|
||||||
|
var addbutton = $(this).closest(".ss-gridfield").find("#action_gridfield_relationadd");
|
||||||
|
if(addbutton.data('button')){
|
||||||
|
addbutton.button('enable');
|
||||||
|
}else{
|
||||||
|
addbutton.removeAttr('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".ss-gridfield .pagination-page-number input").entwine({
|
||||||
|
onkeydown: function(event) {
|
||||||
|
if(event.keyCode == 13) {
|
||||||
|
var newpage = parseInt($(this).val(), 10);
|
||||||
|
|
||||||
|
var gridfield = $(this).getGridField();
|
||||||
|
gridfield.setState('GridFieldPaginator', {currentPage: newpage});
|
||||||
|
gridfield.reload();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}(jQuery));
|
}(jQuery));
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
var _clickTestFn = function(e) {
|
var _clickTestFn = function(e) {
|
||||||
// If the click target is not a child of the current field, close the panel automatically.
|
// If the click target is not a child of the current field, close the panel automatically.
|
||||||
if(!$(e.target).parents('.TreeDropdownField').length) jQuery('.TreeDropdownField').entwine('ss').closePanel();
|
if(!$(e.target).parents('.TreeDropdownField').length) jQuery('.TreeDropdownField').closePanel();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user