这肯定不是最干净的解决方案,但我认为它应该可以解决问题。
首先让我们创建自定义网格字段操作。在这里,我们将在会话中保存所有可访问的记录,并将查询字符串添加到 url,以便我们知道要“克隆”哪个对象
public function getColumnContent($gridField, $record, $columnName) {
if(!$record->canEdit()) return;
$field = GridField_FormAction::create(
$gridField,
'clone'.$record->ID,
'Clone',
'clone',
array('RecordID' => $record->ID)
);
$values = Session::get('ClonedData');
$data = $record->data()->toMap();
if($arr = $values) {
$arr[$record->ID] = $data;
} else {
$arr = array(
$record->ID => $data
);
}
Session::set('ClonedData', $arr);
return $field->Field();
}
public function getActions($gridField) {
return array('clone');
}
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if($actionName == 'clone') {
$id = $arguments['RecordID'];
Controller::curr()->redirect($gridField->Link("item/new/?cloneID=$id"));
}
}
将这个新组件添加到我们的网格字段后,
$gridField->getConfig()->addComponent(new GridFieldCustomAction());
我们需要将数据带入新表单。为此,请将此代码直接添加到您的 getCMSFields 函数的“return $fields”上方,以便每次我们打开此类对象时都会执行该代码。
$values = Session::get('ClonedData');
if($values) {
Session::clear('ClonedData');
$json = json_encode($values);
$fields->push(LiteralField::create('ClonedData', "<div id='cloned-data' style='display:none;'>$json</div>"));
}
最后,我们需要将内容带回字段中。我们将使用一些 javascript 来完成此操作,因此首先您需要创建一个新的 script.js 文件并将其包含在 ss 后端(或仅使用现有的后端)。
(function($) {
$('#cloned-data').entwine({
onmatch: function() {
var data = JSON.parse($(this).text()),
id = getParameterByName('cloneID');
if(id && data) {
var obj = data[id];
if(obj) {
$.each(obj, function(i, val) {
$('[name=' + i + ']').val(val);
});
}
}
}
});
// http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript#answer-901144
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
})(jQuery);
就是这样……相当棘手。希望它能解决你的问题。