gregnb / mui-datatables

Datatables for React using Material-UI
MIT License
2.71k stars 932 forks source link

Boolean data customBodyRender bug #991

Open alielkhateeb opened 5 years ago

alielkhateeb commented 5 years ago

If the column data is boolean and customBodyRender is set, the logic function always receives true value.

Expected Behavior

The value should be either true or false depending on the actual value

Current Behavior

Value received in logic function is always true

Steps to Reproduce (for bugs)

https://codesandbox.io/s/trusting-tharp-2ldj7

  1. Filter the column salary with Yes or No it won't work with the option No as the value is always true.
  2. Comment the customBodyRender line
  3. Try to filter again and it will work this time

Another way to see the problem you could console.log(salary) in the beginning of the logic function and re-run the above procedure to see the value sent to the logic function

Your Environment

Tech Version
Material-UI 4.5
MUI-datatables 2.12
React 16.8.6
gabrielliwerant commented 5 years ago

So, I think this might be down to some confusion over what customBodyRender is doing as far as your ability to filter your data. That's not your fault; the behavior is a bit confusing.

If you are using customBodyRender with your own filter logic, and the code is able to resolve your render function to a value, it will use that value. If it can't, it will resort to the initial value in your data. So in your case, the render function resolves directly to a string, so the filters are using the string you supplied, not the value in your original data. You can therefore fix your issue by checking if salary === "Yes" and salary === "no" in your custom filter logic, and it should work as expected.

It's a bit difficult to predict this behavior at the moment, and it's not well documented, so I'm open to suggestions about how to make this more clear. I'm also open to changing the behavior, however, that would have to wait a while for a major release as it would be a breaking change.

alielkhateeb commented 5 years ago

@gabrielliwerant Oh ok I get it, yeah you're right it's a bit confusing.

Your workaround for comparing string works well, but I modified the code a bit to make customBodyRender return a react component with the prop value = {!value} this obviously causes a problem in the value that goes to the logic function (it will always be true), if I change the props I send in value={value} it works fine, It's very weird, I think in that case this is a bug, no?

NOTE: I edited the sandbox above to elaborate better.

shangan23 commented 4 years ago

Is there any solution for boolean data value issue?

patorjk commented 4 years ago

Just use the proposed workaround. For the example in the codesandbox above, just change the salary column to this and it will work as expected:

      {
        name: "Salary",
        options: {
          filter: true,
          filterType: "checkbox",
          filterOptions: {
            names: ["Yes", "No"],
            logic(salary, filterVal) {
              const show =
                (filterVal.indexOf("Yes") >= 0 && ( salary === true || salary === 'true') ) ||
                (filterVal.indexOf("No") >= 0 && ( salary === false || salary === 'false') );
              return !show;
            }
          },
          customBodyRender: (val) => {
            return val === true ? "true" : "false";
          }
        }
      }
patorjk commented 4 years ago

Hmm, actually, after investigating this a little more, that may not do it for every case. There's currently a PR (https://github.com/gregnb/mui-datatables/pull/1328) that will add the raw row data to the logic call. That means you would get the unprocessed data. That would solve this issue. That will be in the 3.0.1 release, which will be out in a few days.