JSFiddle - React, Tailwind, and code Playground

by Benahmed Taoufiq

HTML

<header>
        <h1>Sélection plage de cellules</h1>
    </header>
    <main>
        <div id="grille-container">
            <table id="grille">
                <tr>
                    <th>Lorem</th>
                    <th>ipsum</th>
                    <th>dolor</th>
                    <th>sit</th>
                    <th>amet</th>
                    <th>consectetur</th>
                    <th>adipiscing</th>
                    <th>elit</th>
                </tr>
                <tr>
                    <td>sed-L0-C0</td>
                    <td>do-L0-C1</td>
                    <td>eiusmod</td>
                    <td>tempor</td>
                    <td>incididunt</td>
                    <td>ut</td>
                    <td>labore</td>
                    <td>et</td>
                </tr>
                <tr>
                    <td>dolore-L1-C0</td>
                    <td>magna-L1-C1</td>
                    <td>aliqua</td>
                    <td>Ut</td>
                    <td>enim</td>
                    <td>ad</td>
                    <td>minim</td>
                    <td>veniam</td>
                </tr>
                <tr>
                    <td>quis-L2-C0</td>
                    <td>nostrud-L2-C1</td>
                    <td>exercitation</td>
                    <td>ullamco</td>
                    <td>laboris</td>
                    <td>nisi</td>
                    <td>ut</td>
                    <td>aliquip</td>
                </tr>
                <tr>
                    <td>ex-L3-C0</td>
                    <td>ea-L3-C1</td>
                    <td>commodo</td>
                    <td>consequat</td>
                    <td>Duis</td>
                    <td>aute</td>
                    <td>irure</td>
                    <td>dolor</td>
                </tr>
                <tr>
                    <td>in-L4-C0</td>
                    <td>reprehenderit-L4-C1</td>
                    <td>in</td>
                   ...

CSS

#grille-container {
            margin: 5% 10%;
        }

        #grille {
            font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
            border-collapse: collapse;
            width: 100%;
            user-select: none;
        }

        #grille td,
        #grille th {
            border: 1px solid #ddd;
            padding: 8px;
        }

        #grille tr:nth-child(even) {
            background-color: #f2f2f2;
        }

        #grille tr:hover {
            background-color: #ddd;
        }

        #grille th {
            padding-top: 12px;
            padding-bottom: 12px;
            text-align: left;
            background-color: #4CAF50;
            color: white;
        }

        #grille td.selected {
            background-color: #927de0;
        }

JavaScript

"use strict";


$(function () {
    // Coordonnées des deux cellules de début et de fin
    let selection = {
        debut: { l: 0, c: 0 },
        fin: { l: 0, c: 0 }
    };
    let ui={cells:$("#grille td"),rows:'',min:'',max:'',trHaveSelected:{first:'',last:'',all:''},
		page:{x:'',y:''},debut:{tr:'',td:''},element:''};
    let active = false;



    ui.cells.on({
        "mousedown": evt => {
           ui. cells.removeClass("selected");
            active = true;
            selection.debut.l = $(evt.target).parent().index() ; // Numéro de la ligne
            selection.debut.c = $(evt.target).index(); // Numéro de la colonne
            ui.debut.tr=$("#grille tr").eq(selection.debut.l);
            ui.debut.td=ui.debut.tr.find('td').eq(selection.debut.c);
            ui.page.x=evt.pageX;
		        ui.page.y=evt.pageY;
            $(evt.target).addClass("selected");



        },
        "mouseup": evt => {
            if (active) {
                selection.fin.l = $(evt.target).parent().index(); // Numéro de la ligne
                selection.fin.c = $(evt.target).index(); // Numéro de la colonne
         				active = false;
                console.log("Début sélection", selection.debut, 
								"fin sélection !", selection.fin,
								", first tr index :",$(ui.rows).first().index(), 
                ', last tr index :',$(ui.rows).last().index(), 
								', min :',ui.min, ', max : ',ui.max ); 
            }
        },
        "mousemove": evt => {
            if (active) {
								
                ui.element=$(evt.target);
								
                ui.element.addClass("selected");
                  if(evt.pageX>ui.page.x){//mouvement à droite
                    ui.page.x=evt.pageX;
                    if(ui.element.prev('.selected').index()<ui.debut.td.index()){
                      $('tr td:nth-child('
                      +(ui.element.prev('.selected').index()+1)+')')
                      .removeClass('selected');
                    }
           ...