ypnos-web / cakephp-datatables

CakePHP3 Plugin for DataTables plug-in for jQuery
MIT License
27 stars 24 forks source link

Filtering and searching on column with boolean #73

Closed treyphax closed 5 years ago

treyphax commented 5 years ago

The idea: I am trying to have a DataTable where you also have two buttons to filter the table where a certain column value is either true or false, yet you can still use the normal search function to search certain strings.

The issue: The filter requires that the column I want to filter on is 'searchable'. However, the column is of the boolean type. So when it becomes searchable, I can not use the normal search function, since anything typed into it will be used as a string that can't be converted to a bool.

Normally I would make the boolean column notSearchable, but I need it to be searchable for the filter buttons to work.

How I somewhat resolved it: In DataTablesComponent.php starting form line 299 there's the following if statement:

        if (strpos(strtolower($comparison), 'like') !== false) {
            $value = $this->getConfig('prefixSearch') ? "{$value}%" : "%{$value}%";

            if ($this->_table->getConnection()->getDriver() instanceof Postgres) {
                $columnDesc = $table->getSchema()->getColumn($column);
                $columnType = $columnDesc['type'];
                if ($columnType !== 'string' && $columnType !== 'text') {
                    $textCast = "::text";
                }
            }
        }
        $condition = ["{$table->getAlias()}.{$column}{$textCast} {$comparison}" => $value];

After the if, I added an else statement so the code would look like this:

        if (strpos(strtolower($comparison), 'like') !== false) {
            $value = $this->getConfig('prefixSearch') ? "{$value}%" : "%{$value}%";

            if ($this->_table->getConnection()->getDriver() instanceof Postgres) {
                $columnDesc = $table->getSchema()->getColumn($column);
                $columnType = $columnDesc['type'];
                if ($columnType !== 'string' && $columnType !== 'text') {
                    $textCast = "::text";
                }
            }
        }
        else {
            $columnDesc = $table->getSchema()->getColumn($column);
            $columnType = $columnDesc['type'];
            if($columnType == 'boolean') {
                $value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
                if ($value === null) {
                    return;
                }
            }
        }
        $condition = ["{$table->getAlias()}.{$column}{$textCast} {$comparison}" => $value];

It allowed me to have a searchable boolean column together with my other columns without it interfering with my normal search function.

Thank you for your time.

ypnos-web commented 5 years ago

Please fix your formatting.

treyphax commented 5 years ago

I edited it, i hope it's a bit more clear now.

ypnos-web commented 5 years ago

Thank you, now I better understand what you are doing. Would you like to prepare a pull request with your change?

treyphax commented 5 years ago

I'll prepare you one tomorrow. Thank you for your time.