mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
(merged from branches/roa. use "svn log -c <changeset> -g <module-svn-path>" for detailed commit message)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@60314 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
2d9c833de5
commit
624540a2d0
@ -259,55 +259,71 @@ class Requirements {
|
||||
* @param string $content HTML content that has already been parsed from the $templateFilePath through {@link SSViewer}.
|
||||
* @return string HTML content thats augumented with the requirements before the closing <head> tag.
|
||||
*/
|
||||
static function includeInHTML($templateFilePath, $content) {
|
||||
static function includeInHTML($templateFile, $content) {
|
||||
if(isset($_GET['debug_profile'])) Profiler::mark("Requirements::includeInHTML");
|
||||
|
||||
if(strpos($content, '</head') === false) {
|
||||
if(isset($_GET['debug_profile'])) Profiler::unmark("Requirements::includeInHTML");
|
||||
if(strpos($content, '</head') !== false && (Requirements::$javascript || Requirements::$css || Requirements::$customScript || Requirements::$customHeadTags)) {
|
||||
$prefix = Director::absoluteBaseURL();
|
||||
$requirements = '';
|
||||
$jsRequirements = '';
|
||||
|
||||
// Combine files - updates Requirements::$javascript and Requirements::$css
|
||||
self::process_combined_files();
|
||||
|
||||
foreach(array_diff_key(self::$javascript,self::$blocked) as $file => $dummy) {
|
||||
if(substr($file,0,7) == 'http://' || Director::fileExists($file)) {
|
||||
if(Director::fileExists($file)) $mtimesuffix = "?m=" . filemtime(Director::baseFolder() . '/' . $file);
|
||||
else $mtimesuffix = '';
|
||||
$jsRequirements .= "<script type=\"text/javascript\" src=\"$prefix$file$mtimesuffix\"></script>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(self::$customScript) {
|
||||
foreach(array_diff_key(self::$customScript,self::$blocked) as $script) {
|
||||
$jsRequirements .= "<script type=\"text/javascript\">\n//<![CDATA[\n";
|
||||
$jsRequirements .= "$script\n";
|
||||
$jsRequirements .= "\n//]]>\n</script>\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach(array_diff_key(self::$css,self::$blocked) as $file => $params) {
|
||||
if(Director::fileExists($file)) {
|
||||
$media = (isset($params['media']) && !empty($params['media'])) ? " media=\"{$params['media']}\"" : "";
|
||||
if(Director::fileExists($file)) $mtimesuffix = "?m=" . filemtime(Director::baseFolder() . '/' .$file);
|
||||
else $mtimesuffix = '';
|
||||
$requirements .= "<link rel=\"stylesheet\" type=\"text/css\"{$media} href=\"$prefix$file$mtimesuffix\" />\n";
|
||||
}
|
||||
}
|
||||
foreach(array_diff_key(self::$customCSS,self::$blocked) as $css) {
|
||||
$requirements .= "<style type=\"text/css\">\n$css\n</style>\n";
|
||||
}
|
||||
|
||||
foreach(array_diff_key(self::$customHeadTags,self::$blocked) as $customHeadTag) {
|
||||
$requirements .= "$customHeadTag\n";
|
||||
}
|
||||
|
||||
if(isset($_GET['debug_profile'])) Profiler::unmark("Requirements::includeInHTML");
|
||||
|
||||
|
||||
// We put script tags into the body, for performance.
|
||||
// If your template already has script tags in the body, then we put our script tags at the top of the body.
|
||||
// Otherwise, we put it at the bottom.
|
||||
$p1 = strripos($content, '<script');
|
||||
$p2 = stripos($content, '<body');
|
||||
if($p1 !== false && $p1 > $p2) {
|
||||
user_error("You have a script tag in the body, moving requirements to top of <body> for compatibilty. I recommend removing the script tag from your template's body.", E_USER_NOTICE);
|
||||
$content = eregi_replace("(<body[^>]*>)", "\\1" . $jsRequirements, $content);
|
||||
} else {
|
||||
$content = eregi_replace("(</body[^>]*>)", $jsRequirements . "\\1", $content);
|
||||
}
|
||||
|
||||
// Put CSS at the bottom of the head
|
||||
return eregi_replace("(</head[^>]*>)", $requirements . "\\1", $content);
|
||||
|
||||
} else {
|
||||
if(isset($_GET['debug_profile'])) Profiler::unmark("Requirements::includeInHTML");
|
||||
return $content;
|
||||
}
|
||||
|
||||
$prefix = Director::absoluteBaseURL();
|
||||
$requirements = '';
|
||||
$jsRequirements = '';
|
||||
|
||||
// Combine files - updates Requirements::$javascript and Requirements::$css
|
||||
// to remove duplicate entries
|
||||
self::process_combined_files();
|
||||
|
||||
foreach(array_diff_key(self::$javascript,self::$blocked) as $file => $dummy) {
|
||||
if(substr($file,0,7) == 'http://' || Director::fileExists($file)) {
|
||||
$requirements .= "<script type=\"text/javascript\" src=\"$prefix$file\"></script>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(self::$customScript) {
|
||||
foreach(array_diff_key(self::$customScript,self::$blocked) as $script) {
|
||||
$requirements .= "<script type=\"text/javascript\">\n//<![CDATA[\n";
|
||||
$requirements .= "$script\n";
|
||||
$requirements .= "\n//]]>\n</script>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$jsRequirements = $requirements;
|
||||
|
||||
foreach(array_diff_key(self::$css,self::$blocked) as $file => $params) {
|
||||
if(Director::fileExists($file)) {
|
||||
$media = (isset($params['media']) && !empty($params['media'])) ? " media=\"{$params['media']}\"" : "";
|
||||
$requirements .= "<link rel=\"stylesheet\" type=\"text/css\"{$media} href=\"$prefix$file\" />\n";
|
||||
}
|
||||
}
|
||||
foreach(array_diff_key(self::$customCSS,self::$blocked) as $css) {
|
||||
$requirements .= "<style type=\"text/css\">\n$css\n</style>\n";
|
||||
}
|
||||
|
||||
foreach(array_diff_key(self::$customHeadTags,self::$blocked) as $customHeadTag) {
|
||||
$requirements .= "$customHeadTag\n";
|
||||
}
|
||||
|
||||
if(isset($_GET['debug_profile'])) Profiler::unmark("Requirements::includeInHTML");
|
||||
|
||||
return eregi_replace("(</head[^>]*>)", $requirements . "\\1", $content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,6 +285,32 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
$name = $this->plural_name();
|
||||
return _t($this->class.'.PLURALNAME', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard implementation of a title/label for a specific
|
||||
* record. Tries to find properties 'Title' or 'Name',
|
||||
* and falls back to the 'ID'. Useful to provide
|
||||
* user-friendly identification of a record, e.g. in errormessages
|
||||
* or UI-selections.
|
||||
*
|
||||
* Overload this method to have a more specialized implementation,
|
||||
* e.g. for an Address record this could be:
|
||||
* <code>
|
||||
* public function getTitle() {
|
||||
* return "{$this->StreetNumber} {$this->StreetName} {$this->City}";
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @usedby {@link DataObjectSet->toDropDownMap()}
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() {
|
||||
if($this->hasField('Title')) return $this->getField('Title');
|
||||
if($this->hasField('Name')) return $this->getField('Name');
|
||||
|
||||
return "#{$this->ID}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the associated database record - in this case, the object itself.
|
||||
@ -2492,6 +2518,7 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
public static $casting = array(
|
||||
"LastEdited" => "Datetime",
|
||||
"Created" => "Datetime",
|
||||
"Title" => 'Text',
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -62,6 +62,14 @@ abstract class DataObjectDecorator extends Extension {
|
||||
*/
|
||||
function augmentDatabase() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Augment a write-record request.
|
||||
*
|
||||
* @param SQLQuery $manipulation Query to augment.
|
||||
*/
|
||||
function augmentWrite(&$manipulation) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -69,7 +69,7 @@ class SQLQuery extends Object {
|
||||
* The logical connective used to join WHERE clauses. Defaults to AND.
|
||||
* @var string
|
||||
*/
|
||||
private $connective = 'AND';
|
||||
public $connective = 'AND';
|
||||
|
||||
/**
|
||||
* Construct a new SQLQuery.
|
||||
|
@ -182,6 +182,7 @@ class SiteTree extends DataObject {
|
||||
|
||||
static $searchable_fields = array(
|
||||
'Title',
|
||||
'Content',
|
||||
);
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ class CheckboxSetField extends OptionsetField {
|
||||
if(!$values && $record && $record->hasMethod($this->name)) {
|
||||
$funcName = $this->name;
|
||||
$join = $record->$funcName();
|
||||
foreach($join as $joinItem) $values[] = $joinItem->ID;
|
||||
if($join) foreach($join as $joinItem) $values[] = $joinItem->ID;
|
||||
}
|
||||
}
|
||||
$source = $this->source;
|
||||
|
@ -252,7 +252,7 @@ JS;
|
||||
* @return Boolean
|
||||
*/
|
||||
function IsAddMode() {
|
||||
return ($this->methodName == "add");
|
||||
return ($this->methodName == "add" || $this->request->param('Action') == 'AddForm');
|
||||
}
|
||||
|
||||
function sourceID() {
|
||||
@ -457,17 +457,20 @@ JS;
|
||||
$childData = new $className();
|
||||
$form->saveInto($childData);
|
||||
$childData->write();
|
||||
|
||||
$closeLink = sprintf(
|
||||
'<small><a href="' . $_SERVER['HTTP_REFERER'] . '" onclick="javascript:window.top.GB_hide(); return false;">(%s)</a></small>',
|
||||
_t('ComplexTableField.CLOSEPOPUP', 'Close Popup')
|
||||
);
|
||||
$message = sprintf(
|
||||
_t('ComplexTableField.SUCCESSADD', 'Added %s %s %s'),
|
||||
$childData->singular_name(),
|
||||
'<a href="' . $this->Link() . '">' . $childData->Title . '</a>',
|
||||
$closeLink
|
||||
);
|
||||
$form->sessionMessage($message, 'good');
|
||||
|
||||
// if ajax-call in an iframe, update window
|
||||
if(Director::is_ajax()) {
|
||||
// Newly saved objects need their ID reflected in the reloaded form to avoid double saving
|
||||
$childRequestHandler = new ComplexTableField_ItemRequest($this, $childData->ID);
|
||||
$form = $childRequestHandler->DetailForm();
|
||||
FormResponse::update_dom_id($form->FormName(), $form->formHtmlContent(), true, 'update');
|
||||
return FormResponse::respond();
|
||||
} else {
|
||||
Director::redirectBack();
|
||||
}
|
||||
Director::redirectBack();
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,18 +602,20 @@ class ComplexTableField_ItemRequest extends RequestHandlingData {
|
||||
function saveComplexTableField($data, $form, $request) {
|
||||
$form->saveInto($this->dataObj());
|
||||
$this->dataObj()->write();
|
||||
|
||||
$closeLink = sprintf(
|
||||
'<small><a href="' . $_SERVER['HTTP_REFERER'] . '" onclick="javascript:window.top.GB_hide(); return false;">(%s)</a></small>',
|
||||
_t('ComplexTableField.CLOSEPOPUP', 'Close Popup')
|
||||
);
|
||||
$message = sprintf(
|
||||
_t('ComplexTableField.SUCCESSEDIT', 'Saved %s %s %s'),
|
||||
$this->dataObj()->singular_name(),
|
||||
'<a href="' . $this->Link() . '">"' . $this->dataObj()->Title . '"</a>',
|
||||
$closeLink
|
||||
);
|
||||
$form->sessionMessage($message, 'good');
|
||||
|
||||
// if ajax-call in an iframe, update window
|
||||
if(Director::is_ajax()) {
|
||||
// Newly saved objects need their ID reflected in the reloaded form to avoid double saving
|
||||
$form = $this->DetailForm();
|
||||
//$form->loadDataFrom($this->dataObject);
|
||||
FormResponse::update_dom_id($form->FormName(), $form->formHtmlContent(), true, 'update');
|
||||
return FormResponse::respond();
|
||||
|
||||
} else {
|
||||
Director::redirectBack();
|
||||
}
|
||||
Director::redirectBack();
|
||||
}
|
||||
|
||||
function PopupCurrentItem() {
|
||||
|
@ -681,7 +681,7 @@ JS
|
||||
if(!isset($_REQUEST['ctf'][$this->Name()]['start']) || !is_numeric($_REQUEST['ctf'][$this->Name()]['start']) || $_REQUEST['ctf'][$this->Name()]['start'] == 0) {
|
||||
return null;
|
||||
}
|
||||
$link = $this->Link() . "/ajax_refresh?ctf[{$this->Name()}][start]={$start}";
|
||||
$link = $this->Link() . "/?ctf[{$this->Name()}][start]={$start}";
|
||||
if($this->extraLinkParams) $link .= "&" . http_build_query($this->extraLinkParams);
|
||||
return $link;
|
||||
}
|
||||
@ -695,7 +695,7 @@ JS
|
||||
|
||||
$start = ($_REQUEST['ctf'][$this->Name()]['start'] - $this->pageSize < 0) ? 0 : $_REQUEST['ctf'][$this->Name()]['start'] - $this->pageSize;
|
||||
|
||||
$link = $this->Link() . "/ajax_refresh?ctf[{$this->Name()}][start]={$start}";
|
||||
$link = $this->Link() . "/?ctf[{$this->Name()}][start]={$start}";
|
||||
if($this->extraLinkParams) $link .= "&" . http_build_query($this->extraLinkParams);
|
||||
return $link;
|
||||
}
|
||||
@ -706,7 +706,7 @@ JS
|
||||
if($currentStart >= $start-1) {
|
||||
return null;
|
||||
}
|
||||
$link = $this->Link() . "/ajax_refresh?ctf[{$this->Name()}][start]={$start}";
|
||||
$link = $this->Link() . "/?ctf[{$this->Name()}][start]={$start}";
|
||||
if($this->extraLinkParams) $link .= "&" . http_build_query($this->extraLinkParams);
|
||||
return $link;
|
||||
}
|
||||
@ -719,7 +719,7 @@ JS
|
||||
return null;
|
||||
}
|
||||
|
||||
$link = $this->Link() . "/ajax_refresh?ctf[{$this->Name()}][start]={$start}";
|
||||
$link = $this->Link() . "/?ctf[{$this->Name()}][start]={$start}";
|
||||
if($this->extraLinkParams) $link .= "&" . http_build_query($this->extraLinkParams);
|
||||
return $link;
|
||||
}
|
||||
@ -928,6 +928,9 @@ JS
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use the standard URL through Link() which gives you the FieldHolder
|
||||
*/
|
||||
function ajax_refresh() {
|
||||
// compute sourceItems here instead of Items() to ensure that
|
||||
// pagination and filters are respected on template accessors
|
||||
|
@ -8,12 +8,9 @@ ComplexTableField.prototype = {
|
||||
popupWidth: 560,
|
||||
popupHeight: 390,
|
||||
|
||||
deleteConfirmMessage: "Are you sure you want to delete this record?",
|
||||
|
||||
initialize: function() {
|
||||
var rules = {};
|
||||
rules['#'+this.id+' table.data a.popuplink'] = {onclick: this.openPopup.bind(this)};
|
||||
rules['#'+this.id+' table.data a.deletelink'] = {onclick: this.deleteRecord.bind(this)};
|
||||
rules['#'+this.id+' table.data tbody td'] = {onclick: this.openPopup.bind(this)};
|
||||
|
||||
Behaviour.register(rules);
|
||||
@ -22,49 +19,6 @@ ComplexTableField.prototype = {
|
||||
if(window != top) $$('#'+this.id+' table.data a.addlink').each(function(el) {Element.hide(el);});
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the given dataobject record via an ajax request
|
||||
* to complextablefield->Delete()
|
||||
* @param {Object} e
|
||||
*/
|
||||
deleteRecord: function(e) {
|
||||
var img = Event.element(e);
|
||||
var link = Event.findElement(e,"a");
|
||||
var row = Event.findElement(e,"tr");
|
||||
|
||||
// TODO ajaxErrorHandler and loading-image are dependent on cms, but formfield is in sapphire
|
||||
var confirmed = (this.deleteConfirmMessage != undefined) ? confirm(this.deleteConfirmMessage) : true;
|
||||
if(confirmed)
|
||||
{
|
||||
img.setAttribute("src",'cms/images/network-save.gif'); // TODO doesn't work
|
||||
new Ajax.Request(
|
||||
link.getAttribute("href"),
|
||||
{
|
||||
method: 'post',
|
||||
postBody: 'forceajax=1' + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''),
|
||||
onComplete: function(){
|
||||
Effect.Fade(
|
||||
row,
|
||||
{
|
||||
afterFinish: function(obj) {
|
||||
// remove row from DOM
|
||||
obj.element.parentNode.removeChild(obj.element);
|
||||
// recalculate summary if needed (assumes that TableListField.js is present)
|
||||
// TODO Proper inheritance
|
||||
if(this._summarise) this._summarise();
|
||||
// custom callback
|
||||
if(this.callback_deleteRecord) this.callback_deleteRecord(e);
|
||||
}.bind(this)
|
||||
}
|
||||
);
|
||||
}.bind(this),
|
||||
onFailure: this.ajaxErrorHandler
|
||||
}
|
||||
);
|
||||
}
|
||||
Event.stop(e);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param href, table Optional dom object (use for external triggering without an event)
|
||||
*/
|
||||
@ -117,10 +71,6 @@ ComplexTableField.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
GB_OpenerObj = this;
|
||||
// use same url to refresh the table after saving the popup, but use a generic rendering method
|
||||
GB_RefreshLink = this.getAttribute('href');
|
||||
|
||||
if(this.GB_Caption) {
|
||||
var title = this.GB_Caption;
|
||||
} else {
|
||||
@ -129,7 +79,17 @@ ComplexTableField.prototype = {
|
||||
var title = (type && type[1]) ? type[1].ucfirst() : "";
|
||||
}
|
||||
|
||||
GB_show(title, popupLink, this.popupHeight, this.popupWidth);
|
||||
// reset internal greybox callbacks, they are not properly unregistered
|
||||
// and fire multiple times on each subsequent popup close action otherwise
|
||||
if(GB_ONLY_ONE) GB_ONLY_ONE.callback_fn = [];
|
||||
|
||||
GB_show(
|
||||
title,
|
||||
popupLink,
|
||||
this.popupHeight,
|
||||
this.popupWidth,
|
||||
this.refresh.bind(this)
|
||||
);
|
||||
|
||||
if(e) {
|
||||
Event.stop(e);
|
||||
|
@ -1,119 +1,10 @@
|
||||
ComplexTableFieldPopupForm = Class.create();
|
||||
ComplexTableFieldPopupForm.prototype = {
|
||||
|
||||
errorMessage: "Error talking to server",
|
||||
|
||||
initialize: function() {
|
||||
var rules = {};
|
||||
rules["#" + this.id + " .Actions input.action"] = {
|
||||
'onclick' : this.submitForm.bind(this)
|
||||
};
|
||||
|
||||
Behaviour.register(rules);
|
||||
},
|
||||
|
||||
loadNewPage : function(content) {
|
||||
this.innerHTML = content;
|
||||
},
|
||||
|
||||
submitForm : function(e) {
|
||||
// if custom validation implementation (extend class to implement)
|
||||
if(this.validate) {
|
||||
if(!this.validate()) {
|
||||
Event.stop(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// only do ajaxy stuff for content loaded in an iframe
|
||||
if(window != top && parent.parent.GB_hide) {
|
||||
var theForm = Event.findElement(e,"form");
|
||||
if(parent.parent.statusMessage != undefined) parent.parent.statusMessage('saving');
|
||||
var submitButton = document.getElementsBySelector("input.action",theForm)[0];
|
||||
if(typeof submitButton != 'undefined') {
|
||||
submitButton.disabled = true;
|
||||
Element.addClassName(submitButton,'loading');
|
||||
}
|
||||
new parent.parent.Ajax.Request(
|
||||
theForm.getAttribute("action"),
|
||||
{
|
||||
parameters: Form.serialize(theForm)+"&ajax=1",
|
||||
onComplete: this.updateTableAfterSave.bind(this),
|
||||
onFailure: this.ajaxErrorHandler.bind(this)
|
||||
}
|
||||
);
|
||||
Event.stop(e);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
updateTableAfterSave : function(response) {
|
||||
try {
|
||||
eval(response.responseText);
|
||||
} catch(er) { alert(er.message); }
|
||||
|
||||
var theForm = document.getElementsByTagName("form")[0];
|
||||
|
||||
// don't update when validation is present and failed
|
||||
if(!this.validate || (this.validate && !hasHadFormError())) {
|
||||
new parent.parent.Ajax.Request(
|
||||
parent.parent.GB_RefreshLink,
|
||||
{
|
||||
onComplete: this.updateAndHide.bind(parent.parent),
|
||||
onFailure : this.ajaxErrorHandler
|
||||
}
|
||||
);
|
||||
} else {
|
||||
var submitButton = document.getElementsBySelector("input.action",theForm)[0];
|
||||
if(typeof submitButton != 'undefined') {
|
||||
submitButton.disabled = false;
|
||||
Element.removeClassName(submitButton,'loading');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ajaxErrorHandler: function(response) {
|
||||
var submitButton = document.getElementsBySelector("input.action",theForm)[0];
|
||||
if(typeof submitButton != 'undefined') {
|
||||
submitButton.disabled = false;
|
||||
Element.removeClassName(submitButton,'loading');
|
||||
}
|
||||
|
||||
// TODO does not work due to sandbox-iframe restrictions?
|
||||
if(typeof(parent.parent.ajaxErrorHandler) == 'function') {
|
||||
parent.parent.ajaxErrorHandler();
|
||||
} else {
|
||||
alert(this.errorMessage);
|
||||
}
|
||||
},
|
||||
|
||||
updateAndHide: function(response) {
|
||||
var theForm =document.getElementsByTagName("form")[0];
|
||||
|
||||
var submitButton = document.getElementsBySelector("input.action",theForm)[0];
|
||||
if(typeof submitButton != 'undefined') {
|
||||
submitButton.disabled = false;
|
||||
Element.removeClassName(submitButton,'loading');
|
||||
}
|
||||
|
||||
onload_init_tabstrip();
|
||||
|
||||
// TODO Fix DOM-relation after pagination inside popup
|
||||
if(this.GB_OpenerObj) {
|
||||
// apparently firefox doesn't remember its DOM after innerHTML, so we help out here...
|
||||
var cachedObj = this.GB_OpenerObj;
|
||||
var cachedParentObj = this.GB_OpenerObj.parentNode;
|
||||
Element.replace(this.GB_OpenerObj, response.responseText);
|
||||
this.Behaviour.apply(cachedParentObj);
|
||||
cachedObj = null;
|
||||
this.GB_OpenerObj = null;
|
||||
}
|
||||
|
||||
// causes IE6 to go nuts
|
||||
this.GB_hide();
|
||||
|
||||
}
|
||||
}
|
||||
ComplexTableFieldPopupForm.applyTo('#ComplexTableField_Popup_DetailForm');
|
||||
|
@ -13,7 +13,7 @@ TableListField.prototype = {
|
||||
};
|
||||
|
||||
rules['#'+this.id+' th a'] = {
|
||||
onclick: this.paginate.bind(this)
|
||||
onclick: this.refresh.bind(this)
|
||||
};
|
||||
|
||||
rules['#'+this.id+' th'] = {
|
||||
@ -31,7 +31,7 @@ TableListField.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
rules['#'+this.id+' div.PageControls a'] = {onclick: this.paginate.bind(this)};
|
||||
rules['#'+this.id+' div.PageControls a'] = {onclick: this.refresh.bind(this)};
|
||||
|
||||
rules['#'+this.id+' table.data tr td.markingcheckbox'] = {
|
||||
onclick : function(e) {
|
||||
@ -71,7 +71,9 @@ TableListField.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* TODO Evaluate server-status before visually deleting (might have caused an error)
|
||||
* Deletes the given dataobject record via an ajax request
|
||||
* to complextablefield->Delete()
|
||||
* @param {Object} e
|
||||
*/
|
||||
deleteRecord: function(e) {
|
||||
var img = Event.element(e);
|
||||
@ -82,16 +84,29 @@ TableListField.prototype = {
|
||||
var confirmed = (this.deleteConfirmMessage != undefined) ? confirm(this.deleteConfirmMessage) : true;
|
||||
if(confirmed)
|
||||
{
|
||||
img.setAttribute("src",'cms/images/network-save.gif'); // TODO doesn't work in Firefox1.5+
|
||||
img.setAttribute("src",'cms/images/network-save.gif'); // TODO doesn't work
|
||||
new Ajax.Request(
|
||||
link.getAttribute("href"),
|
||||
{
|
||||
method: 'post',
|
||||
postBody: 'forceajax=1' + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''),
|
||||
onComplete: function(){
|
||||
Effect.Fade(row);
|
||||
Effect.Fade(
|
||||
row,
|
||||
{
|
||||
afterFinish: function(obj) {
|
||||
// remove row from DOM
|
||||
obj.element.parentNode.removeChild(obj.element);
|
||||
// recalculate summary if needed (assumes that TableListField.js is present)
|
||||
// TODO Proper inheritance
|
||||
if(this._summarise) this._summarise();
|
||||
// custom callback
|
||||
if(this.callback_deleteRecord) this.callback_deleteRecord(e);
|
||||
}.bind(this)
|
||||
}
|
||||
);
|
||||
}.bind(this),
|
||||
onFailure: this.ajaxErrorHandler.bind(this)
|
||||
onFailure: this.ajaxErrorHandler
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -104,22 +119,25 @@ TableListField.prototype = {
|
||||
this._summarise();
|
||||
},
|
||||
|
||||
paginate: function(e) {
|
||||
var el = Event.element(e);
|
||||
|
||||
if(el.nodeName != "a") {
|
||||
var el = Event.findElement(e,"a");
|
||||
refresh: function(e) {
|
||||
if(e) {
|
||||
var el = Event.element(e);
|
||||
if(el.nodeName != "a") el = Event.findElement(e,"a");
|
||||
} else {
|
||||
var el = $(this.id);
|
||||
}
|
||||
new Ajax.Request(
|
||||
el.href,
|
||||
new Ajax.Updater(
|
||||
$(this.id),
|
||||
el.getAttribute('href'),
|
||||
{
|
||||
postBody: 'update=1',
|
||||
onComplete: Ajax.Evaluator,
|
||||
onFailure: this.ajaxErrorHandler.bind(this)
|
||||
onComplete: function() {
|
||||
Behaviour.apply($(this.id))
|
||||
}.bind(this)
|
||||
}
|
||||
);
|
||||
|
||||
Event.stop(e);
|
||||
if(e) Event.stop(e);
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -46,6 +46,12 @@ class SearchContext extends Object {
|
||||
*/
|
||||
protected $filters;
|
||||
|
||||
/**
|
||||
* The logical connective used to join WHERE clauses. Defaults to AND.
|
||||
* @var string
|
||||
*/
|
||||
public $connective = 'AND';
|
||||
|
||||
/**
|
||||
* A key value pair of values that should be searched for.
|
||||
* The keys should match the field names specified in {@link self::$fields}.
|
||||
@ -123,6 +129,8 @@ class SearchContext extends Object {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query->connective = $this->connective;
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
@ -507,6 +507,17 @@ class Permission extends DataObject {
|
||||
return self::$declared_permissions_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the human-readable title for the permission as defined by <code>Permission::declare_permissions</code>
|
||||
*
|
||||
* @param $perm Permission code
|
||||
* @return Label for the given permission, or the permission itself if the label doesn't exist
|
||||
*/
|
||||
public static function get_label_for_permission($perm) {
|
||||
$list = self::get_declared_permissions_list();
|
||||
if(array_key_exists($perm, $list)) return $list[$perm];
|
||||
return $perm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively traverse the nested list of declared permissions and create
|
||||
|
Loading…
x
Reference in New Issue
Block a user