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

CSV export of details table in compact view #83

Open
tidoust opened this issue Mar 29, 2019 · 1 comment
Open

CSV export of details table in compact view #83

tidoust opened this issue Mar 29, 2019 · 1 comment

Comments

@tidoust
Copy link
Member

tidoust commented Mar 29, 2019

From time to time, one will want to extract the results of a questionnaire and work on them in a spreadsheet. The "Details" table in the compact results view is almost perfect for that, but cannot be directly copied and pasted onto a spreadsheet, as far as I can tell.

Main problem is that comments provided in response to some questions may contain newlines. When that happens, the spreadsheet will create artificial rows, requiring to merge the cells manually afterwards.

Another minor issue is that it's hard to select all the content of the table at once ("Select all" will select all the contents of the page in most browsers).

Also, it would be good to have a raw export view where the family name does not end up with " (impersonate)" (but that one is easy to get rid of).

Could a "CSV export" button be provided to ease export of results? Or is there a better way that I missed?

@tidoust
Copy link
Member Author

tidoust commented Apr 2, 2019

FWIW, in the meantime, here is a JavaScript function that can be run against a WBS compact results page to get a CSV export:

const getDetailsTableAsCSV = () => {
  // Field separator may be tab, ",", ";", etc.
  const fieldSeparator = ',';

  // Line separator needs to be "\r" for Google Sheets to process multi-line
  // comments correctly
  const lineSeparator = '\r';

  // Wraps a (possibly multi-line) string in double quotes
  const quoteStr = str => '"' + str.replace(/"/g, '""') + '"';

  // Returns the value of an attribute parsed as integer
  const getIntAttr = (el, attr) => {
    if (el.getAttribute(attr)) {
      try {
        return parseInt(el.getAttribute(attr), 10);
      }
      catch (err) {
        return 0;
      }
    }
  };

  // Adds a header label, taking into account headers that span multiple columns
  const addHeader = th => {
    let res = quoteStr(th.innerText);
    let colspan = getIntAttr(th, 'colspan');
    while (colspan > 1) {
      res += fieldSeparator;
      colspan--;
    }
    return res;
  };

  // Adds a row
  const addRow = tr =>
    [...tr.querySelectorAll('th,td')].map(td => quoteStr(td.innerText)).join(fieldSeparator);

  // Details table to parse
  let table = document.querySelector('#mainTable');

  // Generate the CVS export
  // TODO: the second header row, which typically exists when the questionnaire
  // contains ranking questions, would need to be exported as well
  return []
    .concat([...table.querySelectorAll('thead > tr:first-child > th')].map(addHeader).join(fieldSeparator))
    .concat([...table.querySelectorAll('tbody > tr')].map(addRow))
    .join(lineSeparator);
};

To use it:

  1. Copy and paste the code above in the console pane associated with the results page
  2. Run console.log(getDetailsTableAsCSV())
  3. Copy the result to some export.csv file
  4. Import the CSV file in a Google Sheet

Note import does not work in Excel because it does not seem to support multilines.

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