Search results

Collaborative Editing in JavaScript Spreadsheet control

24 Sep 2021 / 4 minutes to read

The collaborative editing support allows you to work at a spreadsheet collaboratively with other users. Multiple users can access to the the same spreadsheet simultaneously.

  • To use Collaborative editing, inject the CollaborativeEditing module in the spreadsheet.

Dependencies

The following list of dependencies are required to use the collaborative editing support in spreadsheet.

Copied to clipboard
|-- @aspnet/signalr
   |-- eventsource
   |-- request
   |-- ws
  • Run the command npm i @aspnet/signalr to install @aspnet/signalr packages in your application.

Client configuration

To broadcast the data for every action is spreadsheet, you need to transfer the data to the server through send method in actionComplete event and receive the same data by using the dataReceived method. In the dataReceived method, you need to update the action to the connected clients through updateAction method.

The following code example shows Collaborative Editing support in the Spreadsheet control.

Copied to clipboard
import { Spreadsheet, CollaborativeEditing } from '@syncfusion/ej2-spreadsheet';
import * as signalR from '@aspnet/signalr';
import { data } from './datasource.ts';

// To Inject CollaborativeEditing module.

Spreadsheet.Inject(CollaborativeEditing);

// For signalR Hub connection
const connection: signalR.HubConnection = new signalR.HubConnectionBuilder().withUrl('https://localhost:44385/hubs/spreadsheethub', { // localhost from AspNetCore service
    skipNegotiation: true,
    transport: signalR.HttpTransportType.WebSockets
  }).build();

//Initialize the SpreadSheet control
let spreadsheet: Spreadsheet = new Spreadsheet({
    sheets: [{
                ranges: [{ dataSource: data }],
               columns: [{ width: 130 }, { width: 110 },{ width: 110},
                          { width: 90 }, { width: 90 }, {width: 90}, { width: 90 }, {width: 90}]
            }],
  actionComplete: (args) => {
       connection.send('BroadcastData', JSON.stringify(args)); // send the action data to the server
    },
});

spreadsheet.appendTo('#spreadsheet');

 connection.on('dataReceived', (data: string) => {
    let model: CollaborativeEditArgs = JSON.parse(data) as CollaborativeEditArgs;
    spreadsheet.updateAction({ action: model.action, eventArgs: model.eventArgs }); // update the action to the connected clients
 });
    connection.start().then(() => { // to start the server
        console.log('server connected!!!');
    }).catch(err => console.log(err));

Server configuration

To make the communication between the server to the connected clients and from clients to the server, you need to configure the signalR Hubs using the following code.

Copied to clipboard
import * as signalR from '@aspnet/signalr';

// For signalR Hub connection

const connection: signalR.HubConnection = new signalR.HubConnectionBuilder().withUrl('https://localhost:44385/hubs/spreadsheethub', { // localhost from AspNetCore service
    skipNegotiation: true,
    transport: signalR.HttpTransportType.WebSockets
  }).build();

Hub configuration

Initially create a AspNetCore project and add the hub file for sending and receiving the data between server and clients.

Copied to clipboard
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace WebApplication.Hubs
{
    public class SpreadsheetHub : Hub
    {
        public async Task BroadcastData(string data)
        {
            await Clients.All.SendAsync("dataReceived", data);
        }
    }
}

To configure the SignalR middleware by registering the following service in the ConfigureServices method of the Startup class.

Copied to clipboard
    services.AddSignalR();

To set up the SignalR routes by calling MapHub in the Configure method of the Startup class.

Copied to clipboard
    app.UseEndpoints(endpoints =>

    {

        endpoints.MapRazorPages();

        endpoints.MapHub<SpreadsheetHub>("/spreadsheetHub");

    });

For hosting the service, you may use the above code snippet or download and run the local service.

Prevent the particular action update for collaborative client

Using the action argument from the actionComplete event, you can prevent the particular action update for collaborative client.

The following code example shows how to prevent collaborative client from updating the format action.

Copied to clipboard
import { Spreadsheet, CollaborativeEditing } from '@syncfusion/ej2-spreadsheet';
import * as signalR from '@aspnet/signalr';
import { data } from './datasource.ts';

// To Inject CollaborativeEditing module.

Spreadsheet.Inject(CollaborativeEditing);

// For signalR Hub connection
const connection: signalR.HubConnection = new signalR.HubConnectionBuilder().withUrl('https://localhost:44385/hubs/spreadsheethub', { // localhost from AspNetCore service
    skipNegotiation: true,
    transport: signalR.HttpTransportType.WebSockets
  }).build();

//Initialize the SpreadSheet control
let spreadsheet: Spreadsheet = new Spreadsheet({
    sheets: [{
                ranges: [{ dataSource: data }],
                columns: [{ width: 130 }, { width: 110 },{ width: 110},
                          { width: 90 }, { width: 90 }, {width: 90}, { width: 90 }, {width: 90}]
            }],
  actionComplete: (args) => {
      if (args.action != 'format'){  // prevent the format action
         connection.send('BroadcastData', JSON.stringify(args)); // send the action data to the server
      }
    },
});

spreadsheet.appendTo('#spreadsheet');

 connection.on('dataReceived', (data: string) => {
    let model: CollaborativeEditArgs = JSON.parse(data) as CollaborativeEditArgs;
    spreadsheet.updateAction({ action: model.action, eventArgs: model.eventArgs }); // update the action to the connected clients
 });
    connection.start().then(() => { // to start the server
        console.log('server connected!!!');
    }).catch(err => console.log(err));

See Also