Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easier way create table from nested properties #258

Closed
simonbengtsson opened this issue May 23, 2017 · 13 comments
Closed

Easier way create table from nested properties #258

simonbengtsson opened this issue May 23, 2017 · 13 comments

Comments

@simonbengtsson
Copy link
Owner

Right now you either have to flatten your data before passing to autotable or use the hooks to parse the exact data. Research a way to for example allow specifying the nested property to be used with a dot notation. See https://stackoverflow.com/questions/44133030/access-nested-json-property-in-jspdf-autotable-plugin

@gep13
Copy link

gep13 commented May 23, 2017

@simonbengtsson I had another follow up question regarding this, and I thought it better to ask here, than on the Stackoverflow question. If this is not the correct place, then please let me know.

While waiting for this feature to get implemented, I am using the approach that you suggested in the SO post. This is what I am currently doing...

var columns = [
  { title: "ID", dataKey: "Primary_Key" },
  { title: "Customer Name", dataKey: "Owner_Customer_Name", displayKey: "Primary_Key" },
  { title: "Customer Last Updated By", dataKey: "Owner_Customer_Name", displayKey: "LastUpdatedBy_Uid.Primary_Key" }
];

Where the format of the JSON coming back is this:

{
  "Material_State": "IN USE",
  "Primary_Key": "0100050000000700",
  "Owner_Customer_Name": {
    "LastUpdatedBy_Uid": {
      "Primary_Key": "SYSTEM",
      "User_State": "ACTIVE"
    },
    "Primary_Key": "CUSTOMER_A",
  },
}

To extract the information in the createdCell method, I am then trying this:

createdCell: function (cell, data) {
  if (data.column.raw.displayKey) {
    if (cell.raw) {
      var displayKey = data.column.raw.displayKey;
      if (displayKey) {
        var displayKeyParts = displayKey.split('.');
        if (displayKeyParts.length > 1) {
          let o = cell.raw;
          displayKeyParts.forEach(key => { o !== null ? o = o[key] : '' });
            cell.text = o;
        } else {
          cell.text = cell.raw[displayKey];
        }
      }
    } else {
      cell.text = '';
    }
  }
}

which is an extension of the example that you showed. However, the output in the table is:

image

When I was expecting it to be

ID Customer Last Updated By Customer Last Updated By
0100050000000700 CUSTOMER_A SYSTEM

While debugging, I can see that CUSTOMER_A is correctly set to cell.text but I think the issue is that the same dataKey is being used, and therefore being overwritten in the second execution.

Can you confirm if this is the case? If so, can you suggest a way around this?

For example, is there a way to have two cells generated for a single dataKey definition?

Thanks in advance!

@simonbengtsson
Copy link
Owner Author

simonbengtsson commented May 23, 2017

You are correct in that it gets overridden. The dataKey is supposed to be unique. I have not tried it myself, but you can try having the datakey Owner_Customer_Name.Primary_Key for the first column and Owner_Customer_Name.LastUpdatedBy_Uid.Primary_Key. for the second. You can then parse the dataKey in the same way as your displayKey to extract the wanted text.

@gep13
Copy link

gep13 commented May 23, 2017

@simonbengtsson when I tried that in the first pass, it wasn't matching anything on the the dataKey, and as a result cell.raw was null. However, I notice you are specifically including spaces in the name of your dataKey, so let me try that...

@gep13
Copy link

gep13 commented May 23, 2017

@simonbengtsson so when I try that, I get the following:

image

Tried the following for dataKey:

Owner_Customer_Name. Primary_Key
Owner_Customer_Name .Primary_Key
Owner_Customer_Name Primary_Key

@gep13
Copy link

gep13 commented May 23, 2017

@simonbengtsson do you have any other suggestions about how to achieve what I would like? i.e. would like to be able to show, potentially, multiple properties from a nested object, as separate columns in the table.

@gep13
Copy link

gep13 commented May 23, 2017

@simonbengtsson it would seem that I can get to the information that I want via the data.row.raw property. Is that a sensible way to go? Or is that not recommended? i.e. I can make the dataKey property unique for each column, knowing that it won't match on anything and cell.raw will be empty, and then create the path to the property of interest via data.row.raw.

Thanks in advance, appreciate your support on this.

@gep13
Copy link

gep13 commented May 23, 2017

@simonbengtsson okay, this approach works...

var columns = [
  { title: "ID", dataKey: "Primary_Key" },
  { title: "Customer Name", dataKey: "Owner_Customer_Name.Primary_Key" },
  { title: "Customer Last Updated By", dataKey: "Owner_Customer_Name.LastUpdatedBy_Uid.Primary_Key" }
];

with this:

createdCell: function (cell, data) {
  let dataKeyParts = data.column.raw.dataKey.split('.');
  if(dataKeyParts.length > 1) {
    let o = data.row.raw;
    dataKeyParts.forEach(key => {(o !== null || o !== '') ? o = o[key] : ''});
    cell.text = o;
  }
}

Thoughts?

@simonbengtsson
Copy link
Owner Author

That seems sensible. It probably is a bug that cell.raw is not set though. Will look into it.

@gep13
Copy link

gep13 commented May 24, 2017

@simonbengtsson sounds good to me. Thanks again for all your help!

@simonbengtsson
Copy link
Owner Author

simonbengtsson commented May 24, 2017

Seeing as you are using somewhat more advanced features of the plugin. Could you give me some general feedback on how your experience has been? For example things that worked differently from what you expected, unintuitive parts, things that need further documentation etc. And also if you looked into any other library why you chose this plugin.

@simonbengtsson
Copy link
Owner Author

The reason for cell.raw did not exist is most likely that the plugin tried to find row['address.country']. So thinking of that the easiest solution is probably to do what you did and use data.row.raw and parse out the cell definition manually.

@gep13
Copy link

gep13 commented May 25, 2017

@simonbengtsson said...
The reason for cell.raw did not exist is most likely that the plugin tried to find row['address.country']. So thinking of that the easiest solution is probably to do what you did and use data.row.raw and parse out the cell definition manually.

sounds good to me 👍

@simonbengtsson said...
Seeing as you are using somewhat more advanced features of the plugin. Could you give me some general feedback on how your experience has been? For example things that worked differently from what you expected, unintuitive parts, things that need further documentation etc. And also if you looked into any other library why you chose this plugin.

This is the first library that I chose to look at it, and it came as a recommendation from a colleague. Out of the box, I was very impressed with it's functionality and based on the examples that you provide from the GitHub repository I was able to see that it covered all the main use cases that I had, i.e. controlling look and feel, multiple tables, etc. The more advanced use cases are likely to be an edge case, so not sure how worth it would be to try to document those. If the ability to drill down into nested properties gets OOTB support then that would definitely be something to cover.

One general comment about this page:

https://simonbengtsson.github.io/jsPDF-AutoTable/

It would be good if I could "see" the code that went into creating what appears on the right hand side of the page. I know that I can jump to the example.js file and drill into it, but it would be easier for someone coming to it to see the required code alongside the example. Just a thought.

Overall, very impressed with this plugin, great work! 😄

@simonbengtsson
Copy link
Owner Author

Thanks! And good point about the being able to see the code at the same time as the demo. Will fix that in the next version of the demo page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants