React Sortable Table

Greetings

Intro

  • Full stack node/react developer that just started using patternfly for a new project and LOVE IT!

Issue

  • The react table documentation says that you can pass arrays of objects to tables.

  • This is how all data comes out from api calls, not hard to convert but is annoying (especially when the rest of your state relies on arrays of objects)

  • To get around it I have implemented this in my classes:

    // conversion function for pattern fly table data requirements, this will be used a lot
    convertObjArray = (data) => {
    let dataArray = [];
    let containerArray = [];

      for(let i=0; i<data.length; i++){
          dataArray = [];
          console.log(data[i]);
          data[i].edit = <div>
                          <Button key={"e_" + data[i].StoreId}
                                  variant="primary"
                                  onClick={this.patchStore}
                                  className="edit"
                          >Edit</Button>
                          <Button key={"c_" + data[i].StoreId}
                                  variant="danger"
                                  onClick={this.confirm}
                                  className="confirm"
                          >Confirm</Button>
                         </div>;
          const obj = data[i];
          for(let prop in obj){
              dataArray.push(obj[prop]);
          }
          containerArray.push(dataArray);
      }
      this.setState({
          rows: containerArray,
      });
    

    }

I really hope that I am just out to lunch on this one and there is just something I am doing wrong.

Thanks!

hey Gilbert_Comeau, pretty nice hearing this feedback from a Fullstack developer!

I’m not 100% following your question here, but am quite familiar with React-Table syntax. Were you able to find a solution? It seems you are trying to pass custom JSX for the row. That can be done w/ title prop. Our examples in docs show this currently like this:

     rows: [
        ['one', 'two', 'three', 'four', 'five'],
        [
          {
            title: <div>one - 2</div>,
            props: { title: 'hover title', colSpan: 3 }
          },
          'four - 2',
          'five - 2'
        ],
        [
          'one - 3',
          'two - 3',
          'three - 3',
          'four - 3',
          {
            title: 'five - 3 (not centered)',
            props: { textCenter: false }
          }
        ]

The rows prop can change as needed and should reflect state updates. Let me know if this helps in any way!

Also, please let us know if these docs could use further improvement.

Thanks,
-patrick

Hi Patrick,

Thanks for the response, I should have been more clear in my question.

The issue I have is that you cannot pass an array of objects to table rows, it has to be an array of arrays.

Basically from your example, I would not be able to pass an object as row data, it has to be an array:

rows: [
    ['one', 'two', 'three', 'four', 'five'],
    ['one', 'two', 'three', 'four', 'five'],
    ]

What I want to pass would look as so:

rows: [
    {obj1.prop1Value, obj1.prop2Value, obj1.prop3Value, obj1.prop4Value,obj1.prop5Value},
   {obj2.prop1Value, obj2.prop2Value, obj2.prop3Value, obj2.prop4Value,obj2.prop5Value},
    ]

As I mentioned in the previous post, I currently have to convert the object property values to an array and then push those arrays into a second container array. In the docs it says that you should be able to pass an array of objects as table rows:

rows arrayOf Actual rows to display in table. Either array of strings or row objects. If you want to use components in row cells you can pass them as title prop in cells definition. Ex: rows:[ {cells:[ {title: Some component} … ]} ]

Any thoughts? Thanks again!

Blockquote

Any update on this?

Earth to patternfly team?

Hi @Gilbert_Comeau,

Apologies for the delay, have been quite busy! I think the short answer is here, the current API does not support this, however, I’m not entirely sure that it should? If one were to pass an array of objects instead of an array of arrays as we do now, how would the table determine which object key to apply to which cell (in what order)? Today, the nested array enables us to determine which columns to apply (in the order provided)…

rows: [
   ['col-one', 'col-two', 'col-three', 'col-four', 'col-five']  (row1)
]

or the use case you describe, how would we determine which order to apply the object keys?

rows: [
  [ { col1: 'one', col2: 'two', col3: 'three' } ]
]

We would have to devise some sort of mechanism in which way to order object attributes w/ columns… are you assuming it would be alphabetical by object key? Also, this could get tricky if having to implement this interface both ways across all of the existing features/transforms (filter/sort/etc).

FWIW, we don’t have plans to do this at the moment, but we could certainly consider this in the future if you want to file an issue describe exactly how this API addition would work. Now that we have forked Reactabular, it is a great time to consider new API additions!

I’ve started converting the existing API structure to TypeScript and this should help us track this a lot better… for example, here is the rows structure in place today converted to TypeScript style interface…

RowsType:

Happy to consider future additions and apologies if I’ve misunderstood your request. Thanks!

Hi Patrick,

An array of objects always comes out in the same position from the API unless you actually update the databases tables to have new fields. At that point you would need to add columns to the tables, which I would be okay with.

I think that documentation is a bit misleading, while it is correct that you can have a row of objects, I mistakenly took it that you could pass an array of objects as your table data.

This works very well in other frameworks (material design ect.).conversion code I wrote is fine if I have > 1000 entries, but after that performance starts taking a hit. While i can get around this with lazy loading it’s really not ideal.

Gil