Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverstripe 3.2:如何在CMS中创建自定义操作按钮,以创建新的数据对象并从另一个数据对象填充它_Silverstripe_Data Objects - Fatal编程技术网

Silverstripe 3.2:如何在CMS中创建自定义操作按钮,以创建新的数据对象并从另一个数据对象填充它

Silverstripe 3.2:如何在CMS中创建自定义操作按钮,以创建新的数据对象并从另一个数据对象填充它,silverstripe,data-objects,Silverstripe,Data Objects,我正在寻找一种创建自定义操作按钮的方法,该按钮允许我使用另一个DataObject中的预填充内容创建一个新DataObject。举个简单的例子:当我收到一封电子邮件并点击我的电子邮件客户端中的“回答”按钮时,我会看到一个新窗口,其中包含以前电子邮件中预填充的内容。我的按钮正需要这个功能。此按钮应出现在GridField中每个DataObject的旁边 因此,我知道如何制作按钮并将其添加到我的GridField(->)中,并且知道如何转到新的DataObject: Controller::curr

我正在寻找一种创建自定义操作按钮的方法,该按钮允许我使用另一个DataObject中的预填充内容创建一个新DataObject。举个简单的例子:当我收到一封电子邮件并点击我的电子邮件客户端中的“回答”按钮时,我会看到一个新窗口,其中包含以前电子邮件中预填充的内容。我的按钮正需要这个功能。此按钮应出现在GridField中每个DataObject的旁边

因此,我知道如何制作按钮并将其添加到我的GridField(->)中,并且知道如何转到新的DataObject:

Controller::curr()->redirect($gridField->Link('item/new'));
我还发现DataObjects有一个重复的函数:

public function duplicate($doWrite = true) {
        $className = $this->class;
        $clone = new $className( $this->toMap(), false, $this->model );
        $clone->ID = 0;

        $clone->invokeWithExtensions('onBeforeDuplicate', $this, $doWrite);
        if($doWrite) {
            $clone->write();
            $this->duplicateManyManyRelations($this, $clone);
        }
        $clone->invokeWithExtensions('onAfterDuplicate', $this, $doWrite);

        return $clone;
    }

也许这比我想象的要容易,但目前我不知道如何重写它来得到我需要的。谁能给我一个提示吗

这肯定不是最干净的解决方案,但我认为应该这样做

首先,让我们创建自定义gridfield操作。在这里,我们将在会话中保存所有可访问的记录,并向url添加查询字符串,以便知道要“克隆”的对象

将此新组件添加到gridfield后

$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>"));
}

就这样。。。相当棘手。希望它能解决您的问题。

那么您不知道如何组合自定义gridfield操作和复制操作?我正确理解你的问题了吗?是的。我可以使用复制操作的一部分,但是新的dataobject还不应该添加到数据库中。用户应该能够在保存和创建新数据对象之前更改内容,因此必须重定向(或弹出)到尚未添加但已预填充的新数据对象。这可能吗?啊,嗯,我不知道,但那会有用的。几小时后我在家的时候我会想办法弄清楚的。好吧,这有点棘手,但我想a已经找到了解决办法。让我知道它是否对你有用。非常感谢你!这正是我要找的。非常适合我!谢谢你的一步一步的描述!它很容易理解并集成到我的代码中!你让我开心!:)经过一段时间的测试后,代码和htmleditor字段的纠缠似乎出现了问题。它只在第一次起作用。当我从克隆的新Dateobject返回而不保存,然后再次单击“克隆”时,HtmlEditor字段的克隆内容丢失。所有其他领域都很好。你知道如何处理这个问题吗?我现在的时间很短,但我认为要使htmleditor字段起作用,需要修改函数来检测字段是否为htmleditor字段,然后使用tinymce setContent方法
$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>"));
}
(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);