mirror of
https://github.com/symbiote/silverstripe-gridfieldextensions.git
synced 2024-10-22 17:05:39 +02:00
Implement inline creation of records.
* Builds on the editable cols component with GridFieldAddNewInlineButton. * Closes #2.
This commit is contained in:
parent
c10810c3f6
commit
692453bf9b
@ -4,6 +4,7 @@ SilverStripe Grid Field Extensions Module
|
||||
This module provides a number of useful grid field components:
|
||||
|
||||
* `GridFieldAddExistingSearchButton` - a more advanced search form for adding items.
|
||||
* `GridFieldAddNewInlineButton` - builds on `GridFieldEditableColumns` to allow inline creation of records.
|
||||
* `GridFieldAddNewMultiClass` - lets the user select from a list of classes to create a new record from.
|
||||
* `GridFieldEditableColumns` - allows inline editing of records.
|
||||
* `GridFieldOrderableRows` - drag and drop re-ordering of rows.
|
||||
|
142
code/GridFieldAddNewInlineButton.php
Normal file
142
code/GridFieldAddNewInlineButton.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* Builds on the {@link GridFieldEditableColumns} component to allow creating new records.
|
||||
*/
|
||||
class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_SaveHandler {
|
||||
|
||||
private $fragment;
|
||||
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @param string $fragment the fragment to render the button in
|
||||
*/
|
||||
public function __construct($fragment = 'buttons-before-left') {
|
||||
$this->setFragment($fragment);
|
||||
$this->setTitle(_t('GridFieldExtensions.ADD', 'Add'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fragment name this button is rendered into.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFragment() {
|
||||
return $this->fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fragment name this button is rendered into.
|
||||
*
|
||||
* @param string $fragment
|
||||
*/
|
||||
public function setFragment($fragment) {
|
||||
$this->fragment = $fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the button title text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the button title text.
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title) {
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getHTMLFragments($grid) {
|
||||
$class = $grid->getModelClass();
|
||||
$fragment = $this->getFragment();
|
||||
|
||||
if(!$editable = $grid->getConfig()->getComponentByType('GridFieldEditableColumns')) {
|
||||
throw new Exception('Inline adding requires the editable columns component');
|
||||
}
|
||||
|
||||
if(!singleton($class)->canCreate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Requirements::javascript(THIRDPARTY_DIR . '/javascript-templates/tmpl.js');
|
||||
GridFieldExtensions::include_requirements();
|
||||
|
||||
$data = new ArrayData(array(
|
||||
'Title' => $this->getTitle(),
|
||||
));
|
||||
|
||||
return array(
|
||||
$fragment => $data->renderWith(__CLASS__),
|
||||
'after' => $this->getRowTemplate($grid, $editable)
|
||||
);
|
||||
}
|
||||
|
||||
private function getRowTemplate(GridField $grid, GridFieldEditableColumns $editable) {
|
||||
$class = $grid->getModelClass();
|
||||
|
||||
$columns = new ArrayList();
|
||||
$handled = array_keys($editable->getDisplayFields($grid));
|
||||
|
||||
$record = new $class();
|
||||
$fields = $editable->getFields($grid, $record);
|
||||
|
||||
foreach($grid->getColumns() as $column) {
|
||||
if(in_array($column, $handled)) {
|
||||
$field = $fields->dataFieldByName($column);
|
||||
$field->setName(sprintf(
|
||||
'%s[%s][{%%=o.num%%}][%s]', $grid->getName(), __CLASS__, $field->getName()
|
||||
));
|
||||
|
||||
$content = $field->Field();
|
||||
} else {
|
||||
$content = null;
|
||||
}
|
||||
|
||||
$attrs = '';
|
||||
|
||||
foreach($grid->getColumnAttributes($record, $column) as $attr => $val) {
|
||||
$attrs .= sprintf(' %s="%s"', $attr, Convert::raw2att($val));
|
||||
}
|
||||
|
||||
$columns->push(new ArrayData(array(
|
||||
'Content' => $content,
|
||||
'Attributes' => $attrs,
|
||||
'IsActions' => $column == 'Actions'
|
||||
)));
|
||||
}
|
||||
|
||||
return $columns->renderWith('GridFieldAddNewInlineRow');
|
||||
}
|
||||
|
||||
public function handleSave(GridField $grid, DataObjectInterface $record) {
|
||||
$value = $grid->Value();
|
||||
|
||||
if(!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$class = $grid->getModelClass();
|
||||
$editable = $grid->getConfig()->getComponentByType('GridFieldEditableColumns');
|
||||
$form = $editable->getForm($grid, $record);
|
||||
|
||||
if(!singleton($class)->canCreate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($value[__CLASS__] as $fields) {
|
||||
$item = new $class();
|
||||
|
||||
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
||||
$form->saveInto($item);
|
||||
|
||||
$grid->getList()->add($item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -110,7 +110,7 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||
* @param DataObjectInterface $record
|
||||
* @return FieldList
|
||||
*/
|
||||
protected function getFields(GridField $grid, DataObjectInterface $record) {
|
||||
public function getFields(GridField $grid, DataObjectInterface $record) {
|
||||
$cols = $this->getDisplayFields($grid);
|
||||
$fields = new FieldList();
|
||||
$class = $grid->getList()->dataClass();
|
||||
@ -162,7 +162,7 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||
* @param DataObjectInterface $record
|
||||
* @return Form
|
||||
*/
|
||||
protected function getForm(GridField $grid, DataObjectInterface $record) {
|
||||
public function getForm(GridField $grid, DataObjectInterface $record) {
|
||||
$fields = $this->getFields($grid, $record);
|
||||
|
||||
$form = new Form($this, null, $fields, new FieldList());
|
||||
|
@ -86,6 +86,14 @@
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.ss-gridfield-add-new-inline span.readonly {
|
||||
color: #FFF !important;
|
||||
}
|
||||
|
||||
.ss-gridfield-add-new-inline .col-buttons {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/**
|
||||
* GridFieldOrderableRows
|
||||
*/
|
||||
|
@ -72,6 +72,39 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GridFieldAddNewInlineButton
|
||||
*/
|
||||
|
||||
$(".ss-gridfield-add-new-inline").entwine({
|
||||
onclick: function() {
|
||||
var tmpl = window.tmpl;
|
||||
var grid = this.getGridField();
|
||||
var row = grid.find(".ss-gridfield-add-inline-template");
|
||||
var num = grid.data("add-inline-num") || 1;
|
||||
|
||||
tmpl.cache["ss-gridfield-add-inline-template"] = tmpl(row.html());
|
||||
|
||||
grid.find("tbody").append(tmpl("ss-gridfield-add-inline-template", { num: num }));
|
||||
grid.find(".ss-gridfield-no-items").hide();
|
||||
grid.data("add-inline-num", num + 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$(".ss-gridfield-delete-inline").entwine({
|
||||
onclick: function() {
|
||||
var msg = ss.i18n._t("GridFieldExtensions.CONFIRMDEL", "Are you sure you want to delete this?");
|
||||
|
||||
if(confirm(msg)) {
|
||||
this.parents("tr").remove();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GridFieldAddNewMultiClass
|
||||
*/
|
||||
|
3
templates/GridFieldAddNewInlineButton.ss
Normal file
3
templates/GridFieldAddNewInlineButton.ss
Normal file
@ -0,0 +1,3 @@
|
||||
<button href="$Link" class="ss-gridfield-add-new-inline ss-ui-action-constructive ss-ui-button" data-icon="add">
|
||||
$Title
|
||||
</button>
|
13
templates/GridFieldAddNewInlineRow.ss
Normal file
13
templates/GridFieldAddNewInlineRow.ss
Normal file
@ -0,0 +1,13 @@
|
||||
<script type="text/x-tmpl" class="ss-gridfield-add-inline-template">
|
||||
<tr class="ss-gridfield-inline-new">
|
||||
<% loop $Me %>
|
||||
<% if $IsActions %>
|
||||
<td$Attributes>
|
||||
<button class="ss-gridfield-delete-inline gridfield-button-delete ss-ui-button" data-icon="cross-circle"></button>
|
||||
</td>
|
||||
<% else %>
|
||||
<td$Attributes>$Content</td>
|
||||
<% end_if %>
|
||||
<% end_loop %>
|
||||
</tr>
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user