Accessing default values in model-less form - cakephp 4

My site has a search page which in it’s default state returns all the plots for sale by a property developer. It also has a model-less form at the top of the page that can be used to filter the results by house type, number of bedrooms etc. This form uses the GET method.

The model-less form, called FilterForm is set-up with default values so the form appears in a sensible state when it first appears. The code for this is -

        return $schema
            ->addField('type', ['type' => 'string', 'default' => 'Any'])
            ->addField('bedrooms', ['type' => 'string', 'default' => 'All'])
            ->addField('min_price', ['type' => 'integer', 'default' => 200000])
            ->addField('max_price', ['type' => 'integer', 'default' => 800000])
            ->addField('reserved', ['type' => 'boolean', 'default' => true]);

The controller then creates the form and fetches the details from the query string -

        $filter = new FilterForm();
        $query = $this->request->getQuery();
        $filter->setData($query);

There’s then a bunch of stuff where it constructs the query based on the values in the query string.

What I’d like to do is to use the default values set for the form for the database query when the page is first displayed and there’s no query string (because the form itself hasn’t yet been used). I assumed at first that the default values would be the values in the filterform object when it’s first created but if I do $filter->getData() straight after the form object is created, it’s just an empty array that’s returned and I can’t see any method for accessing the default values…

Is there any way of the controller or the form _execute() function accessing the default values or am I going about this in the wrong way?

Once the schema definition data is consumed by the schema, it may not be convenient to get at in your scenario.

You can do something like this

class FilterForm extends Form
{

    protected $schemaData = [
        'type' => ['type' => 'string', 'default' => 'Any'],
        'bedrooms' => ['type' => 'string', 'default' => 'All'],
        'min_price' => ['type' => 'integer', 'default' => 200000],
        'max_price' => ['type' => 'integer', 'default' => 800000],
        'reserved'  => ['type' => 'boolean', 'default' => true],
    ];

    protected function _buildSchema(Schema $schema): Schema
    {

        foreach ($this->schemaData as $column => $attributes) {
            $schema->addField($column, $attributes);
        }
        
        return $schema;
    }
}

Then you can write a getter in the FilterForm class to return the default values for fields

public function getDefault($column)
{
   return $schemaData[$column]['default'] ?? null;
}
1 Like

Thanks so much for that. It worked fine (with a slight tweak on getDefault() where it needed to be return $this->schemaData....

I’ve actually ended up doing it slightly differently though by explicitly setting the values for FilterForm using

    public function setDefaults()
    {
        foreach ($this->schemaData as $field => $attributes) {
            $defaults[$field] = $attributes['default'];
            $this->setData($defaults);
        }
    }

which I then call from the controller after creating the form object and before using the query values -

        $filter = new FilterForm();
        $filter->setDefaults();
        $query = $this->request->getQuery();
        if (!empty($query)) $filter->setData($query);