Products

Persistence

Jspreadsheet is a frontend tool with methods, events, and other features to help with backend data persistence. This section covers the following topics:

  • Posting data to a remote server;
  • Dealing with record IDs synchronization and sequences;
  • Backend persistence in PHP example;
  • Using plugins for data persistence.

Features

Internal row id

JSS provides a property that enables you to attach a unique ID to your rows, aiding in synchronizing data with an external database. This property helps to identify the record to update with each AJAX call.

Sequence

Jspreadsheet implements an internal sequence for each worksheet that automatically increments and assigns a value to a row when no record ID is defined. That enables the user to programmatically set and retrieve IDs for a given row, providing greater flexibility in managing the data in the worksheet.

Documentation

Methods

Method Description
getNextSequence Get the next sequence number.
getNextSequence() : void
getRowId Get the row ID from a row number given.
getRowId(rowNumber: Number) : void
setRowId Set the row ID from a row number given.
setRowId(rowNumber: Number, rowId: Number) : void
getRowById Get the data from a row, or the row object by id.
getRowById(rowNumber: Number, element: Boolean) : any
save Internal method to post a request to the server. The callback is executed when the backend returns a JSON
save(url: String, data: Any, token: String, callback: Function) : void

Events

Events provide the most effective means of customizing the persistence behavior in the JSS data grid. They can be utilized to intercept, modify, or prevent user actions.

Event Description
onbeforesave Executed before a server update request.
onbeforesave(spreadsheet: Object, worksheet: Object, data: Object) : Object
It will return false to cancel the event or the replacement for the original data. Data is the information about the event that requires server persistence.
onsave It will bring information about the server update request.
onsave(spreadsheet: Object, worksheet: Object, data: Object, result, Object) : void

Settings

On the spreadsheet configuration level

Property Description
server: string URL for the server persistence requests. A global URL for all worksheets.

On the worksheet configuration level

Property Description
persistence: string URL for the server persistence requests. One URL for each worksheet.
columns.primaryKey: boolean The primaryKey defines which column will be considered the ID for the records.
rows.id: number Define the ID for the row

Examples

Posting data to a remote server

When the persistence property is set to true, an AJAX request will occur for each update made to the spreadsheet.

<html>
<script src="https://jspreadsheet.com/v11/jspreadsheet.js"></script>
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://jspreadsheet.com/v11/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />

<div id="spreadsheet"></div>

<script>
// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('YjQ2YjEwYzQ5NTA4MThmNjI5YjNjOThjN2RiYzE2ZmMxNWJmZTk2ZGM5ZWQ4MzkyN2E3MDkwNzRlYTIyNWJlNTFiNDliNTNlZjNkODE2Y2YyZGYyODY0ZWJkZDA4NTJmOTZjOTEyZmEyOWFjMmEwYzEwNGJmM2QxZDRkYTk5NDQsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpNME9EWTROVFUzTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

// Create the spreadsheet
jspreadsheet(document.getElementById('spreadsheet'), {
    worksheets: [{
        url: '/jspreadsheet/books.json',
        columns: [
            {
                type: 'autonumber',
                width: '50px',
                title: 'Code',
                name: 'id',
                readOnly: true,
                primaryKey: true
            },
            {
                type: 'image',
                title: 'Image',
                name: 'thumbnailUrl',
                render: function(cell, val, col, row) {
                    if (! val) {
                        cell.innerHTML = '<img src="https://images-na.ssl-images-amazon.com/images/I/21%2Bwfxx2lyL._SX319_BO1,204,203,200_.jpg" style="width:60px;" />';
                    }
                }
            },
            {
                type: 'text',
                title: 'Title',
                name: 'title'
            },
            {
                type: 'text',
                width: '55px',
                title: 'Pages',
                name: 'pageCount'
            },
            {
                type: 'calendar',
                width: '90px',
                title: 'Published',
                name: 'publishedDate'
            },
            {
                type: 'text',
                title: 'Author',
                name: 'authors'
            },
            {
                type: 'dropdown',
                title: 'Categories',
                name: 'categories',
                source: ['Internet','Web Development', 'Java', 'Mobile', 'Open Source'],
                multiple: true,
                render: 'tag'
            },
        ],
        persistence: '/jspreadsheet/save',
    }]
});
</script>
</html>
import React, { useRef } from "react";
import { Spreadsheet, Worksheet } from "@jspreadsheet/react";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";

const license = 'YjQ2YjEwYzQ5NTA4MThmNjI5YjNjOThjN2RiYzE2ZmMxNWJmZTk2ZGM5ZWQ4MzkyN2E3MDkwNzRlYTIyNWJlNTFiNDliNTNlZjNkODE2Y2YyZGYyODY0ZWJkZDA4NTJmOTZjOTEyZmEyOWFjMmEwYzEwNGJmM2QxZDRkYTk5NDQsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpNME9EWTROVFUzTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

export default function App() {
    const spreadsheet = useRef();

    // Columns
    const columns = [{
            type: 'autonumber',
            width: '50px',
            title: 'Code',
            name: 'id',
            readOnly: true,
            primaryKey: true
        },
        {
            type: 'image',
            width: '80px',
            title: 'Image',
            name: 'thumbnailUrl',
            render: function(cell, val, col, row) {
                if (! val) {
                    cell.innerHTML = '<img src="https://images-na.ssl-images-amazon.com/images/I/21%2Bwfxx2lyL._SX319_BO1,204,203,200_.jpg" style="width:60px;" />';
                }
            }
        },
        { type: 'text', width: '200px', title: 'Title', name: 'title' },
        { type: 'text', width: '55px', title: 'Pages', name: 'pageCount' },
        { type: 'calendar', width: '90px', title: 'Published', name: 'publishedDate' },
        { type: 'text', width: '200px', title: 'Author', name: 'authors' },
        { type: 'dropdown', width: '180px', title: 'Categories', name: 'categories',
            source: [ 'Internet','Web Development', 'Java', 'Mobile', 'Open Source' ],
            multiple: true, render: 'tag' }
    ];

    // Render react component
    return (
        <Spreadsheet ref={spreadsheet} license={license}>
            <Worksheet
                url="/jspreadsheet/books.json"
                columns={columns}
                search
                persistence="/jspreadsheet/save" />
        </Spreadsheet>
    );
}
<template>
    <Spreadsheet ref="spreadsheet" :license="license">
        <Worksheet :columns="columns"
            url="/jspreadsheet/books.json"
            search
            persistence="/jspreadsheet/save" />
    </Spreadsheet>
</template>

<script>
import { Spreadsheet, Worksheet } from "@jspreadsheet/vue";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";

const license = 'YjQ2YjEwYzQ5NTA4MThmNjI5YjNjOThjN2RiYzE2ZmMxNWJmZTk2ZGM5ZWQ4MzkyN2E3MDkwNzRlYTIyNWJlNTFiNDliNTNlZjNkODE2Y2YyZGYyODY0ZWJkZDA4NTJmOTZjOTEyZmEyOWFjMmEwYzEwNGJmM2QxZDRkYTk5NDQsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpNME9EWTROVFUzTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

export default {
    components: {
        Spreadsheet,
        Worksheet,
    },
    data() {
        // Columns
        const columns = [
            {
                type: 'autonumber',
                width: '50px',
                title: 'Code',
                name: 'id',
                readOnly: true,
                primaryKey: true
            },
            {
                type: 'image',
                width: '80px',
                title: 'Image',
                name: 'thumbnailUrl',
                render: function(cell, val, col, row) {
                    if (! val) {
                        cell.innerHTML = '<img src="https://images-na.ssl-images-amazon.com/images/I/21%2Bwfxx2lyL._SX319_BO1,204,203,200_.jpg" style="width:60px;" />';
                    }
                }
            },
            { type: 'text', width: '200px', title: 'Title', name: 'title' },
            { type: 'text', width: '55px', title: 'Pages', name: 'pageCount' },
            { type: 'calendar', width: '90px', title: 'Published', name: 'publishedDate' },
            { type: 'text', width: '200px', title: 'Author', name: 'authors' },
            { type: 'dropdown', width: '180px', title: 'Categories', name: 'categories',
                source: [ 'Internet','Web Development', 'Java', 'Mobile', 'Open Source' ],
                multiple: true, render: 'tag' }
        ];

        return {
            columns,
            license,
        };
    }
}
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet";

import "jspreadsheet/dist/jspreadsheet.css"
import "jsuites/dist/jsuites.css"

// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('YjQ2YjEwYzQ5NTA4MThmNjI5YjNjOThjN2RiYzE2ZmMxNWJmZTk2ZGM5ZWQ4MzkyN2E3MDkwNzRlYTIyNWJlNTFiNDliNTNlZjNkODE2Y2YyZGYyODY0ZWJkZDA4NTJmOTZjOTEyZmEyOWFjMmEwYzEwNGJmM2QxZDRkYTk5NDQsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpNME9EWTROVFUzTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

@Component({
    standalone: true,
    selector: "app-root",
    template: `<div #spreadsheet></div>`
})
export class AppComponent {
    @ViewChild("spreadsheet") spreadsheet: ElementRef;
    // Worksheets
    worksheets: jspreadsheet.worksheetInstance[];
    // Create a new data grid
    ngAfterViewInit() {
        // Create spreadsheet
        this.worksheets = jspreadsheet(this.spreadsheet.nativeElement, {
            url: '/jspreadsheet/books.json',
            columns: [
                {
                    type: 'autonumber',
                    width: '50px',
                    title: 'Code',
                    name: 'id',
                    readOnly: true,
                    primaryKey: true
                },
                {
                    type: 'image',
                    width: '80px',
                    title: 'Image',
                    name: 'thumbnailUrl',
                    render: function(cell, val, col, row) {
                        if (! val) {
                            cell.innerHTML = '<img src="https://images-na.ssl-images-amazon.com/images/I/21%2Bwfxx2lyL._SX319_BO1,204,203,200_.jpg" style="width:60px;" />';
                        }
                    }
                },
                {
                    type: 'text',
                    width: '200px',
                    title: 'Title',
                    name: 'title'
                },
                {
                    type: 'text',
                    width: '55px',
                    title: 'Pages',
                    name: 'pageCount'
                },
                {
                    type: 'calendar',
                    width: '90px',
                    title: 'Published',
                    name: 'publishedDate'
                },
                {
                    type: 'text',
                    width: '200px',
                    title: 'Author',
                    name: 'authors'
                },
                {
                    type: 'dropdown',
                    width: '180px',
                    title: 'Categories',
                    name: 'categories',
                    source: ['Internet','Web Development', 'Java', 'Mobile', 'Open Source'],
                    multiple: true,
                    render: 'tag'
                },
            ],
            allowComments:true,
            search: true,
            persistence: '/jspreadsheet/save',
        });
    }
}

Database ID synchronization and sequences

The following example demonstrates several concepts related to record ID synchronization and sequences in Jspreadsheet:

  • Loading data with hidden IDs for the user;
  • Creating a custom column with an icon to perform actions using the record ID
  • Obtaining the record ID from a remote server when a new row is added.

NOTE: the example shows one new line, but you can interact to get more ids if more than one row is added.

<html>
<script src="https://jspreadsheet.com/v11/jspreadsheet.js"></script>
<script src="https://jsuites.net/v5/jsuites.js"></script>
<link rel="stylesheet" href="https://jspreadsheet.com/v11/jspreadsheet.css" type="text/css" />
<link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />

<div id="spreadsheet"></div>

<script>
let action = function() {
    let methods = {};
 
    methods.createCell = function(cell, value, x, y, instance, options) {
        let input = document.createElement('i');
        input.className = 'material-icons';
        input.style.cursor = 'pointer';
        input.style.fontSize = '22px';
        input.innerHTML = "search";
        input.onclick = function() {
            let id = instance.getRowId(y);
            // Do some action
            alert(id);
        }
 
        cell.appendChild(input);

        // Readonly
        cell.classList.add('readonly');
    }
 
    return methods;
}();
 
jspreadsheet(document.getElementById('spreadsheet'), {
    worksheets: [{
        data: [
            { id:1, data:['Google', '5', ''] },
            { id:2, data:['Bing', '4', ''] },
            { id:3, data:['Yahoo', '1', ''] },
            { id:4, data:['Duckduckgo', '5', ''] },
        ],
        columns: [
            { type: 'text', width:'400px' },
            { type: 'rating', width:'100px' },
            { type: action, width:'100px' },
        ],
        persistence: '/jspreadsheet/save',
    }],
    oninsertrow: function(worksheet, rows) {
        rows.forEach((value) => {
            // Go in remotely get the id and return to the cell
            jSuites.ajax({
                url: '/jspreadsheet/id',
                method: 'GET',
                dataType: 'json',
                success: function(result) {
                    // The new id is
                    alert('The new row has id: ' + result);
                    // set row id
                    worksheet.setRowId(value.row, result);
                }
            })
        })
    }
});
</script>
</html>
import React, { useRef } from "react";
import { Spreadsheet, Worksheet } from "@jspreadsheet/react";
import jSuites from "jsuites";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";

const license = 'YjQ2YjEwYzQ5NTA4MThmNjI5YjNjOThjN2RiYzE2ZmMxNWJmZTk2ZGM5ZWQ4MzkyN2E3MDkwNzRlYTIyNWJlNTFiNDliNTNlZjNkODE2Y2YyZGYyODY0ZWJkZDA4NTJmOTZjOTEyZmEyOWFjMmEwYzEwNGJmM2QxZDRkYTk5NDQsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpNME9EWTROVFUzTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

const action = function() {
    const methods = {};

    methods.createCell = function(cell, value, x, y, instance, options) {
        let input = document.createElement('i');
        input.className = 'material-icons';
        input.style.cursor = 'pointer';
        input.style.fontSize = '22px';
        input.innerHTML = "search";
        input.onclick = function() {
            let id = instance.getRowId(y);
            // Do some action
            alert(id);
        }

        cell.appendChild(input);

        // Readonly
        cell.classList.add('readonly');
    }

    return methods;
}();

export default function App() {
    const spreadsheet = useRef();

    // Data
    const data = [
        { id:1, data:['Google', '5', ''] },
        { id:2, data:['Bing', '4', ''] },
        { id:3, data:['Yahoo', '1', ''] },
        { id:4, data:['Duckduckgo', '5', ''] },
    ];
    // Event for insert row
    const oninsertrow = function(worksheet, rows) {
        rows.forEach((value) => {
            // Go in remotely get the id and return to the cell
            jSuites.ajax({
                url: '/jspreadsheet/id',
                method: 'GET',
                dataType: 'json',
                success: function(result) {
                    // The new id is
                    alert('The new row has id: ' + result);
                    // set row id
                    worksheet.setRowId(value.row, result);
                }
            })
        })
    }
    // Columns
    const columns = [
        { type: 'text', width:'400px' },
        { type: 'rating', width:'100px' },
        { type: action, width:'100px' },
    ];

    // Render react component
    return (
        <Spreadsheet ref={spreadsheet} license={license} oninsertrow={oninsertrow}>
            <Worksheet data={data} persistence="/jspreadsheet/save" columns={columns} />
        </Spreadsheet>
    );
}
<template>
    <Spreadsheet ref="spreadsheet" :license="license" :oninsertrow="oninsertrow">
        <Worksheet :data="data" :columns="columns" />
    </Spreadsheet>
</template>

<script>
import { Spreadsheet, Worksheet } from "@jspreadsheet/vue";
import jSuites from "jsuites";
import "jsuites/dist/jsuites.css";
import "jspreadsheet/dist/jspreadsheet.css";

const license = 'YjQ2YjEwYzQ5NTA4MThmNjI5YjNjOThjN2RiYzE2ZmMxNWJmZTk2ZGM5ZWQ4MzkyN2E3MDkwNzRlYTIyNWJlNTFiNDliNTNlZjNkODE2Y2YyZGYyODY0ZWJkZDA4NTJmOTZjOTEyZmEyOWFjMmEwYzEwNGJmM2QxZDRkYTk5NDQsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpNME9EWTROVFUzTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==';

const action = function() {
    const methods = {};

    methods.createCell = function(cell, value, x, y, instance, options) {
        let input = document.createElement('i');
        input.className = 'material-icons';
        input.style.cursor = 'pointer';
        input.style.fontSize = '22px';
        input.innerHTML = "search";
        input.onclick = function() {
            let id = instance.getRowId(y);
            // Do some action
            alert(id);
        }

        cell.appendChild(input);

        // Readonly
        cell.classList.add('readonly');
    }

    return methods;
}();

export default {
    components: {
        Spreadsheet,
        Worksheet,
    },
    methods {
        // Event for insert row
        oninsertrow(worksheet, rows) {
          rows.forEach((value) => {
            // Go in remotely get the id and return to the cell
            jSuites.ajax({
              url: '/jspreadsheet/id',
              method: 'GET',
              dataType: 'json',
              success: function(result) {
                // The new id is
                alert('The new row has id: ' + result);
                // set row id
                worksheet.setRowId(value.row, result);
              }
            })
          })
        }
    },
    data() {
        // Data
        const data = [
            { id:1, data:['Google', '5', ''] },
            { id:2, data:['Bing', '4', ''] },
            { id:3, data:['Yahoo', '1', ''] },
            { id:4, data:['Duckduckgo', '5', ''] },
        ];
        // Columns
        const columns = [
            { type: 'text', width:'400px' },
            { type: 'rating', width:'100px' },
            { type: action, width:'100px' },
        ];

        return {
            data,
            columns,
            license,
        };
    }
}
</script>
import { Component, ViewChild, ElementRef } from "@angular/core";
import jspreadsheet from "jspreadsheet";

import "jspreadsheet/dist/jspreadsheet.css"
import "jsuites/dist/jsuites.css"

// Set your JSS license key (The following key only works for one day)
jspreadsheet.setLicense('YjQ2YjEwYzQ5NTA4MThmNjI5YjNjOThjN2RiYzE2ZmMxNWJmZTk2ZGM5ZWQ4MzkyN2E3MDkwNzRlYTIyNWJlNTFiNDliNTNlZjNkODE2Y2YyZGYyODY0ZWJkZDA4NTJmOTZjOTEyZmEyOWFjMmEwYzEwNGJmM2QxZDRkYTk5NDQsZXlKamJHbGxiblJKWkNJNklpSXNJbTVoYldVaU9pSktjM0J5WldGa2MyaGxaWFFpTENKa1lYUmxJam94TnpNME9EWTROVFUzTENKa2IyMWhhVzRpT2xzaWFuTndjbVZoWkhOb1pXVjBMbU52YlNJc0ltTnZaR1Z6WVc1a1ltOTRMbWx2SWl3aWFuTm9aV3hzTG01bGRDSXNJbU56WWk1aGNIQWlMQ0ozWldJaUxDSnNiMk5oYkdodmMzUWlYU3dpY0d4aGJpSTZJak0wSWl3aWMyTnZjR1VpT2xzaWRqY2lMQ0oyT0NJc0luWTVJaXdpZGpFd0lpd2lkakV4SWl3aVkyaGhjblJ6SWl3aVptOXliWE1pTENKbWIzSnRkV3hoSWl3aWNHRnljMlZ5SWl3aWNtVnVaR1Z5SWl3aVkyOXRiV1Z1ZEhNaUxDSnBiWEJ2Y25SbGNpSXNJbUpoY2lJc0luWmhiR2xrWVhScGIyNXpJaXdpYzJWaGNtTm9JaXdpY0hKcGJuUWlMQ0p6YUdWbGRITWlMQ0pqYkdsbGJuUWlMQ0p6WlhKMlpYSWlMQ0p6YUdGd1pYTWlYU3dpWkdWdGJ5STZkSEoxWlgwPQ==');

const action = function() {
    let methods = {};

    methods.createCell = (cell, value, x, y, instance, options) => {
        let input = document.createElement('i');
        input.className = 'material-icons';
        input.style.cursor = 'pointer';
        input.style.fontSize = '22px';
        input.innerHTML = "search";
        input.onclick = function() {
            let id = instance.getRowId(y);
            // Do some action
            alert(id);
        }

        cell.appendChild(input);

        // Readonly
        cell.classList.add('readonly');
    }

    return methods;
}();

@Component({
    standalone: true,
    selector: "app-root",
    template: `<div #spreadsheet></div>`,
})
export class AppComponent {
    @ViewChild("spreadsheet") spreadsheet: ElementRef;
    // Worksheets
    worksheets: jspreadsheet.worksheetInstance[];
    // Create a new data grid
    ngAfterViewInit() {
        // Create spreadsheet
        this.worksheets = jspreadsheet(this.spreadsheet.nativeElement, {
            worksheets: [{
                data: [
                    { id:1, data:['Google', '5', ''] },
                    { id:2, data:['Bing', '4', ''] },
                    { id:3, data:['Yahoo', '1', ''] },
                    { id:4, data:['Duckduckgo', '5', ''] },
                ],
                columns: [
                    { type: 'text', width:'400px' },
                    { type: 'rating', width:'100px' },
                    { type: action, width:'100px' },
                ],
                persistence: '/jspreadsheet/save',
            }],
            oninsertrow: function(worksheet, rows) {
                rows.forEach((value) => {
                    // Go in remotely get the id and return to the cell
                    jSuites.ajax({
                        url: '/jspreadsheet/id',
                        method: 'GET',
                        dataType: 'json',
                        success: function(result) {
                            // The new id is
                            alert('The new row has id: ' + result);
                            // set row id
                            worksheet.setRowId(value.row, result);
                        }
                    })
                })
            }
        });
    }
}