¿como modificar un array declarada en un archvio js desde un onclick?

Iniciado por Drakaris, 13 Diciembre 2020, 11:54 AM

0 Miembros y 1 Visitante están viendo este tema.

Drakaris

Buenas, estoy haciendo un registro de jugadores, de manera dinamica, que cuando rellenas un formulario, se guarda en un array los datos y posteriormente se añade a una lista HTML un item con el jugador.
img: https://drive.google.com/file/d/1hOvYRr46p17064tz_1pf9hkF8Lw764Rr/view?usp=sharing

Cuando pasas por el item del jugador, puedes eliminar el usuario, lo hice con un evento onclick, pero mi problema esta que el onclick debe acceder al array definida en el archivo js para poder eliminar el subarray del jugador.

IMPORTANTE: los subarrays se añaden dinamicamente durante el envio del formulario.
file js:
Código (js) [Seleccionar]

var players=[
    ["player1"],
    ["player2"],
];


HTML:
Código (html) [Seleccionar]

<html>
    <head>
         <script src='file.js'></script>
    </head>
                        <i class="fas fa-times-circle close-player" onclick="
                            players.splice(this.parentNode.id,1);
                            this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
                            console.log(players);
                        "></i>
</html>


El problema esta en que me sale como si players no estuviera definido.
CitarUncaught ReferenceError: players is not defined

Como lo puedo resolver con onclick?

Gracias
Lo increible, no es lo que ves, sino como es

MinusFour

players tendría que ser una variable global. ¿Ese es el contenido tal cual de tu file.js?

#!drvy

No hagas eso. Nunca más. Te lo prohíbo xD

El javascript inline esta bien para meter cosas pequeñas y tal... pero no pare meter 500 lineas de JS xD


Dicho esto, realmente no veo porque te tiene que fallar. Aparte de la gorseria esa y que el <i> lo metes fuera del <body>...

Pero vamos, tu código lo podrías estructurar mucho mejor..

Código (javascript) [Seleccionar]
var players = [
   ["player1"],
   ["player2"],
   ["player3"],
   ["player4"],
   ["player5"],
];


function removePlayer(node) {
   let parentNode     = node.parentNode;
   let grandNode      = parentNode.parentNode;
   let grandGrandNode = grandNode.parentNode;

   players.splice(parentNode.id, 1);
   grandGrandNode.remove(grandNode);

   console.log(players);
};

document.querySelector('.close-player').addEventListener('click', function(event) {
   removePlayer(event.target);
});


Código (html5) [Seleccionar]
<i class="fas fa-times-circle close-player"></i>


Así lo tienes todo en el mismo script y el html te queda bien limpio...


O incluso podrias estructurar mejor el HTML y facilitar las cosas aun más.

Código (html5) [Seleccionar]
<div>                         <!-- grandGrandNode -->
    <div class="playerItem">  <!-- grandNode -->
        <div data-player="3"> <!-- parentNode -->
            <i class="fas fa-times-circle close-player">t</i>
        </div>
    </div>
</div>


Código (javascript) [Seleccionar]
function removePlayer(node) {
   let playerID = parseInt(node.parentNode.dataset.player);

   players.splice(playerID, 1);
   node.closest('.playerItem').remove();

   console.log(players);
};

document.querySelector('.close-player').addEventListener('click', function(event) {
   removePlayer(event.target);
});



Saludos

@XSStringManolo

En vez de declarar el array en el archivo yo crearía un módulo ES6 que lo retorne.

players.mjs
Código (javascript) [Seleccionar]
let getPlayers = () => [
    ["player1"],
    ["player2"],
];

export default getPlayers;



index.html
Código (html4strict) [Seleccionar]
<html>
<head>
<meta charset="utf-8">
<script type="module">
import getPlayers from "./players.mjs";

let players = getPlayers();
console.log(players);
// aquí puedes meter más código para trabajar con players.
</script>
</head>
</html>



No suele ser buena idea trabajar con inline javascript (onClick) cuando es posible utilizarlo desde un script.
Puedes usar
Código (javascript) [Seleccionar]
let i = document.createElement("i");
i.className = "bla bla";
i.addEventListener("click", function(evento) {
  // evento.target ....
  // evento.target.parentElement
  // evento.target.parentNode
  // ...
});
body.appendChild(i);

...

Drakaris

Gracias chicos, entiendo que el inline no se recomienda, pero antes no veía otra forma de hacerlo. Mi archivo js es mucho más grande y complejo, porque la lista de jugadores es dinamico, declaro en un principio el array sin elementos y mientras añado los jugadores añado subarrays al array players.

Lo que he hecho es seleccionar todos los elementos con la clase close-player y con un bucle for hago los listening (no se me ocurrio....)

        list_ids=document.getElementsByClassName("close-player");
        for(x=0;x<=list_ids.length-1;x++){
            document.getElementById(list_ids[x].id).addEventListener("click",function(){
                players.splice(this.id,1);
                this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
                console.log(players);
            });           
        }


P.D: El document.querySelector() no puede utilizarlo porque me funcionaba la primera vez que añado un jugador pero no los posteriores.
Lo increible, no es lo que ves, sino como es

@XSStringManolo

Probaste usando Ajax, ya sea XHR o fetch en lugar de modificar un archivo? Creo que es la manera más adecuada de hacer lo que quieres. Incluso una API REST podría ser lo más adecuado.