SOLVED - CSV string converted and downloadable to CSV file

Hi everyone !
I am trying to allow my users to download the filtered content of the dataset on their member’s page into a CSV file. I already managed to code the conversion of the content into a CSV string, now I would like to set up the behavior of a button that would would create a CSV file out of this string, and then download a CSV file when clicked.
Any idea ? i also thought of using an API that would send the file by email in the end, however I can’t find a proper API for that.

Thanks !

You can create a button using custom element to download the csv;

  1. Add a custom element to your page.

  2. Create a js file under public/custom-elements.

  3. In the custom element file use something like:

const css = `
a {
    text-decoration: none;
    background-color: orange;
    color: white;
    padding: 8px;
    border-radius:10px;
    font-size: 14px;
}
.disabled {
    background-color: lightgrey;
}
`;
function generateCsvLink(shadow, value){
            const data  = JSON.parse(value);
            const keys = [];
            data.forEach(obj => {
                const objKeys = Object.keys(obj);
                objKeys.forEach(k => {
                if(!keys.includes(k)){keys.push(k);}
                })
            })
            
             const commaSeparatedString = [keys.join(',') , data.map(row => keys.map(key => row[key]).join(',')).join('\n')].join('\n');
             const csvBlob = new Blob([commaSeparatedString]);
            const downloadButton = shadow.getElementById('csv-download')
            downloadButton.href = URL.createObjectURL(csvBlob);
            downloadButton.classList.remove('disabled');
        }

class Csv extends HTMLElement {
    constructor(){
        super().attachShadow({mode: 'open'});
    }
    connectedCallback() {
        const shadow = this.shadowRoot;
        const style = document.createElement('style');
        style.innerHTML = css;
        const wrapper = document.createElement('div');
        wrapper.innerHTML = '<a id="csv-download" download="file.csv" class="disabled">Download CSV file</a>';
        shadow.appendChild(style);
        shadow.appendChild(wrapper);
    }
    static get observedAttributes() { return ['data']; }
    attributeChangedCallback(name, _, value) {
        if (name === 'data') {
       generateCsvLink(this.shadowRoot, value)
    }
}
}
customElements.define('csv-generator', Csv);
  1. Connect the custom element (on the page editor) to the file (Velo source, file name, csv-generator tag).
  2. On the page code once the data is ready (after filtering. In then() part):
$w('#dataset1').getItems(0, 1000)
.then(r => $w('#customElement1').setAttribute('data', JSON.stringify(r.items)))

And that’s all.

1 Like

P.S. only if your site is under your own domain.

Another P.S. you can also initiate the download without a button (using custom element and window.open) but some browsers will block it.

Thank you so much for all this info :smiley:
I will give it a try and let you know how it goes.
Thanks !

@jonatandor35 Hey thank you so much for your answer :slight_smile: Apparently, there might be a little problem in the custom element’s code as the button is not rendering on preview. On live site, I have the following error in the console :

Error: failed to load custom element corvid file with url: https://bundler.wix-code.com/6516b74f-3cf2-4c47-be56-52968edc7f7a/98d7a743-946c-4b92-b91b-b49ef88827d8/bab3af1d-a1f1-4008-803f-55219004c9f7/custom-elements/download-function?no-umd=true&wix-data-as-namespace=true&replace-console=true
    at l (wixCustomElementComponent.dce6ce7e.chunk.min.js:1:1228)
    at async Promise.all (index 0)
    at async Object.pageWillMount (wixCustomElementComponent.dce6ce7e.chunk.min.js:1:707)
    at async t (bootstrap-features.2a7d7fd1.bundle.min.js:6:76761)
    at async Promise.all (index 23)
    at async bootstrap-features.2a7d7fd1.bundle.min.js:6:76932
    at async Promise.all (index 0)
    at async initPage (bootstrap-features.2a7d7fd1.bundle.min.js:6:77017)
    at async bootstrap-features.2a7d7fd1.bundle.min.js:6:101769
    at async Object.N [as navigate] (bootstrap-features.2a7d7fd1.bundle.min.js:6:101655)

Thank you !

@valentinloppe It will only work if you connected your site to your own domain and didn’t leave it under wixsite.com

P.S. I tried it and it worked.

@jonatandor35 Thanks J.D, it is already the case as it has been implemented on this page : https://www.myvineyardcheckin.com/account/my-submissions
Would it be an issue from the editor itself ? I am having quite a lot of issues with the editor these days…

@valentinloppe I can’t tell. I don’t see the error on the page you linked but I also don’t see the custom element there.

@jonatandor35 All good, it’s working now ! Thank you so much !