Page 1 sur 1

onclick sur <tr> tableau

Posté : 30 sept. 2018, 19:47
par GeGaX
Bonjour,
J'ai ce popup.html

Code : Tout sélectionner

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" href="popup.css">
    </head>
    <body>
        <div class="container">
            <div class="table-wrap table-thead-fixed">
                <table>
                    <thead>
                        <tr>
                            <th>Date</th>
                            <th>Time</th>
                            <th title="Timezone">TZ</th>
                            <th>Position</th>
                            <th title="Time To Waypoint">TTW</th>
                            <th title="Distance To Waypoint">DTW</th>
                            <th title="Distance To Go">DTG</th>
                            <th title="True Wind Direction">TWD</th>
                            <th title="True Wind Speed">TWS</th>
                            <th title="True Wind Angle">TWA</th>
                            <th title="Bearing To Waypoint">BTW</th>
                            <th>Sail</th>
                            <th title="Speed Through Water">STW</th>
                            <th title="Average True Wind Angle">ATWA</th>
                            <th title="Average Bearing To Waypoint">ABTW</th>
                        </tr>
                    </thead>
                    <tbody id="pointsTable" align="center">
                    </tbody>
                </table>
            </div>
            <br>
            <div id="localtimeDiv">
                <input type="checkbox" id="localtime" tabindex="-1">
                <label>Local Time</label>
            </div>
            <div id="versionDiv">
                <label>Version</label>
                <label id="version"></label>
            </div>
            <div id="gpxDiv">
                <input class="cssButton" type="button" id="gpxExport" value=".GPX" tabindex="-1">
            </div>
            <br>
            <textarea id="gpxOutput" rows="2" readonly tabindex="-1">...::: Click on GPX button for generate file :::...
Select All | Copy selection | Paste on your text editor | Save the file with the .gpx extension</textarea>
        </div>
    </body>
    <script src="bundle.js"></script>
    <script src="resizeTables.js"></script>
</html>
et ce bundle.js (= popup.js + librairies moment-timezone et xmlbuilder)
Je mets que la partie popup.js

Code : Tout sélectionner

/************
 * popup.js *
 ************/
const builder = require('xmlbuilder');
const moment = require('moment-timezone');

var background = chrome.extension.getBackgroundPage();

var twaList = [];
var btwList = [];
var ttwLast = "T+ 0:00";
var twaLast = undefined;
var btwLast = undefined;

function createCell(value, row) {
    var cell = document.createElement("td");
    cell.innerHTML = value;
    row.appendChild(cell);
}

function ttwStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function dtwStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function dtgStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function twsStyling(value1, value2, cell) {
    var tws_foil = value1.replace(" kt", "");
    var twa_bd = value2.replace("\u00B0", "");
    if (tws_foil >= 11.1 && tws_foil <= 39.9 && Math.abs(twa_bd) >= 71 && Math.abs(twa_bd) <= 169) {
        cell.style.backgroundColor = "black";
        cell.style.color = "white";
    }
    cell.innerHTML = tws_foil + " kt";
}

function twaStyling(value, cell) {
    var twa_bd = value.replace("\u00B0", "");
    if (twa_bd >= 0) {
        cell.style.color = "green";
    } else {
        cell.style.color = "red";
    }
    cell.innerHTML = Math.abs(twa_bd) + "\u00B0";
}

function btwStyling(value, cell) {
    cell.style.color = "blue";
    cell.innerHTML = value;
}

function sailStyling(value, cell) {
    switch (value.trim()) {
            // Upwind sail
        case "Jib":
            cell.style.backgroundColor = "#FFD479";
            break;
        case "LJ":
            cell.style.backgroundColor = "#FFFC79";
            break;
        case "Stay":
            cell.style.backgroundColor = "#D4FB79";
            break;
            // Downwind sail
        case "Spi":
            cell.style.backgroundColor = "#76D6FF";
            break;
        case "LG":
            cell.style.backgroundColor = "#7A81FF";
            break;
        case "HG":
            cell.style.backgroundColor = "#D783FF";
            break;
            // Reaching sail
        case "C0":
            cell.style.backgroundColor = "#FF7E79";
            break;
    }
    cell.innerHTML = value;
}

function atwaStyling(value, cell) {
    if (value >= 0) {
        cell.style.color = "green";
    } else {
        cell.style.color = "red";
    }
    if (value !== "-") {
        cell.innerHTML = Math.abs(value) + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}

function abtwStyling(value, cell) {
    cell.style.color = "blue";
    if (value !== "-") {
        cell.innerHTML = value + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}

function createCellWithCustomStyling(value, row, customStyling) {
    var cell = document.createElement("td");
    customStyling(value, cell);
    row.appendChild(cell);
}

function createCellWithCustomStyling2(value1, value2, row, customStyling) {
    var cell = document.createElement("td");
    customStyling(value1, value2, cell);
    row.appendChild(cell);
}

function space(value) {
    if (value < 10) {
        value = " " + value;
    }
    return value;
}

function zero(value) {
    if (value < 10) {
        value = "0" + value;
    }
    return value;
}

function dmsConv(latitude, longitude) {
    var latAbs = Math.abs(latitude);
    var latDeg = Math.trunc(latAbs);
    var latMin = Math.trunc((latAbs - latDeg) * 60);
    var latSec = Math.trunc((((latAbs - latDeg) * 60) - latMin ) * 60);
    var latCard = (latitude >= 0) ? "N" : "S";

    var lonAbs = Math.abs(longitude);
    var lonDeg = Math.trunc(lonAbs);
    var lonMin = Math.trunc((lonAbs - lonDeg) * 60);
    var lonSec = Math.trunc((((lonAbs - lonDeg) * 60) - lonMin ) * 60);
    var lonCard = (longitude >= 0) ? "E" : "W";

    return zero(latDeg) + "\u00B0" + zero(latMin) + "\u0027" + zero(latSec) + "\u0022" + latCard + " - " + zero(lonDeg) + "\u00B0" + zero(lonMin) + "\u0027" + zero(lonSec) + "\u0022" + lonCard;
}

function atwaCalc(twaList) {
    const
    twaData = twaList;
    Math.radians = function (degrees) {
        return degrees * Math.PI / 180;
    },
    Math.degrees = function (radians) {
        return radians * 180 / Math.PI;
    };

    let
    arX = [],
        arY = [],
        somX = 0,
        somY = 0,
        avgX = 0,
        avgY = 0,
        atwa = 0;

    for (const [i, angle] of twaData.entries()) {
        arX[i] = Math.cos(Math.radians(angle));
        arY[i] = Math.sin(Math.radians(angle));
    }

    for (const value of arX) {
        somX += value;
    }
    avgX = somX / arX.length;

    for (const value of arY) {
        somY += value;
    }
    avgY = somY / arY.length;

    atwa = Math.round(Math.degrees(Math.atan2(avgY, avgX)));
    if (isNaN (atwa)) {
        atwa = "-";
    }
    return atwa ;
}

function abtwCalc(btwList) {
    const
    btwData = btwList;
    Math.radians = function (degrees) {
        return degrees * Math.PI / 180;
    },
    Math.degrees = function (radians) {
        return radians * 180 / Math.PI;
    };

    let
    arX = [],
        arY = [],
        somX = 0,
        somY = 0,
        avgX = 0,
        avgY = 0,
        abtw = 0;

    for (const [i, angle] of btwData.entries()) {
        arX[i] = Math.cos(Math.radians(angle));
        arY[i] = Math.sin(Math.radians(angle));
    }

    for (const value of arX) {
        somX += value;
    }
    avgX = somX / arX.length;

    for (const value of arY) {
        somY += value;
    }
    avgY = somY / arY.length;

    abtw = Math.round(Math.degrees(Math.atan2(avgY, avgX)));
    if (isNaN (abtw)) {
        abtw = "-";
    } else if (abtw < 0) {
        abtw += 360;
    }
    return abtw;
}

function reinitializeDisplay() {
    document.getElementById("pointsTable").innerHTML = "";
}

function TzToLocal(date, time, timezone) {
    var tzGuess = moment.tz.guess();

    if ((timezone === "CET") || (timezone === "CEST")) {
        var CetOrCestToUtc = moment.tz(date + " " + time, "Europe/Paris").utc();
        var localDateTz = moment.utc(CetOrCestToUtc).tz(tzGuess);
    } else if (timezone === "UTC") {
        var localDateTz = moment.utc(date + " " + time).tz(tzGuess);
    }

    var offset = localDateTz.utcOffset();
    var absOffset = Math.abs(offset);
    var sign = (offset > 0) ? "+" : "-";
    var hoursOffset = Math.trunc(absOffset / 60);
    var MinutesHoursOffset = (hoursOffset === 0) ? "\u00b1" + "0" : sign + hoursOffset;
    var minutesOffset = absOffset % 60;
    var HoursMinutesOffset = (minutesOffset === 0) ? MinutesHoursOffset : sign + hoursOffset + ":" + minutesOffset;

    var formatDate = localDateTz.format('YYYY-MM-DD');
    var formatTime = localDateTz.format('HH:mm');
    var formatTimeZone = "UTC" + HoursMinutesOffset;
    return [formatDate, formatTime, formatTimeZone];
}

function displayTable(localTime) {
    points.forEach(function (element) {
        var row = document.createElement("tr");
        document.getElementById("pointsTable").appendChild(row);
        if (localTime) {
            var localTZ = TzToLocal(element.date, element.time, element.timezone);
            createCell(localTZ[0], row);
            createCell(localTZ[1], row);
            createCell(localTZ[2], row);
        } else {
            createCell(element.date, row);
            createCell(element.time, row);
            createCell(element.timezone, row);
        }
        var position = dmsConv(element.latitude, element.longitude);
        createCell(position, row);
        createCellWithCustomStyling(element.ttw, row, ttwStyling);
        createCellWithCustomStyling(element.dtw, row, dtwStyling);
        createCellWithCustomStyling(element.dtg, row, dtgStyling);
        createCell(element.twd, row);
        createCellWithCustomStyling2(element.tws, element.twa, row, twsStyling);
        createCellWithCustomStyling(element.twa, row, twaStyling);
        createCellWithCustomStyling(element.btw, row, btwStyling);
        createCellWithCustomStyling(element.sail, row, sailStyling);
        createCell(element.stw, row);
        createCellWithCustomStyling(element.atwa, row, atwaStyling);
        createCellWithCustomStyling(element.abtw, row, abtwStyling);
        var manifest = chrome.runtime.getManifest();
        document.getElementById("version").innerHTML = manifest.version;
    });
	if( document.getElementById("pointsTable2") != null && document.getElementById("pointsTable2") != 'undefined' ) {
		document.getElementById("pointsTable2").innerHTML = document.getElementById("pointsTable").innerHTML;
	}
}

var displayLocal = function () {
    reinitializeDisplay();
    if (document.getElementById("localtime").checked) {
        chrome.storage.local.set({"localTime" : true});
        displayTable(true);
    } else {
        chrome.storage.local.set({"localTime" : false});
        displayTable(false);
    }
};

document.getElementById("localtime").addEventListener("change", displayLocal);
var exportGpx = function () {
    let xml = builder.create('gpx');
    xml.att('xmlns','http://www.topografix.com/GPX/1/1');
    xml.att('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance');
    xml.att('xsi:schemaLocation','http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd');
    xml.att('version','1.0');
    xml.att('creator','Route Zezo.org');

    let route = xml.ele('rte');
    route.ele('name', 'RZ ' + points[0].race);
    for (point of points) {
        if (point.latitude !== undefined && point.longitude !== undefined) {
            let routePoint = route.ele('rtept', {lat: point.latitude, lon: point.longitude});
            if ((point.timezone === "CET") || (point.timezone === "CEST")) {
                routePoint.ele('time', moment.tz(point.date + " " + point.time, "Europe/Paris").toISOString());
            } else if (point.timezone === "UTC") {
                routePoint.ele('time', moment.utc(point.date + " " + point.time).toISOString());
            }
            routePoint.ele('name', point.ttw);
        }
    }
    let xmlString = xml.end({pretty: true});
    let gpxOutput = document.getElementById("gpxOutput");
    gpxOutput.innerText = "";
    gpxOutput.innerText = xmlString;
};
document.getElementById("gpxExport").addEventListener("click", exportGpx);

chrome.storage.local.get("localTime", function (result) {
    if (result.localTime === true) {
        document.getElementById("localtime").checked = true;
        displayLocal();
    } else {
        document.getElementById("localtime").checked = false;
    }
});
reinitializeDisplay();
var points = background.points[background.currentTab];

function genIteNext(ttwCurr) {
    var ttwCurr = ttwCurr.match(/.*?([0-9]{1,3}):([0-9]{2})/);
    var ttwHours = parseInt(ttwCurr[1], 10);
    var ttwMinutes = parseInt(ttwCurr[2], 10);
    var ttwNext = [];
    if (ttwMinutes + 10 < 60) {
        ttwNext = "T+" + space(ttwHours) + ":" + zero(ttwMinutes + 10);
    } else {
        ttwNext = "T+" + space(ttwHours + 1) + ":" + zero(ttwMinutes - 50);
    }
    return ttwNext;
}

for (var i = 0; i < points.length; i++) {
    points[i].atwa = atwaCalc(twaList);
    points[i].abtw = abtwCalc(btwList);
    while (points[i].ttw !== ttwLast) {
        twaList.push(parseInt(twaLast,10));
        btwList.push(parseInt(btwLast,10));
        ttwLast = genIteNext(ttwLast);
    }
    twaLast = parseInt(points[i].twa, 10);
    btwLast = parseInt(points[i].btw, 10);
    if (twaList.length === 0) {
        twaList.push(twaLast);
        btwList.push(btwLast);
    } else if (twaList[0] * twaLast < 0) {
        twaList = [twaLast];
        btwList = [btwLast];
    } else {
        twaList.push(twaLast);
        btwList.push(btwLast);
    }
    ttwLast = genIteNext(ttwLast);
}

displayTable(false);
Le tableau final ressemble à ceci :
Image

Dans ce popup.js j'ai ce code pour calculer une moyenne des valeurs TWA et BTW du tableau avec prise en compte des itérations manquantes qui me donne respectivement les valeurs ATWA et ABTW.

Code : Tout sélectionner

var twaList = [];
var btwList = [];
var ttwLast = "T+ 0:00";
var twaLast = undefined;
var btwLast = undefined;

function atwaStyling(value, cell) {
    if (value >= 0) {
        cell.style.color = "green";
    } else {
        cell.style.color = "red";
    }
    if (value !== "-") {
        cell.innerHTML = Math.abs(value) + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}

function abtwStyling(value, cell) {
    cell.style.color = "blue";
    if (value !== "-") {
        cell.innerHTML = value + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}

function atwaCalc(twaList) {
    const
    twaData = twaList;
    Math.radians = function (degrees) {
        return degrees * Math.PI / 180;
    },
    Math.degrees = function (radians) {
        return radians * 180 / Math.PI;
    };

    let
    arX = [],
        arY = [],
        somX = 0,
        somY = 0,
        avgX = 0,
        avgY = 0,
        atwa = 0;

    for (const [i, angle] of twaData.entries()) {
        arX[i] = Math.cos(Math.radians(angle));
        arY[i] = Math.sin(Math.radians(angle));
    }

    for (const value of arX) {
        somX += value;
    }
    avgX = somX / arX.length;

    for (const value of arY) {
        somY += value;
    }
    avgY = somY / arY.length;

    atwa = Math.round(Math.degrees(Math.atan2(avgY, avgX)));
    if (isNaN (atwa)) {
        atwa = "-";
    }
    return atwa ;
}

function abtwCalc(btwList) {
    const
    btwData = btwList;
    Math.radians = function (degrees) {
        return degrees * Math.PI / 180;
    },
    Math.degrees = function (radians) {
        return radians * 180 / Math.PI;
    };

    let
    arX = [],
        arY = [],
        somX = 0,
        somY = 0,
        avgX = 0,
        avgY = 0,
        abtw = 0;

    for (const [i, angle] of btwData.entries()) {
        arX[i] = Math.cos(Math.radians(angle));
        arY[i] = Math.sin(Math.radians(angle));
    }

    for (const value of arX) {
        somX += value;
    }
    avgX = somX / arX.length;

    for (const value of arY) {
        somY += value;
    }
    avgY = somY / arY.length;

    abtw = Math.round(Math.degrees(Math.atan2(avgY, avgX)));
    if (isNaN (abtw)) {
        abtw = "-";
    } else if (abtw < 0) {
        abtw += 360;
    }
    return abtw;
}

function genIteNext(ttwCurr) {
    var ttwCurr = ttwCurr.match(/.*?([0-9]{1,3}):([0-9]{2})/);
    var ttwHours = parseInt(ttwCurr[1], 10);
    var ttwMinutes = parseInt(ttwCurr[2], 10);
    var ttwNext = [];
    if (ttwMinutes + 10 < 60) {
        ttwNext = "T+" + space(ttwHours) + ":" + zero(ttwMinutes + 10);
    } else {
        ttwNext = "T+" + space(ttwHours + 1) + ":" + zero(ttwMinutes - 50);
    }
    return ttwNext;
}

for (var i = 0; i < points.length; i++) {
    points[i].atwa = atwaCalc(twaList);
    points[i].abtw = abtwCalc(btwList);
    while (points[i].ttw !== ttwLast) {
        twaList.push(parseInt(twaLast,10));
        btwList.push(parseInt(btwLast,10));
        ttwLast = genIteNext(ttwLast);
    }
    twaLast = parseInt(points[i].twa, 10);
    btwLast = parseInt(points[i].btw, 10);
    if (twaList.length === 0) {
        twaList.push(twaLast);
        btwList.push(btwLast);
    } else if (twaList[0] * twaLast < 0) {
        twaList = [twaLast];
        btwList = [btwLast];
    } else {
        twaList.push(twaLast);
        btwList.push(btwLast);
    }
    ttwLast = genIteNext(ttwLast);
}
Tout ça fonctionne parfaitement, ce que je souhaite mettre en place :

Si je clique, sur la ligne en surbrillance par exemple dans le tableau, le calcul prendrait T+22:40 comme valeur twaLast et donc toutes les valeurs suivantes seraient modifiées puisque recalculées mais pas les valeurs précédentes et ça autant de fois que je le souhaite sur le tableau.

J'ai lu, sur le net, que "onclick" pourrait faire ce que je souhaite mais je galère a déterminer comment je dois m'y prendre.

Comment vous aborderiez la chose ?

Merci

Re: onclick sur <tr> tableau

Posté : 04 oct. 2018, 12:53
par webmaster
Bonjour,

C'est vraiment compliqué de se plonger dans tout le code

Quelle est la difficulté initiale ?
Avec :
<tr onclick="getInfo(this)">

On a l'objet tr en paramètre de getInfo et on doit pouvoir atteindre les valeurs de la ligne

Re: onclick sur <tr> tableau

Posté : 08 oct. 2018, 20:07
par GeGaX
Bonjour webmaster,
Désolé j'ai pas eu de notification comme quoi tu avais répondu (ou alors elle a foutu le camp dans les spams ...)
webmaster a écrit : Quelle est la difficulté initiale ?
Alors la première difficulté, c'est que je suis "débutant" avec quelques notions (je sais ça aide pas)
Mais je suis têtu donc je lâche pas l'affaire même si de nombreux soirs j'ai le cerveau en ébullition ...

J'vais essayer de dégrossir le code et la reflexion, pour aller à l'essentiel.

Toutes les instructions qui sont listés dans le tableau et qui proviennent du code source se font avec ce code

Code : Tout sélectionner

{
    let layer = document.getElementById("dot_layer");
    Array.prototype.slice.call(layer.getElementsByTagName("img")).forEach(function (element) {
        let event = element.getAttribute("onmouseover");
        if (event !== null) {
            let match = pattern.exec(event);
            const date = match[1],
                time = match[2],
                timezone = match[3],
                ttw = match[4],
                dtw = match[5],
                dtg = match[6],
                twd = match[7],
                tws = match[8],
                twa = match[9],
                btw = match[10],
                sail = match[11],
                stw = match[12];
            let race = document.title;
            points.push({
                race: race,
                date: date,
                time: time,
                timezone: timezone,
                ttw: ttw,
                dtw: dtw,
                dtg: dtg,
                twd: twd,
                tws: tws,
                twa: twa,
                btw: btw,
                sail: sail,
                stw: stw
            });
            pattern.lastIndex = 0;
        }
    });
    chrome.runtime.sendMessage(points);
}
Dans ces points, ceux qui m'intéressent sont ATWA et ABTW, ils sont calculés par les fonctions atwaCalc et abtwCalc

Code : Tout sélectionner

        function atwaCalc(twaList) {
            const twaData = twaList;
                Math.radians = function (degrees) {
                    return degrees * Math.PI / 180;
                },
                Math.degrees = function (radians) {
                    return radians * 180 / Math.PI;
                };
            let arX = [],
                arY = [],
                somX = 0,
                somY = 0,
                avgX = 0,
                avgY = 0,
                atwa = 0;
            for (const [i, angle] of twaData.entries()) {
                arX[i] = Math.cos(Math.radians(angle));
                arY[i] = Math.sin(Math.radians(angle));
            }
            for (const value of arX) {
                somX += value;
            }
            avgX = somX / arX.length;
            for (const value of arY) {
                somY += value;
            }
            avgY = somY / arY.length;
            atwa = Math.round(Math.degrees(Math.atan2(avgY, avgX)));
            if (isNaN(atwa)) {
                atwa = "-";
            }
            return atwa;
        }

        function abtwCalc(btwList) {
            const btwData = btwList;
                Math.radians = function (degrees) {
                    return degrees * Math.PI / 180;
                },
                Math.degrees = function (radians) {
                    return radians * 180 / Math.PI;
                };
            let arX = [],
                arY = [],
                somX = 0,
                somY = 0,
                avgX = 0,
                avgY = 0,
                abtw = 0;
            for (const [i, angle] of btwData.entries()) {
                arX[i] = Math.cos(Math.radians(angle));
                arY[i] = Math.sin(Math.radians(angle));
            }
            for (const value of arX) {
                somX += value;
            }
            avgX = somX / arX.length;
            for (const value of arY) {
                somY += value;
            }
            avgY = somY / arY.length;
            abtw = Math.round(Math.degrees(Math.atan2(avgY, avgX)));
            if (isNaN(abtw)) {
                abtw = "-";
            } else if (abtw < 0) {
                abtw += 360;
            }
            return abtw;
        }
J'ai une contrainte avec ces valeurs, elles ne me sont pas données toutes les 10 min donc pour un calcul plus précis j'ai une boucle qui fait le job et affiche les valeurs ATWA et ABTW si la ligne existe (sinon elles ne s'affiche pas mais sont prises en compte dans le calcul)

Code : Tout sélectionner

        function genIteNext(ttwCurr) {
            var ttwCurr = ttwCurr.match(/.*?([0-9]{1,3}):([0-9]{2})/),
                ttwHours = parseInt(ttwCurr[1], 10),
                ttwMinutes = parseInt(ttwCurr[2], 10),
                ttwNext = [];
            if (ttwMinutes + 10 < 60) {
                ttwNext = "T+" + space(ttwHours) + ":" + zero(ttwMinutes + 10);
            } else {
                ttwNext = "T+" + space(ttwHours + 1) + ":" + zero(ttwMinutes - 50);
            }
            return ttwNext;
        }

        for (var i = 0; i < points.length; i++) {
            points[i].atwa = atwaCalc(twaList);
            points[i].abtw = abtwCalc(btwList);
            while (points[i].ttw !== ttwLast) {
                twaList.push(parseInt(twaLast, 10));
                btwList.push(parseInt(btwLast, 10));
                ttwLast = genIteNext(ttwLast);
            }
            twaLast = parseInt(points[i].twa, 10);
            btwLast = parseInt(points[i].btw, 10);
            if (twaList.length === 0) {
                twaList.push(twaLast);
                btwList.push(btwLast);
            } else if (twaList[0] * twaLast < 0) {
                twaList = [twaLast];
                btwList = [btwLast];
            } else {
                twaList.push(twaLast);
                btwList.push(btwLast);
            }
            ttwLast = genIteNext(ttwLast);
        }
Tout ça fonctionne parfaitement.

Comme tu as pu le comprendre, je souhaite lorsque je clique sur une ligne du tableau, que les calculs des points ATWA et ABTW recommencent.
En gros je veux forcer la boucle à refaire le calcul à partir de cet endroit (la ligne ou j'viens de cliquer) MAIS sans que les lignes au dessus changent (sinon elles afficheraient toutes " - " pour ATWA et ABTW) et pour avoir quelque chose de visuel la ligne cliquée aurait un fond jaune par exemple.

Je comprends bien que le onclick doit agir sur la boucle mais je dois le mettre en oeuvre et la y'a plus personne je capte pas la logique ...