从您的问题来看,您似乎打算将filter
传递给可搜索字段的内容更改为脚手架。我已经进行了一些挖掘,但似乎并非如此。但是,如果您改用该field
选项,您可能会实现您想要的。
您确实特别提到ListboxField
了,虽然它确实支持多个,但它并没有被字段上的默认构造函数启用,这就是它的实例化方式。
您想要的可以通过
CheckboxSetField
. (我承认,在 ModelAdmin 中使用时 UI 有点一般)
生成的代码可能如下所示:
class MyDataObject extends DataObject {
static $db = array(
'Name' => "Varchar(255)",
'MyEnum' => "Enum('Option1,Option2,Option3','Option1')"
);
public static $searchable_fields = array (
'MyEnum' => array('field' => 'CheckboxSetField')
);
}
不幸的是,这并不容易,您会注意到,只要这样做,它就会出现“无可用选项”而不是复选框列表。这是因为当我们提供field
我之前提到的选项时,SilverStripe 的行为有所不同。
这种解决方法不是很好,但可以说仍然是通用的。我做了一个扩展类ModelAdmin
,它CheckboxSetField
在搜索表单中查找并为其设置枚举值。
class MyModelAdminExtension extends Extension {
public function updateSearchForm($form) {
$modelClass = $form->getController()->modelClass;
foreach ($form->Fields() as $field) {
if ($field->class == 'CheckboxSetField') {
//We need to remove the "q[]" around the field name set by ModelAdmin
$fieldName = substr($field->getName(), 2, -1);
$dbObj = singleton($modelClass)->dbObject($fieldName);
if ($dbObj->class == 'Enum') {
$enumValues = $dbObj->enumValues();
$field->setSource($enumValues);
}
}
}
}
}
这是一个相对安全的ModelAdmin
扩展,因为它专门寻找映射到 a 的 Enum 的组合,CheckboxSetField
这只能在您手动指定它时发生。
走到这一步,我们实际上可以回顾一下ListboxField
,克服禁用的多个选项并用值填充它(因为它会遇到上面提到的相同问题)。这个解决方案将不那么通用,因为我们将强制ListboxField
从 Enum 映射的所有 's 为倍数,但如果我们想要一个更好的解决方案,这就是我们可以获得它的方法。
class MyModelAdminExtension extends Extension {
public function updateSearchForm($form) {
$modelClass = $form->getController()->modelClass;
foreach ($form->Fields() as $field) {
if ($field->class == 'ListboxField') {
//We need to remove the "q[]" around the field name set by ModelAdmin
$fieldName = substr($field->getName(), 2, -1);
$dbObj = singleton($modelClass)->dbObject($fieldName);
if ($dbObj->class == 'Enum') {
$field->setMultiple(true);
$enumValues = $dbObj->enumValues();
$field->setSource($enumValues);
}
}
}
}
}
对于我们的模型...
class MyDataObject extends DataObject {
private static $db = array(
'Name' => "Varchar(255)",
'MyEnum' => "Enum('Option1,Option2,Option3','Option1')"
);
public static $searchable_fields = array (
'MyEnum' => array('field' => 'ListboxField')
);
}
你现在有了你想要的 - 一个ListBoxField
带有 Enum 值的多选。
你现在可能会问,我为什么要覆盖CheckboxSetField
?好吧,我认为查看所有可能的解决方案很重要。我通过尝试找到了我提供的解决方案CheckboxSetField
,这实际上只是最后一分钟的事情,我意识到通过一些小的修改,我可以让它为ListboxField
.
正如您所提出的,上述代码在HasOne
关系中处理枚举存在问题。这是由于ModelAdmin
扩展采用字段名称并将其视为dbObject
表单模型类上的数据库字段(via)。相反,我们可以从字段名称上的双下划线检测关系,将其替换为点语法并将其视为关系(通过relObject
)。
我们更新后的updateSearchForm
函数如下所示:
public function updateSearchForm($form) {
$modelClass = $form->getController()->modelClass;
foreach ($form->Fields() as $field) {
if ($field->class == 'ListboxField') {
//We need to remove the "q[]" around the field name set by Model Admin
$fieldName = substr($field->getName(), 2, -1);
$dbObj = null;
//Check if the field name represents a value across a relationship
if (strpos($fieldName, '__') !== false) {
//To use "relObject", we need dot-syntax
$fieldName = str_replace('__', '.', $fieldName);
$dbObj = singleton($modelClass)->relObject($fieldName);
}
else {
$dbObj = singleton($modelClass)->dbObject($fieldName);
}
if ($dbObj != null && $dbObj->class == 'Enum') {
$field->setMultiple(true);
$enumValues = $dbObj->enumValues();
$field->setSource($enumValues);
}
}
}
}