This commit is contained in:
Christopher Tombleson 2015-10-22 03:39:09 +00:00
commit 6f4ef44a4a
3 changed files with 344 additions and 52 deletions

View File

@ -0,0 +1,285 @@
<?php
class GridFieldBulkActionAddHandler extends GridFieldBulkActionHandler {
/**
* RequestHandler allowed actions
* @var array
*/
private static $allowed_actions = array(
'index',
'bulkAddForm',
'recordAddForm'
);
/**
* RequestHandler url => action map
* @var array
*/
private static $url_handlers = array(
'bulkAdd/bulkAddForm' => 'bulkAddForm',
'bulkAdd/recordAddForm' => 'recordAddForm',
'bulkAdd' => 'index'
);
public function Link($action = null)
{
return Controller::join_links(parent::Link(), 'bulkAdd', $action);
}
public function bulkAddForm()
{
$crumbs = $this->Breadcrumbs();
if ($crumbs && $crumbs->count()>=2) {
$one_level_up = $crumbs->offsetGet($crumbs->count()-2);
}
$actions = new FieldList();
$actions->push(
FormAction::create('doSave', _t('GRIDFIELD_BULKMANAGER_ADD_HANDLER.SAVE_BTN_LABEL', 'Save all'))
->setAttribute('id', 'bulkEditingSaveBtn')
->addExtraClass('ss-ui-action-constructive')
->setAttribute('data-icon', 'accept')
->setUseButtonTag(true)
);
$actions->push(
FormAction::create('Cancel', _t('GRIDFIELD_BULKMANAGER_ADD_HANDLER.CANCEL_BTN_LABEL', 'Cancel'))
->setAttribute('id', 'bulkEditingUpdateCancelBtn')
->addExtraClass('ss-ui-action-destructive cms-panel-link')
->setAttribute('data-icon', 'decline')
->setAttribute('href', $one_level_up->Link)
->setUseButtonTag(true)
->setAttribute('src', '')//changes type to image so isn't hooked by default actions handlers
);
$recordsFieldList = new FieldList();
$modelClass = $this->gridField->getModelClass();
$singleton = singleton($modelClass);
$titleModelClass = $singleton->i18n_singular_name();
//some cosmetics
$headerText = _t('GRIDFIELD_BULKMANAGER_ADD_HANDLER.HEADER_TEXT',
'Adding {class}',
array(
'class' => $titleModelClass
)
);
$header = LiteralField::create(
'bulkEditHeader',
'<h1 id="bulkEditHeader">' . $headerText . '</h1>'
);
$recordsFieldList->push($header);
$toggle = LiteralField::create(
'bulkEditToggle',
'<span id="bulkEditToggle">' .
_t('GRIDFIELD_BULKMANAGER_ADD_HANDLER.TOGGLE_ALL_LINK', 'Show/Hide all') . '</span>'
);
$recordsFieldList->push($toggle);
$record = new ListingImage();
for ($i=0; $i < 10; $i++) {
$tempForm = Form::create(
$this, "TempEditForm",
$record->getCMSFields(),
FieldList::create()
);
$fields = $tempForm->Fields();
$fields = $this->filterRecordAddFields($fields, $i);
$toggleField = ToggleCompositeField::create(
'RecordFields_' . $i,
$record->getTitle(),
$fields
)
->setHeadingLevel(4)
->setAttribute('data-id', $i)
->addExtraClass('bulkEditingFieldHolder');
$recordsFieldList->push($toggleField);
}
//recordEditForm name is here to trick SS to pass all subform request to recordEditForm()
$bulkEditForm = Form::create(
$this,
'recordAddForm',
$recordsFieldList,
$actions
);
if ($crumbs && $crumbs->count()>=2) {
$bulkEditForm->Backlink = $one_level_up->Link;
}
//override form action URL back to bulkEditForm
//and add record ids GET var
$bulkEditForm->setAttribute(
'action',
$this->Link('bulkAddForm')
);
return $bulkEditForm;
}
public function recordAddForm()
{
//clone current request : used to figure out what record we are asking
$request = clone $this->request;
$recordInfo = $request->shift();
//shift request till we find the requested field
while ($recordInfo) {
if ($unescapedRecordInfo = $this->unEscapeFieldName($recordInfo)) {
$id = $unescapedRecordInfo['id'];
$fieldName = $unescapedRecordInfo['name'];
$action = $request->shift();
break;
} else {
$recordInfo = $request->shift();
}
}
//generate a form with only that requested record's fields
if ($id) {
$modelClass = $this->gridField->getModelClass();
$record = DataObject::get_by_id($modelClass, $id);
$cmsFields = $record->getCMSFields();
$recordEditingFields = $this->getRecordEditingFields($record);
return Form::create(
$this->gridField,
'recordEditForm',
FieldList::create($recordEditingFields),
FieldList::create()
);
}
}
private function filterRecordAddFields(FieldList $fields, $num)
{
$config = $this->component->getConfig();
$editableFields = $config['editableFields'];
// get all dataFields or just the ones allowed in config
if ($editableFields){
$dataFields = array();
foreach ($editableFields as $fieldName) {
$dataFields[$fieldName] = $fields->dataFieldByName($fieldName);
}
} else {
$dataFields = $fields->dataFields();
}
// escape field names with unique prefix
foreach ($dataFields as $name => $field) {
$field->Name = $this->escapeFieldName($num, $name);
$dataFields[$name] = $field;
}
return $dataFields;
}
protected function escapeFieldName($num, $name)
{
return 'record_' . $num . '_' . $name;
}
protected function unEscapeFieldName($fieldName)
{
$parts = array();
$match = preg_match('/record_(\d+)_(\w+)/i', $fieldName, $parts);
if (!$match) {
return false;
} else {
return array(
'id' => $parts[1],
'name' => $parts[2],
);
}
}
public function index()
{
$form = $this->bulkAddForm();
$form->setTemplate('LeftAndMain_EditForm');
$form->addExtraClass('center cms-content');
$form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
Requirements::javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/GridFieldBulkEditingForm.js');
Requirements::css(BULKEDITTOOLS_MANAGER_PATH . '/css/GridFieldBulkEditingForm.css');
Requirements::add_i18n_javascript(BULKEDITTOOLS_PATH . '/lang/js');
$controller = $this->getToplevelController();
return $controller->customise(array( 'Content' => $form ));
}
public function doSave($data, $form)
{
$className = $this->gridField->list->dataClass;
$singleton = singleton($className);
$formsData = array();
$done = 0;
foreach ($data as $fieldName => $value) {
if ($fieldInfo = $this->unEscapeFieldName($fieldName)) {
if (!isset($formsData[$fieldInfo['id']])) {
$formsData[$fieldInfo['id']] = array();
}
$formsData[$fieldInfo['id']][$fieldInfo['name']] = $value;
}
}
foreach ($formsData as $recordID => $recordData) {
if (!$this->isEmpty($recordData)) {
$record = new $className($recordData);
$id = $record->write();
if ($id) {
$this->gridField->list->add($record);
$done++;
}
}
}
$messageModelClass = (($done > 1) ? $singleton->i18n_plural_name() : $singleton->i18n_singular_name());
$message = _t('GRIDFIELD_BULKMANAGER_ADD_HANDLER.SAVE_RESULT_TEXT',
'{count} {class} created successfully.',
array(
'count' => $done,
'class' => $messageModelClass
)
);
$form->sessionMessage($message, 'good');
return Controller::curr()->redirect($this->Link());
}
private function isEmpty($data)
{
$empty = true;
$ignore_fields = array('SecurityID', 'Image');
foreach ($data as $name => $value) {
if (!in_array($name, $ignore_fields) && !empty($value)) {
$empty = false;
}
}
return $empty;
}
}

View File

@ -17,8 +17,8 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
* @var array
*/
protected $config = array(
'editableFields' => null,
'actions' => array()
'editableFields' => null,
'actions' => array()
);
@ -29,39 +29,48 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
* @param boolean $defaultActions Use default actions list. False to start fresh.
*/
public function __construct($editableFields = null, $defaultActions = true)
{
if ( $editableFields != null ) $this->setConfig ( 'editableFields', $editableFields );
{
if ($editableFields != null) $this->setConfig ('editableFields', $editableFields);
if ( $defaultActions )
if ($defaultActions)
{
$this->config['actions'] = array(
'bulkEdit' => array(
'label' => _t('GRIDFIELD_BULK_MANAGER.EDIT_SELECT_LABEL', 'Edit'),
'handler' => 'GridFieldBulkActionEditHandler',
'config' => array(
'bulkAdd' => array(
'label' => _t('GRIDFIELD_BULK_MANAGER.ADD_SELECT_LABEL', 'Add'),
'handler' => 'GridFieldBulkActionAddHandler',
'config' => array(
'isAjax' => false,
'icon' => 'add',
'isDestructive' => false
)
),
'bulkEdit' => array(
'label' => _t('GRIDFIELD_BULK_MANAGER.EDIT_SELECT_LABEL', 'Edit'),
'handler' => 'GridFieldBulkActionEditHandler',
'config' => array(
'isAjax' => false,
'icon' => 'pencil',
'isDestructive' => false
)
),
'unLink' => array(
'label' => _t('GRIDFIELD_BULK_MANAGER.UNLINK_SELECT_LABEL', 'UnLink'),
'handler' => 'GridFieldBulkActionUnLinkHandler',
'config' => array(
),
'unLink' => array(
'label' => _t('GRIDFIELD_BULK_MANAGER.UNLINK_SELECT_LABEL', 'UnLink'),
'handler' => 'GridFieldBulkActionUnLinkHandler',
'config' => array(
'isAjax' => true,
'icon' => 'chain--minus',
'isDestructive' => false
)
),
'delete' => array(
'label' => _t('GRIDFIELD_BULK_MANAGER.DELETE_SELECT_LABEL', 'Delete'),
'handler' => 'GridFieldBulkActionDeleteHandler',
'config' => array(
),
'delete' => array(
'label' => _t('GRIDFIELD_BULK_MANAGER.DELETE_SELECT_LABEL', 'Delete'),
'handler' => 'GridFieldBulkActionDeleteHandler',
'config' => array(
'isAjax' => true,
'icon' => 'decline',
'isDestructive' => true
)
)
)
);
}
}
@ -160,10 +169,10 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
}
$this->config['actions'][$name] = array(
'label' => $label,
'handler' => $handler,
'config' => $config
);
'label' => $label,
'handler' => $handler,
'config' => $config
);
return $this;
}
@ -177,12 +186,11 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
*/
function removeBulkAction($name)
{
if ( !array_key_exists($name, $this->config['actions']) )
{
if (!array_key_exists($name, $this->config['actions'])) {
user_error("Bulk action '$name' doesn't exists.", E_USER_ERROR);
}
unset( $this->config['actions'][$name] );
unset($this->config['actions'][$name]);
return $this;
}
@ -228,8 +236,8 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
function getColumnContent($gridField, $record, $columnName)
{
$cb = CheckboxField::create('bulkSelect_'.$record->ID)
->addExtraClass('bulkSelect no-change-track')
->setAttribute('data-record', $record->ID);
->addExtraClass('bulkSelect no-change-track')
->setAttribute('data-record', $record->ID);
return $cb->Field();
}
@ -263,7 +271,6 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
}
/* **********************************************************************
* GridField_HTMLProvider
* */
@ -279,18 +286,16 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
Requirements::javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/GridFieldBulkManager.js');
Requirements::add_i18n_javascript(BULKEDITTOOLS_PATH . '/lang/js');
if ( !count($this->config['actions']) )
{
if (!count($this->config['actions'])) {
user_error("Trying to use GridFieldBulkManager without any bulk action.", E_USER_ERROR);
}
$actionsListSource = array();
$actionsConfig = array();
foreach ($this->config['actions'] as $action => $actionData)
{
$actionsListSource[$action] = $actionData['label'];
$actionsConfig[$action] = $actionData['config'];
foreach ($this->config['actions'] as $action => $actionData) {
$actionsListSource[$action] = $actionData['label'];
$actionsConfig[$action] = $actionData['config'];
}
reset($this->config['actions']);
@ -301,19 +306,19 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
->setAttribute('class', 'bulkActionName no-change-track')
->setAttribute('id', '');
$templateData = array(
'Menu' => $dropDownActionsList->FieldHolder(),
'Button' => array(
'Label' => _t('GRIDFIELD_BULK_MANAGER.ACTION_BTN_LABEL', 'Go'),
'DataURL' => $gridField->Link('bulkAction'),
'Icon' => $this->config['actions'][$firstAction]['config']['icon'],
'DataConfig' => htmlspecialchars(json_encode($actionsConfig), ENT_QUOTES, 'UTF-8')
),
'Select' => array(
'Label' => _t('GRIDFIELD_BULK_MANAGER.SELECT_ALL_LABEL', 'Select all')
),
'Colspan' => (count($gridField->getColumns()) - 1)
);
$templateData = array(
'Menu' => $dropDownActionsList->FieldHolder(),
'Button' => array(
'Label' => _t('GRIDFIELD_BULK_MANAGER.ACTION_BTN_LABEL', 'Go'),
'DataURL' => $gridField->Link('bulkAction'),
'Icon' => $this->config['actions'][$firstAction]['config']['icon'],
'DataConfig' => htmlspecialchars(json_encode($actionsConfig), ENT_QUOTES, 'UTF-8')
),
'Select' => array(
'Label' => _t('GRIDFIELD_BULK_MANAGER.SELECT_ALL_LABEL', 'Select all')
),
'Colspan' => (count($gridField->getColumns()) - 1)
);
$templateData = new ArrayData($templateData);

View File

@ -14,6 +14,7 @@
targets = ['.filter-header', '.sortable-header'],
$target = $parent.find(targets.join(',')),
$component = this.clone(),
index = $tr.index(this),
newIndex = $tr.length - 1
;
@ -28,8 +29,9 @@
if ( index > newIndex )
{
$tr.eq(newIndex).insertAfter($(this));
}
$component.insertBefore($tr.eq(newIndex));
this.remove();
}
},
onunmatch: function(){}
});
@ -191,7 +193,7 @@
data = { records: ids }
;
if ( ids.length <= 0 )
if ( ids.length <= 0 && action != 'bulkAdd' )
{
alert( ss.i18n._t('GRIDFIELD_BULK_MANAGER.BULKACTION_EMPTY_SELECT') );
return;