From 39372497df75eca5982f8b90aad7d7251ff63267 Mon Sep 17 00:00:00 2001 From: Stig Lindqvist Date: Mon, 9 Jan 2012 18:21:14 +1300 Subject: [PATCH] BUGFIX GridField_Actions did not work in more complex Forms with tabsets (i.e SecurityAdmin) when using GridField_Action BUGFIX Empty GridState data causes isset error BUGFIX Last field of GridFieldFilter outputs wrong label --- forms/Form.php | 26 +++++++++++++++----- forms/gridfield/GridField.php | 38 ++++++++++++++++------------- forms/gridfield/GridFieldFilter.php | 2 +- forms/gridfield/GridState.php | 3 +++ javascript/GridField.js | 11 ++++++--- 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/forms/Form.php b/forms/Form.php index b602ad03f..63606ea04 100644 --- a/forms/Form.php +++ b/forms/Form.php @@ -361,17 +361,31 @@ class Form extends RequestHandler { // Otherwise, try a handler method on the form object. } elseif($this->hasMethod($funcName)) { return $this->$funcName($vars, $this, $request); - } else { - // Finally try to find a field that could handle that action, ie GridField - foreach ($this->Fields() as $field){ - if (!$field->hasMethod($funcName)) continue; - return $field->$funcName($vars, $this, $request); - } + } elseif($field = $this->checkFieldsForAction($this->Fields(), $funcName)) { + return $field->$funcName($vars, $this, $request); } return $this->httpError(404); } + /** + * Fields can have action to, let's check if anyone of the responds to $funcname them + * + * @return FormField + */ + protected function checkFieldsForAction($fields, $funcName) { + foreach($fields as $field){ + if(method_exists($field, 'FieldList')) { + if($field = $this->checkFieldsForAction($field->FieldList(), $funcName)) { + return $field; + } + } elseif (!$field->hasMethod($funcName)) { + continue; + } + return $field; + } + } + /** * Handle a field request. * Uses {@link Form->dataFieldByName()} to find a matching field, diff --git a/forms/gridfield/GridField.php b/forms/gridfield/GridField.php index 160798caa..eb49b8de2 100644 --- a/forms/gridfield/GridField.php +++ b/forms/gridfield/GridField.php @@ -337,9 +337,11 @@ class GridField extends FormField { 'class' => "field CompositeField {$this->extraClass()}" ); return - implode("\n", $content['before']) . - $this->createTag('table', $attrs, $head."\n".$foot."\n".$body) . - implode("\n", $content['after']); + $this->createTag('fieldset', array('id'=>$this->ID(),'class'=>'ss-gridfield'), + implode("\n", $content['before']) . + $this->createTag('table', $attrs, $head."\n".$foot."\n".$body) . + implode("\n", $content['after']) + ); } function getColumns() { @@ -420,30 +422,32 @@ class GridField extends FormField { * @param array $data * @return string */ - public function gridFieldAlterAction($data, $form, $request) { + public function gridFieldAlterAction($data, $form, SS_HTTPRequest $request) { $id = $data['StateID']; $stateChange = Session::get($id); + $gridName = $stateChange['grid']; + $grid = $form->Fields()->dataFieldByName($gridName); - $state = $this->getState(false); + $state = $grid->getState(false); $state->setValue($data['GridState']); - $gridName = $stateChange['grid']; - $grid = $form->Fields()->fieldByName($gridName); $actionName = $stateChange['actionName']; $args = $stateChange['args']; $grid->handleAction($actionName, $args, $data); - // Make the form re-load it's values from the Session after redirect - // so the changes we just made above survive the page reload - // @todo Form really needs refactoring so we dont have to do this - if (Director::is_ajax()) { - return $form->forTemplate(); - } else { - $data = $form->getData(); - Session::set("FormInfo.{$form->FormName()}.errors", array()); - Session::set("FormInfo.{$form->FormName()}.data", $data); - Controller::curr()->redirectBack(); + switch($request->getHeader('X-Get-Fragment')) { + case 'CurrentField': + return $grid->FieldHolder(); + break; + + case 'CurrentForm': + return $form->forTemplate(); + break; + + default: + return $form->forTemplate(); + break; } } diff --git a/forms/gridfield/GridFieldFilter.php b/forms/gridfield/GridFieldFilter.php index f8d082ed7..cd7e423d8 100644 --- a/forms/gridfield/GridFieldFilter.php +++ b/forms/gridfield/GridFieldFilter.php @@ -79,7 +79,7 @@ class GridFieldFilter implements GridField_HTMLProvider, GridField_DataManipulat if(isset($filterArguments[$columnField])) { $value = $filterArguments[$columnField]; } - $field = new TextField('filter['.$columnField.']', 'filter['.$columnField.']', $value); + $field = new TextField('filter['.$columnField.']', '', $value); $field->addExtraClass('ss-gridfield-sort'); } else { $field = new LiteralField('', ''); diff --git a/forms/gridfield/GridState.php b/forms/gridfield/GridState.php index fb5da4f4d..f71fd6899 100644 --- a/forms/gridfield/GridState.php +++ b/forms/gridfield/GridState.php @@ -68,6 +68,9 @@ class GridState extends HiddenField { /** @return string */ public function Value() { + if(!$this->gridStateData) { + return json_encode(array()); + } return json_encode($this->gridStateData->toArray()); } diff --git a/javascript/GridField.js b/javascript/GridField.js index 546a62b4c..236b10471 100644 --- a/javascript/GridField.js +++ b/javascript/GridField.js @@ -1,18 +1,21 @@ jQuery(function($){ - $('.ss-gridfield .action').entwine({ + $('fieldset.ss-gridfield .action').entwine({ onclick: function(e){ - button = this; + var button = this; e.preventDefault(); var form = $(this).closest("form"); + var field = $(this).closest("fieldset.ss-gridfield"); form.addClass('loading'); $.ajax({ + headers: {"X-Get-Fragment" : 'CurrentField'}, type: "POST", url: form.attr('action'), data: form.serialize()+'&'+escape(button.attr('name'))+'='+escape(button.val()), dataType: 'html', success: function(data) { - form.replaceWith(data); + // Replace the grid field with response, not the form. + field.replaceWith(data); form.removeClass('loading'); }, error: function(e) { @@ -35,7 +38,7 @@ jQuery(function($){ * ToDo ensure filter-button state is maintained after filtering (see resetState param) * ToDo get working in IE 6-7 */ - $('.ss-gridfield input.ss-gridfield-sort').entwine({ + $('fieldset.ss-gridfield input.ss-gridfield-sort').entwine({ onfocusin: function(e) { // Dodgy results in IE <=7 if($.browser.msie && $.browser.version <= 7) {