From 92a35354556920e6e4fd6a3eb5ed5bc84aa35f50 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Fri, 9 Mar 2012 16:48:08 +1300 Subject: [PATCH 1/5] API CHANGE: Added targetFragment argument to GridFieldExportButton to control button placement. Moved search fields to 2nd argument. --- forms/gridfield/GridFieldExportButton.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/forms/gridfield/GridFieldExportButton.php b/forms/gridfield/GridFieldExportButton.php index f853041ce..021bdecb3 100644 --- a/forms/gridfield/GridFieldExportButton.php +++ b/forms/gridfield/GridFieldExportButton.php @@ -27,11 +27,18 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP * @var boolean */ protected $csvHasHeader = true; + + /** + * Fragment to write the button to + */ + protected $targetFragment; /** - * @param array + * @param string $targetFragment The HTML fragment to write the button into + * @param array $exportColumns The columns to include in the export */ - public function __construct($exportColumns = null) { + public function __construct($targetFragment = "after", $exportColumns = null) { + $this->targetFragment = $targetFragment; $this->exportColumns = $exportColumns; } @@ -49,7 +56,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP $button->setAttribute('data-icon', 'download-csv'); $button->addExtraClass('no-ajax'); return array( - 'after' => '

' . $button->Field() . '

', + $this->targetFragment => '

' . $button->Field() . '

', ); } From d795a55bdb7d83a1f857515cdce69bacb80c67ea Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Fri, 9 Mar 2012 16:49:18 +1300 Subject: [PATCH 2/5] API CHANGE: Removed 'add new' button from GridFieldToolbarHeader, instead opting to include two HTML fragments: toolbar-header-left and toolbar-header-right. --- css/GridField.css | 3 +- forms/gridfield/GridFieldToolbarHeader.php | 53 ++------------------ scss/GridField.scss | 8 ++- templates/Includes/GridFieldToolbarHeader.ss | 6 ++- 4 files changed, 17 insertions(+), 53 deletions(-) diff --git a/css/GridField.css b/css/GridField.css index 16b55b33b..5fbbdd8b8 100644 --- a/css/GridField.css +++ b/css/GridField.css @@ -17,7 +17,8 @@ .cms table.ss-gridfield-table tr.title { -moz-border-radius-topleft: 7px; -webkit-border-top-left-radius: 7px; -o-border-top-left-radius: 7px; -ms-border-top-left-radius: 7px; -khtml-border-top-left-radius: 7px; border-top-left-radius: 7px; -moz-border-radius-topright: 7px; -webkit-border-top-right-radius: 7px; -o-border-top-right-radius: 7px; -ms-border-top-right-radius: 7px; -khtml-border-top-right-radius: 7px; border-top-right-radius: 7px; } .cms table.ss-gridfield-table tr.title th { position: relative; background: #7f9198; border-top: 1px solid rgba(0, 0, 0, 0.1); padding: 5px; min-height: 40px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #b1c0c5), color-stop(100%, #7f9198)); background-image: -webkit-linear-gradient(#b1c0c5, #7f9198); background-image: -moz-linear-gradient(#b1c0c5, #7f9198); background-image: -o-linear-gradient(#b1c0c5, #7f9198); background-image: -ms-linear-gradient(#b1c0c5, #7f9198); background-image: linear-gradient(#b1c0c5, #7f9198); -moz-border-radius-topleft: 7px; -webkit-border-top-left-radius: 7px; -o-border-top-left-radius: 7px; -ms-border-top-left-radius: 7px; -khtml-border-top-left-radius: 7px; border-top-left-radius: 7px; -moz-border-radius-topright: 7px; -webkit-border-top-right-radius: 7px; -o-border-top-right-radius: 7px; -ms-border-top-right-radius: 7px; -khtml-border-top-right-radius: 7px; border-top-right-radius: 7px; text-shadow: rgba(0, 0, 0, 0.3) 0px -1px 0; } .cms table.ss-gridfield-table tr.title th h2 { padding: 0px; font-size: 16.8px; color: #fff; margin: 3px 8px 0; display: inline-block; } -.cms table.ss-gridfield-table tr.title th .new { font-size: 14.4px; float: right; } +.cms table.ss-gridfield-table tr.title th .right > * { float: right; font-size: 14.4px; } +.cms table.ss-gridfield-table tr.title th .left > * { float: left; font-size: 14.4px; } .cms table.ss-gridfield-table tr.sortable-header { background: #bac8ce; } .cms table.ss-gridfield-table tr.sortable-header th { padding: 0px; } .cms table.ss-gridfield-table tr:hover { background: #FFFAD6 !important; } diff --git a/forms/gridfield/GridFieldToolbarHeader.php b/forms/gridfield/GridFieldToolbarHeader.php index e8b140e28..e9830ff67 100644 --- a/forms/gridfield/GridFieldToolbarHeader.php +++ b/forms/gridfield/GridFieldToolbarHeader.php @@ -2,62 +2,17 @@ /** * Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds a header title to that field. * The header serves double duty of displaying the name of the data the GridField is showing and - * providing an "add new" button to create new object instances. - * - * The reason for making "add new" part of the title component is to make it easier for the user to tell - * which "add new" button belongs to which datagrid, in the case where multiple datagrids are on a single - * page. It is also a more efficient use of screen space. - * - * The default DataGrid includes the add button. You can hide the button by setting a boolean using the - * setNewEnabled() method + * providing a space for actions on this grid. + * + * This header provides two new HTML fragment spaces: 'toolbar-header-left' and 'toolbar-header-right'. * * @package sapphire * @subpackage gridfield */ class GridFieldToolbarHeader implements GridField_HTMLProvider { - - /** - * - * @var bool - */ - protected $newEnabled = true; - - /** - * - * @var type - */ - protected $gridField = null; - public function getHTMLFragments( $gridField) { - $this->gridField = $gridField; return array( - 'header' => $gridField->customise(array( - 'NewLink' => Controller::join_links($gridField->Link('item'), 'new'), - 'NewEnabled' => $this->getNewEnabled() - ))->renderWith('GridFieldToolbarHeader') + 'header' => $gridField->renderWith('GridFieldToolbarHeader') ); } - - /** - * Returns whether or not the "add new" button will appear when rendering this DataGrid title - * @return bool - */ - public function getNewEnabled() { - if($this->gridField) { - $model = singleton($this->gridField->getModelClass()); - if(!$model->canCreate()) { - return false; - } - } - - return $this->newEnabled; - } - - /** - * Enable or disable the "add new" button to add new DataGrid object instances - * @param $enabled - */ - public function setNewEnabled($enabled) { - $this->newEnabled = $enabled; - } } diff --git a/scss/GridField.scss b/scss/GridField.scss index 685a8de4d..cd5aa8b73 100644 --- a/scss/GridField.scss +++ b/scss/GridField.scss @@ -139,9 +139,13 @@ $gf_grid_x: 16px; margin:$gf_grid_y/4 $gf_grid_x/2 0; display:inline-block; } - .new{ - font-size: $gf_grid_y*1.2; + .right > * { float: right; + font-size: $gf_grid_y*1.2; + } + .left > * { + float: left; + font-size: $gf_grid_y*1.2; } } } diff --git a/templates/Includes/GridFieldToolbarHeader.ss b/templates/Includes/GridFieldToolbarHeader.ss index 81f6b4817..31548aa26 100644 --- a/templates/Includes/GridFieldToolbarHeader.ss +++ b/templates/Includes/GridFieldToolbarHeader.ss @@ -1,3 +1,7 @@ -

$Title

<% if NewEnabled %> <% _t('GridField.AddNew', 'Add New') %><% end_if %> + + <% if Title %>

$Title

<% end_if %> +
\$DefineFragment(toolbar-header-left)
+
\$DefineFragment(toolbar-header-right)
+ \ No newline at end of file From 12618e20279f7b6b2769709f3efed65907da186c Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Fri, 9 Mar 2012 16:50:05 +1300 Subject: [PATCH 3/5] API CHANGE: Added targetFragment argument to GridFieldAddExistingAutocompleter, so that its location can be changed. Updated CSS and HTML to allow for this. --- css/GridField.css | 2 ++ .../GridFieldAddExistingAutocompleter.php | 17 +++++++++++++---- scss/GridField.scss | 9 +++++++++ .../GridFieldAddExistingAutocompleter.ss | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/css/GridField.css b/css/GridField.css index 5fbbdd8b8..74d34fe2b 100644 --- a/css/GridField.css +++ b/css/GridField.css @@ -2,6 +2,8 @@ .cms .ss-gridfield > div { margin-bottom: 35px; } .cms .ss-gridfield[data-selectable] tr.ui-selected, .cms .ss-gridfield[data-selectable] tr.ui-selecting { background: #FFFAD6 !important; } .cms .ss-gridfield[data-selectable] td { cursor: pointer; } +.cms .ss-gridfield .add-existing-autocompleter { width: 500px; } +.cms .ss-gridfield .add-existing-autocompleter input.relation-search { width: 380px; } .cms table.ss-gridfield-table { display: table; box-shadow: none; padding: 0; border-collapse: separate; border-bottom: 0 none; width: 100%; } .cms table.ss-gridfield-table thead { color: #1d2224; background: transparent; } .cms table.ss-gridfield-table thead tr.filter-header .fieldgroup { max-width: 512px; } diff --git a/forms/gridfield/GridFieldAddExistingAutocompleter.php b/forms/gridfield/GridFieldAddExistingAutocompleter.php index 04f81e832..58e9b5611 100755 --- a/forms/gridfield/GridFieldAddExistingAutocompleter.php +++ b/forms/gridfield/GridFieldAddExistingAutocompleter.php @@ -15,7 +15,12 @@ class GridFieldAddExistingAutocompleter implements GridField_HTMLProvider, GridF * @var string $itemClass */ protected $itemClass = 'GridFieldAddExistingAutocompleter'; - + + /** + * The HTML fragment to write this component into + */ + protected $targetFragment; + /** * Which columns that should be used for doing a "StartsWith" search. * If multiple fields are provided, the filtering is performed non-exclusive. @@ -40,7 +45,8 @@ class GridFieldAddExistingAutocompleter implements GridField_HTMLProvider, GridF * * @param array $searchFields Which fields on the object in the list should be searched */ - public function __construct($searchFields = null) { + public function __construct($targetFragment = 'before', $searchFields = null) { + $this->targetFragment = $targetFragment; $this->searchFields = (array)$searchFields; } @@ -67,7 +73,7 @@ class GridFieldAddExistingAutocompleter implements GridField_HTMLProvider, GridF $findAction = new GridField_FormAction($gridField, 'gridfield_relationfind', _t('GridField.Find', "Find"), 'find', 'find'); $findAction->setAttribute('data-icon', 'relationfind'); - $addAction = new GridField_FormAction($gridField, 'gridfield_relationadd', _t('GridField.LinkExisting', "Link Exisiting"), 'addto', 'addto'); + $addAction = new GridField_FormAction($gridField, 'gridfield_relationadd', _t('GridField.LinkExisting', "Link Existing"), 'addto', 'addto'); $addAction->setAttribute('data-icon', 'chain--plus'); // If an object is not found, disable the action @@ -78,7 +84,10 @@ class GridFieldAddExistingAutocompleter implements GridField_HTMLProvider, GridF $forTemplate->Fields->push($searchField); $forTemplate->Fields->push($findAction); $forTemplate->Fields->push($addAction); - return array('before' => $forTemplate->renderWith($this->itemClass)); + + return array( + $this->targetFragment => $forTemplate->renderWith($this->itemClass) + ); } /** diff --git a/scss/GridField.scss b/scss/GridField.scss index cd5aa8b73..3df89a5e2 100644 --- a/scss/GridField.scss +++ b/scss/GridField.scss @@ -53,6 +53,15 @@ $gf_grid_x: 16px; } } } + + .ss-gridfield { + .add-existing-autocompleter { + input.relation-search { + width: 380px; + } + width: 500px; + } + } table.ss-gridfield-table { display: table; diff --git a/templates/Includes/GridFieldAddExistingAutocompleter.ss b/templates/Includes/GridFieldAddExistingAutocompleter.ss index f50e6385f..21fc9ad93 100644 --- a/templates/Includes/GridFieldAddExistingAutocompleter.ss +++ b/templates/Includes/GridFieldAddExistingAutocompleter.ss @@ -1,4 +1,4 @@ -
<% control Fields %> +
<% control Fields %> $Field <% end_control %>
\ No newline at end of file From 818c341c57bc1f3a2e56764389e3a9be79c23bd8 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Fri, 9 Mar 2012 16:50:43 +1300 Subject: [PATCH 4/5] API CHANGE: Created GridFieldAddNewButton, replacing the one that was previously hardcoded in GridFieldToolbarHeader --- forms/gridfield/GridFieldAddNewButton.php | 24 +++++++++++++++++++++ templates/Includes/GridFieldAddNewButton.ss | 1 + 2 files changed, 25 insertions(+) create mode 100644 forms/gridfield/GridFieldAddNewButton.php create mode 100644 templates/Includes/GridFieldAddNewButton.ss diff --git a/forms/gridfield/GridFieldAddNewButton.php b/forms/gridfield/GridFieldAddNewButton.php new file mode 100644 index 000000000..9967cf436 --- /dev/null +++ b/forms/gridfield/GridFieldAddNewButton.php @@ -0,0 +1,24 @@ +targetFragment = $targetFragment; + } + + public function getHTMLFragments($gridField) { + $data = new ArrayData(array( + 'NewLink' => Controller::join_links($gridField->Link('item'), 'new'), + )); + return array( + $this->targetFragment => $data->renderWith('GridFieldAddNewbutton'), + ); + } + +} \ No newline at end of file diff --git a/templates/Includes/GridFieldAddNewButton.ss b/templates/Includes/GridFieldAddNewButton.ss new file mode 100644 index 000000000..75a9bb931 --- /dev/null +++ b/templates/Includes/GridFieldAddNewButton.ss @@ -0,0 +1 @@ +<% _t('GridField.AddNew', 'Add New') %> \ No newline at end of file From 1f7263e55e21205f07e15cc352b02b3de53f5c03 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Fri, 9 Mar 2012 16:51:09 +1300 Subject: [PATCH 5/5] ENHANCEMENT: Updated default many-many grid field to show "add existing" and "add new" side by side. --- forms/gridfield/GridFieldConfig.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/forms/gridfield/GridFieldConfig.php b/forms/gridfield/GridFieldConfig.php index b6da4213f..2d7852774 100755 --- a/forms/gridfield/GridFieldConfig.php +++ b/forms/gridfield/GridFieldConfig.php @@ -163,6 +163,7 @@ class GridFieldConfig_RecordEditor extends GridFieldConfig { */ public function __construct($itemsPerPage=null) { $this->addComponent(new GridFieldToolbarHeader()); + $this->addComponent(new GridFieldAddNewButton('toolbar-header-right')); $this->addComponent($sort = new GridFieldSortableHeader()); $this->addComponent($filter = new GridFieldFilterHeader()); $this->addComponent(new GridFieldDataColumns()); @@ -209,7 +210,8 @@ class GridFieldConfig_RelationEditor extends GridFieldConfig { */ public function __construct($itemsPerPage=null) { $this->addComponent(new GridFieldToolbarHeader()); - $this->addComponent(new GridFieldAddExistingAutocompleter()); + $this->addComponent(new GridFieldAddExistingAutocompleter('toolbar-header-left')); + $this->addComponent(new GridFieldAddNewButton('toolbar-header-right')); $this->addComponent($sort = new GridFieldSortableHeader()); $this->addComponent($filter = new GridFieldFilterHeader()); $this->addComponent(new GridFieldDataColumns());