No it is not safe to share the alias and field name...

The field name could be nested, for example: user[data]
Using this as an alias is user[data]::onDoSomething
Resulting in an invalid AJAX handler name
This commit is contained in:
Samuel Georges 2016-03-17 19:50:34 +11:00
parent 7f209d2df9
commit e9c7e6b9d1
5 changed files with 27 additions and 15 deletions

View File

@ -147,14 +147,10 @@ class DataTable extends FormWidgetBase
protected function makeTableWidget()
{
$config = $this->makeConfig((array) $this->config);
$config->dataSource = 'client';
// It's safe to use the field name as an alias
// as field names do not repeat in forms. This
// approach lets to access the table data by the
// field name in POST requests directly (required
// in some edge cases).
$config->dataSource = 'client';
$config->alias = studly_case(HtmlHelper::nameToId($this->fieldName)) . 'datatable';
$config->fieldName = $this->fieldName;
$table = new Table($this->controller, $config);

View File

@ -31,8 +31,19 @@ class Table extends WidgetBase
*/
protected $showHeader = true;
/**
* @var Backend\Widgets\Table\DatasourceBase
*/
protected $dataSource = null;
/**
* @var string Field name used for request data.
*/
protected $fieldName = null;
/*
* @var string
*/
protected $recordsKeyFrom;
protected $dataSourceAliases = [
@ -47,6 +58,8 @@ class Table extends WidgetBase
{
$this->columns = $this->getConfig('columns', []);
$this->fieldName = $this->getConfig('fieldName', $this->alias);
$this->recordsKeyFrom = $this->getConfig('keyFrom', 'id');
$dataSourceClass = $this->getConfig('dataSource');
@ -65,10 +78,12 @@ class Table extends WidgetBase
$this->dataSource = new $dataSourceClass($this->recordsKeyFrom);
if (Request::method() == 'POST' && $this->isClientDataSource()) {
if (strpos($this->alias, '[') === false)
$requestDataField = $this->alias.'TableData';
else
$requestDataField = $this->alias.'[TableData]';
if (strpos($this->fieldName, '[') === false) {
$requestDataField = $this->fieldName.'TableData';
}
else {
$requestDataField = $this->fieldName.'[TableData]';
}
if (Request::exists($requestDataField)) {
// Load data into the client memory data source on POST

View File

@ -296,7 +296,7 @@ return}
Table.prototype.onFormSubmit=function(ev,data){if(data.handler==this.options.postbackHandlerName){this.unfocusTable()
if(!this.validate()){ev.preventDefault()
return}
var fieldName=this.options.alias.indexOf('[')>-1?this.options.alias+'[TableData]':this.options.alias+'TableData'
var fieldName=this.options.fieldName.indexOf('[')>-1?this.options.fieldName+'[TableData]':this.options.fieldName+'TableData'
data.options.data[fieldName]=this.dataSource.getAllData()}}
Table.prototype.onToolbarClick=function(ev){var target=this.getEventTarget(ev),cmd=target.getAttribute('data-cmd')
if(!cmd)

View File

@ -786,9 +786,9 @@
return
}
var fieldName = this.options.alias.indexOf('[') > -1
? this.options.alias + '[TableData]'
: this.options.alias + 'TableData'
var fieldName = this.options.fieldName.indexOf('[') > -1
? this.options.fieldName + '[TableData]'
: this.options.fieldName + 'TableData'
data.options.data[fieldName] = this.dataSource.getAllData()
}

View File

@ -4,6 +4,8 @@
class="control-table"
data-columns="<?= e(json_encode($columns)) ?>"
data-data="<?= e($data) ?>"
data-alias="<?= e($this->alias) ?>"
data-field-name="<?= e($this->fieldName) ?>"
data-postback-handler-name="<?= e($postbackHandlerName) ?>"
data-adding="<?= e($adding) ?>"
data-deleting="<?= e($deleting) ?>"
@ -13,7 +15,6 @@
data-key-column="<?= e($recordsKeyFrom) ?>"
data-client-data-source-class="<?= e($clientDataSourceClass) ?>"
data-dynamic-height="<?= e($dynamicHeight) ?>"
data-alias="<?= e($this->alias) ?>"
data-btn-add-row-label="<?= e($btnAddRowLabel) ?>"
data-btn-add-row-below-label="<?= e($btnAddRowBelowLabel) ?>"
data-btn-delete-row-label="<?= e($btnDeleteRowLabel) ?>"