mirror of
https://github.com/silverstripe/silverstripe-reports
synced 2024-10-22 11:05:53 +02: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/cms/trunk@60204 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
05ad3c8e1c
commit
83fff5f1c1
@ -42,6 +42,17 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
'delete'
|
'delete'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model object currently in manipulation queue. Used for updating Link to point
|
||||||
|
* to the correct generic data object in generated URLs.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $currentModel = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the model admin interface. Sets up embedded jquery libraries and requisite plugins
|
||||||
|
*/
|
||||||
public function init() {
|
public function init() {
|
||||||
parent::init();
|
parent::init();
|
||||||
|
|
||||||
@ -50,13 +61,34 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
user_error('ModelAdmin::init(): Invalid Model class', E_USER_ERROR);
|
user_error('ModelAdmin::init(): Invalid Model class', E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Requirements::css('cms/css/ModelAdmin.css');
|
Requirements::css('cms/css/ModelAdmin.css'); // standard layout formatting for management UI
|
||||||
|
Requirements::css('cms/css/silverstripe.tabs.css'); // follows the jQuery UI theme conventions
|
||||||
|
|
||||||
|
Requirements::javascript('jsparty/jquery/jquery.js');
|
||||||
|
Requirements::javascript('jsparty/jquery/livequery/jquery.livequery.js');
|
||||||
|
Requirements::javascript('jsparty/jquery/ui/ui/ui.base.js');
|
||||||
|
Requirements::javascript('jsparty/jquery/ui/ui/ui.tabs.js');
|
||||||
|
Requirements::javascript('jsparty/jquery/ui/plugins/form/jquery.form.js');
|
||||||
|
Requirements::javascript('cms/javascript/ModelAdmin.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add mappings for generic form constructors to automatically delegate to a scaffolded form object.
|
||||||
|
*/
|
||||||
|
function defineMethods() {
|
||||||
|
parent::defineMethods();
|
||||||
|
foreach($this->getManagedModels() as $class) {
|
||||||
|
$this->addWrapperMethod('SearchForm_' . $class, 'getSearchFormForModel');
|
||||||
|
$this->addWrapperMethod('AddForm_' . $class, 'getAddFormForModel');
|
||||||
|
$this->addWrapperMethod('EditForm_' . $class, 'getEditFormForModel');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return default link to this controller
|
* Return default link to this controller
|
||||||
*
|
*
|
||||||
* @todo We've specified this in Director::addRules(), why repeat?
|
* @todo extract full URL binding from Director::addRules so that it's not tied to 'admin/crm'
|
||||||
|
* @todo is there a way of removing the dependency on this method from the Form?
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -91,13 +123,11 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo documentation
|
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param Form $form
|
|
||||||
*/
|
*/
|
||||||
public function save($data, $form) {
|
public function save($data, $form) {
|
||||||
// @todo implementation
|
Debug::dump($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +142,7 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
|
|
||||||
$form = new Form(
|
$form = new Form(
|
||||||
$this,
|
$this,
|
||||||
'AddForm_add',
|
"AddForm",
|
||||||
new FieldSet(
|
new FieldSet(
|
||||||
new DropdownField('ClassName', 'Type', $modelMap)
|
new DropdownField('ClassName', 'Type', $modelMap)
|
||||||
),
|
),
|
||||||
@ -120,6 +150,7 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
new FormAction('add', _t('GenericDataAdmin.CREATE'))
|
new FormAction('add', _t('GenericDataAdmin.CREATE'))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
$form->setFormMethod('get');
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,21 +187,14 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
*/
|
*/
|
||||||
protected function getEditForm($modelClass) {
|
protected function getEditForm($modelClass) {
|
||||||
$modelObj = singleton($modelClass);
|
$modelObj = singleton($modelClass);
|
||||||
|
$formName = "EditForm_$modelClass";
|
||||||
$fields = $this->getFieldsForModel($modelObj);
|
$fields = $this->getFieldsForModel($modelObj);
|
||||||
|
$this->getComponentFieldsForModel($modelObj, $fields);
|
||||||
$actions = $this->getActionsForModel($modelObj);
|
$actions = $this->getActionsForModel($modelObj);
|
||||||
|
|
||||||
$validator = $this->getValidatorForModel($modelObj);
|
$validator = $this->getValidatorForModel($modelObj);
|
||||||
|
// necessary because of overriding the form action - NEED TO VERIFY THIS
|
||||||
$form = new Form(
|
$fields->push(new HiddenField("executeForm", $formName));
|
||||||
$this,
|
$form = new Form($this, $formName, $fields, $actions, $validator);
|
||||||
'ModelEditForm',
|
|
||||||
$fields,
|
|
||||||
$actions,
|
|
||||||
$validator
|
|
||||||
);
|
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +221,28 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
* @return FieldSet
|
* @return FieldSet
|
||||||
*/
|
*/
|
||||||
protected function getFieldsForModel($modelObj) {
|
protected function getFieldsForModel($modelObj) {
|
||||||
return $modelObj->getCMSFields();
|
$fields = $modelObj->getCMSFields();
|
||||||
|
if (!$fields->dataFieldByName('ID')) {
|
||||||
|
$fields->push(new HiddenField('ID'));
|
||||||
|
}
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update: complex table field generation moved into controller - could be
|
||||||
|
* in the DataObject scaffolding?
|
||||||
|
*
|
||||||
|
* @param unknown_type $modelObj
|
||||||
|
* @return FieldSet of ComplexTableFields
|
||||||
|
*/
|
||||||
|
protected function getComponentFieldsForModel($modelObj, $fieldSet) {
|
||||||
|
foreach($modelObj->has_many() as $relationship => $component) {
|
||||||
|
|
||||||
|
$relationshipFields = array_keys(singleton($component)->searchableFields());
|
||||||
|
$fieldSet->push(new ComplexTableField($this, $relationship, $component, $relationshipFields));
|
||||||
|
|
||||||
|
}
|
||||||
|
return $fieldSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,7 +259,6 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
new FormAction('save', _t('GenericDataAdmin.SAVE')),
|
new FormAction('save', _t('GenericDataAdmin.SAVE')),
|
||||||
new FormAction('delete', _t('GenericDataAdmin.DELETE'))
|
new FormAction('delete', _t('GenericDataAdmin.DELETE'))
|
||||||
);
|
);
|
||||||
|
|
||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,18 +282,19 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
* @return FieldSet
|
* @return FieldSet
|
||||||
*/
|
*/
|
||||||
protected function getSearchFormForModel($modelClass) {
|
protected function getSearchFormForModel($modelClass) {
|
||||||
|
if(substr($modelClass,0,11) == 'SearchForm_') $modelClass = substr($modelClass, 11);
|
||||||
|
|
||||||
$context = singleton($modelClass)->getDefaultSearchContext();
|
$context = singleton($modelClass)->getDefaultSearchContext();
|
||||||
|
|
||||||
$form = new Form(
|
$form = new Form(
|
||||||
$this,
|
$this,
|
||||||
"SearchForm_search_{$modelClass}",
|
"SearchForm_$modelClass",
|
||||||
$context->getSearchFields(),
|
$context->getSearchFields(),
|
||||||
new FieldSet(
|
new FieldSet(
|
||||||
new FormAction('search', _t('MemberTableField.SEARCH'))
|
new FormAction('search', _t('MemberTableField.SEARCH'))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
//can't set generic search form as GET because of weirdness with FormObjectLink
|
$form->setFormMethod('get');
|
||||||
//$form->setFormMethod('get');
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,25 +302,19 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
* Overwrite the default form action with the path to the DataObject filter
|
* Overwrite the default form action with the path to the DataObject filter
|
||||||
* (relies on the search form having the specifically named id as 'SearchForm_DataObject')
|
* (relies on the search form having the specifically named id as 'SearchForm_DataObject')
|
||||||
*
|
*
|
||||||
* @todo extract hard-coded prefix and generate from Director settings
|
* @todo override default linking to add DataObject based URI paths
|
||||||
*/
|
*/
|
||||||
function FormObjectLink($formName) {
|
function FormObjectLink($formName) {
|
||||||
$segments = explode('_', $formName);
|
return $this->Link();
|
||||||
if (count($segments) == 3) {
|
|
||||||
return Director::absoluteBaseURL()."admin/crm/{$segments[1]}/{$segments[2]}";
|
|
||||||
} elseif (count($segments) == 2) {
|
|
||||||
return Director::absoluteBaseURL()."admin/crm/{$segments[1]}";
|
|
||||||
} else {
|
|
||||||
return "?executeForm=$formName";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to render a data object collection, using the model context to provide filters
|
* Action to render a data object collection, using the model context to provide filters
|
||||||
* and paging.
|
* and paging.
|
||||||
*/
|
*/
|
||||||
function search() {
|
function search($data, $form) {
|
||||||
$className = $this->urlParams['ClassName'];
|
$className = $this->urlParams['ClassName'];
|
||||||
|
Debug::dump($className);
|
||||||
if (in_array($className, $this->getManagedModels())) {
|
if (in_array($className, $this->getManagedModels())) {
|
||||||
$model = singleton($className);
|
$model = singleton($className);
|
||||||
// @todo need to filter post vars
|
// @todo need to filter post vars
|
||||||
@ -306,7 +345,7 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
* View a generic model using a form object to render a partial HTML
|
* View a generic model using a form object to render a partial HTML
|
||||||
* fragment to be embedded via Ajax calls.
|
* fragment to be embedded via Ajax calls.
|
||||||
*/
|
*/
|
||||||
function view() {
|
function show() {
|
||||||
$className = $this->urlParams['ClassName'];
|
$className = $this->urlParams['ClassName'];
|
||||||
$ID = $this->urlParams['ID'];
|
$ID = $this->urlParams['ID'];
|
||||||
|
|
||||||
@ -314,14 +353,15 @@ abstract class ModelAdmin extends LeftAndMain {
|
|||||||
|
|
||||||
$model = DataObject::get_by_id($className, $ID);
|
$model = DataObject::get_by_id($className, $ID);
|
||||||
|
|
||||||
$fields = $model->getCMSFields();
|
/*$fields = $model->getCMSFields();
|
||||||
|
|
||||||
$actions = new FieldSet(
|
$actions = new FieldSet(
|
||||||
new FormAction('save', 'Save')
|
new FormAction('save', 'Save')
|
||||||
);
|
);
|
||||||
|
|
||||||
$form = new Form($this, $className, $fields, $actions);
|
$form = new Form($this, $className, $fields, $actions);
|
||||||
$form->makeReadonly();
|
$form->makeReadonly();*/
|
||||||
|
$form = $this->getEditForm($className);
|
||||||
$form->loadNonBlankDataFrom($model);
|
$form->loadNonBlankDataFrom($model);
|
||||||
return $form->forTemplate();
|
return $form->forTemplate();
|
||||||
}
|
}
|
||||||
|
31
css/silverstripe.tabs.css
Normal file
31
css/silverstripe.tabs.css
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* SilverStripe specific styles that map to elements from the jQuery UI theme.
|
||||||
|
*
|
||||||
|
* This is not a fully functional tab module, but the file naming convention reflects
|
||||||
|
* the jQuery theme format
|
||||||
|
*
|
||||||
|
* @todo move generic tab styles into this file
|
||||||
|
* @todo add to silverstripe specific branch of /jsparty/jquery/ui/themes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Caution! Ensure accessibility in print and other media types... */
|
||||||
|
@media projection, screen { /* Use class for showing/hiding tab content, so that visibility can be better controlled in different media types... */
|
||||||
|
.ui-tabs-hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide useless elements in print layouts... */
|
||||||
|
@media print {
|
||||||
|
.ui-tabs-nav {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stuff for search forms
|
||||||
|
*/
|
||||||
|
.loading {
|
||||||
|
cursor:hourglass;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
jQuery(document).ready(function() {
|
||||||
|
|
||||||
|
function showRecord(uri) {
|
||||||
|
jQuery.get(uri, function(result){
|
||||||
|
jQuery('#right').html(result);
|
||||||
|
Behaviour.apply();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveRecord(uri, data) {
|
||||||
|
//jQuery.post(uri, data, function(result) {)
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery('#AddForm_holder form').submit(function(){
|
||||||
|
className = jQuery('select option:selected', this).val();
|
||||||
|
// @todo remove dependency on hardcoded URL path
|
||||||
|
requestPath = jQuery(this).attr('action') + '/add/' + className;
|
||||||
|
showRecord(requestPath);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// attach generic action handler to all forms displayed in the #right panel
|
||||||
|
jQuery('#right .action').click(function(){
|
||||||
|
alert('do something here');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery('#SearchForm_holder').tabs();
|
||||||
|
|
||||||
|
jQuery('.tab form').submit(function(){
|
||||||
|
form = jQuery(this);
|
||||||
|
|
||||||
|
var data = {};
|
||||||
|
jQuery('*[name]', form).each(function(){
|
||||||
|
var t = jQuery(this);
|
||||||
|
var val = (t.attr('type') == 'checkbox') ? (t.attr('checked') == true) ? 1 : 0 : t.val();
|
||||||
|
data[t.attr('name')] = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery.get(form.attr('action'), data, function(result){
|
||||||
|
jQuery('#ResultTable_holder').html(result);
|
||||||
|
jQuery('#ResultTable_holder td').click(function(){
|
||||||
|
td = jQuery(this);
|
||||||
|
showRecord(td.parent().attr('id'));
|
||||||
|
td.parent().parent().find('td').removeClass('active');
|
||||||
|
td.addClass('active').siblings().addClass('active');
|
||||||
|
}).hover(function(){
|
||||||
|
jQuery(this).addClass('over').siblings().addClass('over')
|
||||||
|
}, function(){
|
||||||
|
jQuery(this).removeClass('over').siblings().removeClass('over')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user