v4.3.0
When extending ModelAdmin to add new pre-defined queries (e.g. a checkbox that will be used to filter adresses in Belgium - using later on the getlist function), the overwritten getSearchContext functions never called.
This is the code I used but you may simply use examples from your on-line developers doc (https://docs.silverstripe.org/en/4/developer_guides/customising_the_admin_interface/modeladmin/).
class Adress_Admin extends ModelAdmin {
private static $url_segment = 'Adress';
private static $menu_title = 'Adressen';
private static $managed_models = [Adress::class];
public function getSearchContext()
{
$context = parent::getSearchContext();
if($this->modelClass == 'bpf\Adress') {
$context->getFields()->push(new CheckboxField('q[InBelgiumA]', 'Only expensive stuff'));
}
return $context;
}
It's very easy to check - use e.g. error_log to trace the fact the function has been called.
Help us with step-by-step instructions.
ps: I know this will be depreciated in v5 but at least could you please provide an updated documentation on how to do it using GridfieldFilterHeader.
Thank you!!!
We made an effort to ensure the existing API still worked - apparently we missed a spot.
The extension points for updating context still exist. You can write an extension that uses the updateSearchContext extension point:
Hi Guy,
It looks a bit complex to me but I will try to do it.
I learned silverstripe all by myself without little support and I get lost sometimes. My actual site in Prod runs with V3.5.1 and I am working on converting it to V4.3.
Not so easy as some facilities/modules became obsolete e.g. Translatable.
ok - this being said, what I want to do is what is explained on the developers documentation. In casus the following:
It would be fine if you can show the equivalent with GridfieldFilterHeader as this is the future no?
Thank you in advance
Philippe
You can also customize the search behavior directly on your ModelAdmin instance. For example, we might want to have a checkbox which limits search results to expensive products (over $100).
app/code/MyAdmin.php
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Admin\ModelAdmin;
class MyAdmin extends ModelAdmin
{
public function getSearchContext()
{
$context = parent::getSearchContext();
if($this->modelClass == 'Product') {
$context->getFields()->push(new CheckboxField('q[ExpensiveOnly]', 'Only expensive stuff'));
}
return $context;
}
public function getList()
{
$list = parent::getList();
$params = $this->getRequest()->requestVar('q'); // use this to access search parameters
if($this->modelClass == 'Product' && isset($params['ExpensiveOnly']) && $params['ExpensiveOnly']) {
$list = $list->exclude('Price:LessThan', '100');
}
return $list;
}
}
On 26 Feb 2019, at 22:37, Guy Marriott notifications@github.com wrote:
We made an effort to ensure the existing API still worked - apparently we missed a spot.
The extension points for updating context still exist. You can write an extension that uses the updateSearchContext extension point:
https://github.com/silverstripe/silverstripe-admin/blob/8267623bc5044e47026d7716e859d2208b0e651e/code/ModelAdmin.php#L201 https://github.com/silverstripe/silverstripe-admin/blob/8267623bc5044e47026d7716e859d2208b0e651e/code/ModelAdmin.php#L201
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub https://github.com/silverstripe/silverstripe-framework/issues/8827#issuecomment-467623947, or mute the thread https://github.com/notifications/unsubscribe-auth/ALNjXWzl9HX4WbIdnvD6KzM1sf_q2qXhks5vRaj9gaJpZM4bQO4s.
I succeeded to create the extension and get it called. The additional variable is added to the form.
However, it looks like the parameters are not passed using the URL anymore, which means that $params = $this->getRequest()->requestVar('q‘) returns nothing.
I don’t know how to get the value for the additional variable I created.
In app.yml, I added
SilverStripe\Admin\ModelAdmin:
extensions:
- bpf\ModelAdminExtension
I created the class ModelAdminExtension
namespace bpf;
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\i18n\i18nEntityProvider;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\GridField\GridFieldDetailForm;
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
use SilverStripe\ORM\DataExtension;
class ModelAdminExtension extends DataExtension
{
public function updateSearchContext($context)
{
if($this->owner->modelClass == Adress::class) {
$context->getFields()->push(new CheckboxField('q[InBelgiumA]', 'Only if in Belgium'));
}
return $context;
}
}
?>
I do not get any params in the getlist() function of my modeladmin extension because params are not passed using the URL.
class Adress_Admin extends ModelAdmin {
private static $url_segment = 'Adress';
private static $menu_title = 'Adressen';
private static $managed_models = [Adress::class];
private static $menu_icon_class = 'font-icon-book';
public function getList()
{
$list = parent::getList();
$params = $this->getRequest()->requestVar('q'); // use this to access search parameters
if($this->modelClass == Adress::class && isset($params['InBelgiumA']) && $params['InBelgiumA']) {
$list = $list->exclude('getInBelgium()', true);
}
return $list;
}
}
On 26 Feb 2019, at 22:37, Guy Marriott notifications@github.com wrote:
We made an effort to ensure the existing API still worked - apparently we missed a spot.
The extension points for updating context still exist. You can write an extension that uses the updateSearchContext extension point:
https://github.com/silverstripe/silverstripe-admin/blob/8267623bc5044e47026d7716e859d2208b0e651e/code/ModelAdmin.php#L201 https://github.com/silverstripe/silverstripe-admin/blob/8267623bc5044e47026d7716e859d2208b0e651e/code/ModelAdmin.php#L201
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub https://github.com/silverstripe/silverstripe-framework/issues/8827#issuecomment-467623947, or mute the thread https://github.com/notifications/unsubscribe-auth/ALNjXWzl9HX4WbIdnvD6KzM1sf_q2qXhks5vRaj9gaJpZM4bQO4s.
Yes, @ScopeyNZ The example for customising ModelAdmin search as shown in the docs doesnt work anymore and is throwing a lot of people. We need an example in there using the preferred method with GridfieldFilterHeader.
With SS 4.3.x and upward, the ModelAdmin custom search box guide is not valid anymore. I've figured out a way to get the job done.
updateSearchContext to extend search form:public function updateSearchContext($context)
{
// don't need to wrap field name inside the `q[]` tag anymore
$dateField = DateField::create('DateFrom', 'From date');
$context->getFields()->push($field);
}
/**
* Returns GridField filter params
*/
public function getFilterParams()
{
$class = $this->sanitiseClassName($this->modelClass);
$body = $this->getRequest()->getBody();
parse_str($body, $array);
$params = [];
// first, try to get params from filter state in request body
if (isset($array['filter'][$class]) && is_array($array['filter'][$class])) {
$params = $array['filter'][$class];
}
// second, try to get params from GridFieldFilterHeader state in request body
if (empty($params) && isset($array[$class]['GridState']) && $array[$class]['GridState']) {
$gridState = json_decode($array[$class]['GridState'], true);
if (isset($gridState['GridFieldFilterHeader']['Columns'])
&& is_array($gridState['GridFieldFilterHeader']['Columns'])) {
$params = $gridState['GridFieldFilterHeader']['Columns'];
}
}
// third, try to get params from GridFieldFilterHeader state in request vars
if (empty($params) && $requestVar = $this->getRequest()->requestVar($class)) {
if (isset($requestVar['GridState']) && !empty($requestVar['GridState'])) {
$gridState = json_decode($requestVar['GridState'], true);
if (isset($gridState['GridFieldFilterHeader']['Columns'])
&& is_array($gridState['GridFieldFilterHeader']['Columns'])) {
$params = $gridState['GridFieldFilterHeader']['Columns'];
}
}
}
return $params;
}
getFilterParams to get search params and do filter:public function getList()
{
// get list
$list = parent::getList();
// get search params
$params = $this->getFilterParams();
if (isset($params['DateFrom'])) {
// do filter stuffs
}
return $list;
}
Great!!! Thank you Anh Le!!!
This works fine if you correct the typo in the function updateSearchContext:
public function updateSearchContext($context)
{
// don't need to wrap field name inside the `q[]` tag anymore
$dateField = DateField::create('DateFrom', 'From date');
// $context->getFields()->push($field); this should be ... next line
$context->getFields()->push($dateField);
}
I'm going to reopen this in the context of docs because there's a lot of good discussion here. Also - we technically broke an API in a minor release, which is a bug in the context of SemVer.
I added this to my ModelAdmin but the updateSearchContext function doesn't seem to even be called. Am I missing something from @anhld solution? Running SS4.3.2. Any help would be greatly appreciated.
@lienajp , you said you got this working...?
class JobAdmin extends ModelAdmin
{
private static $managed_models = [
'Job'
];
public function updateSearchContext($context)
{
// don't need to wrap field name inside the q[] tag anymore
$dateField = DateField::create('DateFrom', 'From date');
$context->getFields()->push($dateField);
}
}
Forgive my ignorance. I didn't realise you had to extend your custom ModelAdmin. For those looking for a more complete solution:
https://docs.silverstripe.org/en/4/developer_guides/customising_the_admin_interface/how_tos/extending_an_existing_modeladmin/
use SilverStripe\Core\Extension;
use SilverStripe\Forms\DateField;
class JobAdminExtension extends Extension
{
public function updateSearchContext($context)
{
// don't need to wrap field name inside the `q[]` tag anymore
$dateField = DateField::create('DateFrom', 'From date');
$context->getFields()->push($dateField);
}
}
And in your config.yml
JobAdmin:
extensions:
- JobAdminExtension
Working now : )
So you need an extension to get this working on a custom modelAdmin? That feels a bit of a roundabout way....
Yes, that is why I didn't cotton on to it in the first place. It does seem a roundabout way of doing this.
@Jellygnite: yes, I got it working. The extension thing is mentioned in my second reaction on 27/2. See also the title of this issue. You noticed quickly and managed to get it working, so that's fine.
It is indeed a workaround as the updateSearchContext function should be called. This is why it its considered as a bug (I guess).
Should the impact of this bug be higher? I've developed some pretty complex search forms for some clients because the default ones aren't very powerful, so losing those has a major impact for my users.
This is a related issue: https://github.com/silverstripe/silverstripe-framework/issues/8518 the quick fix there was not to fix this bug, but to allow opting out of the React search form so the bug isn't surfaced. To test that solution I tried setting useLegacyFilterHeader to for a single model admin instance by accessing the GridFieldFilterHeader instance from getEditForm(), but it didn't work, perhaps because it was switched after initialisation? I then tried forcing the legacy behaviour with:
SilverStripe\Forms\GridField\GridFieldFilterHeader:
force_legacy: true
That triggered the 'legacy' behaviour, but apparently that behaviour is not equivalent to the behaviour in SS 4.2. In SS 4.2 when you clicked the search icon, a vertical search form expanded, showing all the fields you provided in getSearchContext(). This allowed you to create whatever fields and behaviour you like, which was great. (For example, in this interface the Community and Lot Status each search across a couple of different fields)
_4.2 model admin filter UI:_

The 'legacy' behaviour instead places search fields directly in columns, which means that you can only provide search fields that match up with columns 1:1. The bigger issue though, is that getSearchContext() is still not called, so my custom search form is not used whether I use the new React UI or the supposed 'legacy' UI. Instead the search fields are automatically scaffolded.
_4.3 model admin 'legacy' filter UI:_

The solution outlined above by @anhld looks workable but I'm reluctant to do it since a refactor like that shouldn't be necessary after upgrading to a new minor version. I might just revert to 4.2 instead.
I confirm the solution works and I fully agree with you that this is a bad surprise after a minor upgrade.
But as I am still in the process to migrate from 3.6 to 4.3 it was a satisfactory solution for me.
Based on the posts above I'd agree that the impact should be at least medium.
Should the impact of this bug be higher? I've developed some pretty complex search forms for some clients because the default ones aren't very powerful, so losing those has a major impact for my users.
I'm in the same basket with Jonom. We have some pretty complex CMS search forms that clients absolutely need.
So you need an extension to get this working on a custom modelAdmin? That feels a bit of a roundabout way....
In 4.3.3 you don't need an extension (not sure about other versions of 4.3.x though).
In the custom ModelAdmin, create the getEditForm() function and add this (tailor to your needs):
$config->removeComponentsByType(GridFieldFilterHeader::class);
$filterHeader = new GridFieldFilterHeader(
false,
function($context) {
$context->getFields()->insertAfter(
'SomeField',
CheckboxField::create('NewField', 'My new field to filter on')
);
}
);
$config->addComponent($filterHeader);
Got this to work, however if you pre-filter the list to exclude eg. 'Status' => 'completed' by default, when selected to include 'completed' items, they can't be opened in the GridField Detail Form... this may be a related bug?
Most helpful comment
With SS 4.3.x and upward, the ModelAdmin custom search box guide is not valid anymore. I've figured out a way to get the job done.
updateSearchContextto extend search form:getFilterParamsto get search params and do filter: