I have a dynamic select that works as follows I explain:
There is an input where I add a value "X" and when I click the button called "generate select" it adds the number of values that I add to the input
When I select a select value, it loads another dynamic select where the missing numbers appear in ascending order and so on until the last number is selected, and each select that is generated shows a button called "create".
Option 1
What I need is that each time a dynamic select is generated, the button called "create" only remains in the last array.
import React, { useState } from "react";
let initialState = {
first: null,
arraySelect: []
};
const Test = () => {
const [arraySelect, setarraySelect] = useState(initialState.arraySelect);
const [numberIni, setnumberIni] = useState(initialState.first);
const [selectedNumbers, setSelectedNumbers] = useState([]);
const getArray = (value) => {
const numValue = parseInt(value, 10);
const arr = [];
for (let i = 0; i < numValue - 1; i++) {
arr.push(numValue - i - 1);
}
if (arr.length) {
return arr;
}
};
const setSelect = (value) => {
let isArray = getArray(value);
if (isArray) {
setarraySelect([...arraySelect, isArray]);
}
};
const handleChange = (index, value) => {
const tmpSelectedNumbers = [...selectedNumbers];
tmpSelectedNumbers[index] = value;
setSelectedNumbers(tmpSelectedNumbers);
};
const handleSubmit = (event) => {
event.preventDefault();
setnumberIni(event.target.numberIni.value - 1);
};
const resetForm = () => {
setnumberIni(null);
setarraySelect([]);
};
return (
<div>
<form onSubmit={handleSubmit}>
<input name="numberIni" type="number" />
<input type="submit" value="Generar select" />
</form>
{numberIni && (
<div>
<select
onChange={(e) => handleChange(0, e.target.value)}
name=""
id=""
>
<option value="seleccione">Seleccione</option>
{Array(parseInt(numberIni))
.fill(1)
.map((value, key) => {
return (
<option value={numberIni - key}>{numberIni - key}</option>
);
})}
</select>
<button
type="submit"
className="btn btn-success"
onClick={() => {
setSelect(selectedNumbers[0]);
}}
>
crear
</button>
{Array(parseInt(numberIni))
.fill(1)
.map((value, key2) => {
return (
<div>
{arraySelect[key2] && (
<>
<select
onChange={(e) => handleChange(key2 + 1, e.target.value)}
name=""
id=""
>
<option value="seleccione">Seleccione</option>
{arraySelect[key2].map((value, key3) => {
return (
<option value={arraySelect[key2][key3]}>
{arraySelect[key2][key3]}
</option>
);
})}
</select>
<button
type="submit"
className="btn btn-success"
onClick={() => {
setSelect(selectedNumbers[key2 + 1]);
}}
>
crear
</button>
</>
)}
</div>
);
})}
</div>
)}
{numberIni && (
<input onClick={() => resetForm()} type="button" value="Reiniciar" />
)}
</div>
);
};
export default Test;
EXHIBIT
Regarding the solution that they give me, it does not work for me in my project, I add the code exactly the same and it does not work for me, the current code of my project has the same code, the only thing that changes is that it has two inputs initially and it has an input field at the side of the select where they are created but it doesn't affect the code at all, I don't know why it doesn't work for me if I add exactly the code and the create buttons don't appear anywhere:
import React, { useState} from "react";
//input dinamico
import Row from "./Row2";
let initialState = {
first: null,
arraySelect: [],
arraySelect2: []
};
function test(props) {
//input dinamico
const [rows, setRows] = useState([]);
const [initialeRow, setInitialRow] = useState({ nombre: "" });
//SELECT2
const [selectedNumbers, setSelectedNumbers] = useState([]);
const handleOnChange = (index, value) => {
const copy = rows.map((e, i) => {
if (i === index) {
e.nombre = value;
}
return e;
});
setRows([...copy]);
};
//division
const [number, setNumber] = useState();
//Mostrar 4
const [modocuatro, setModoCuatro] = useState(null);
//Mostrar 5
const [modoboton, setModoBoton] = useState(null);
//modo cuatro
const handleClick_cuatro = (event) => {
event.preventDefault();
setModoCuatro(true);
global.multi = global.nuevo * global.select1;
console.log(global.multi + "resultado");
};
const handleInput_division = (event) => {
const { name, value } = event.target;
setNumber({ ...number, [name]: value });
};
const handleInput_division2 = (event) => {
const { name, value } = event.target;
setSelect(value)
setNumber({ ...number, [name]: value });
setInitialRow({ nombre: value * 1 + 1});
};
const [arraySelect, setarraySelect] = useState(initialState.arraySelect);
const [arraySelect2, setarraySelect2] = useState(initialState.arraySelect2);
const [numberIni, setnumberIni] = useState(initialState.first);
const [numberIni2, setnumberIni2] = useState(initialState.first);
const getArray = (value) => {
let arr = [];
{
let reco = Math.round(numberIni - parseInt(value));
console.log(reco + "mi");
if (parseInt(value) == numberIni) {
return false;
}
Array(reco)
.fill(1)
.map((value2, key) => {
arr.push(parseInt(value) + parseInt(key + 1));
});
}
return arr;
};
const setSelect = (value) => {
//debugger;
let isArray = getArray(value);
if (isArray) {
setarraySelect([...arraySelect, isArray]);
setModoBoton(true);
}
if (isArray) {
setInitialRow({ nombre: value});
setRows([...rows, { nombre: value}]);
}
};
//segundo array
const getArray2 = (value) => {
const numValue2 = parseInt(value, 10);
const arr2 = [];
for (let i = 0; i < numValue2 - 1; i++) {
arr2.push(numValue2 - i - 1);
}
if (arr2.length) {
return arr2;
}
};
//segundo select
const setSelect_select2 = (value) => {
let mi=global.division2020;
let isArray2 = getArray2(value);
if (isArray2) {
setarraySelect2([...arraySelect2, isArray2]);
setInitialRow({ nombre: initialeRow.nombre * 1 + 1 }) ;
setRows([...rows, initialeRow]);
}
};
//SEGUNDO SELECT
const handleChange = (index, value) => {
const tmpSelectedNumbers = [...selectedNumbers];
tmpSelectedNumbers[index] = value;
setSelectedNumbers(tmpSelectedNumbers);
};
const handleSubmit = (event) => {
event.preventDefault();
setnumberIni(event.target.numberIni.value);
setnumberIni2(event.target.numberIni2.value - 1);
};
const resetFormtodo = () => {
setnumberIni(null);
setnumberIni2(null);
setRows([]);
setarraySelect([]);
setarraySelect2([]);
};
return (
<div>
<form onSubmit={handleSubmit}>
<div class="row">
<div class="col-sm-3">
<h6>INGRESA UN PRIMER VALOR "GRUPOS"</h6>
<div class="input-group ">
<select
name="numberIni2"
class="form-control"
onChange={ handleInput_division }
>
<option value="0" selected>Seleccione</option>
<option value="10"> 10 </option>
<option value="20">20</option>
</select>
<br />
</div>
</div>
<div class="col-sm-3">
<h6>INGRESA UN SEGUNDO VALOR</h6>
<div class="input-group ">
<input
type="number"
name="numberIni"
placeholder="0"
class="form-control"
/>
<br />
<button type="submit" className="btn btn-primary">
GENERAR
</button>
</div>
</div>
</div>
</form>
<br />
<div>
<hr/>
</div>
<br /> <br />
<div class="row">
<div class="col-sm-12">
{numberIni && (
<div>
<h6>Criterio Para Equipos Clasificados a la Siguiente Fase</h6>
<label>
<font size="2">
1° Clasificados Por Grupo <br />
Clasificarán a Siguiente Fases Los Primeros : {" "}
</font>
</label>
<select
onChange={handleInput_division2}
name="numberIni3"
>
<option value="seleccione">Seleccione</option>
{Array(parseInt(numberIni))
.fill(1)
.map((value, key) => {
return <option value={key + 1}>{key + 1} Equipos</option>;
})}
</select>
<label>
<font size="2"> Equipos De Cada Grupo </font>{" "}
</label>
<label>
<font size="2">
{" "}
{" "}
{modoboton ? (
<button
className="btn btn-primary"
onClick={handleClick_cuatro}
>
Generar select
</button>
) : (
<></>
)}
{" "}
</font>{" "}
</label>
<hr />
{modocuatro ? (
<div class="col-sm-10" style={{ top: "-20px" }}>
{Array(parseInt(numberIni2))
.fill(1)
.map((value, key2) => {
return (
<div>
{arraySelect[key2] && (
<>
<label>
<font size="2">
<label>
<font size="2">
{" "}
{" "}
<div class="row">
<div class="col-sm-9">
<h6>Segundos Clasificados Por Grupo</h6>
<label><font size="2">Clasificarán a Siguiente Fases Los de Mejor Promedio :
<select
onChange={(e) => handleChange(0, e.target.value)
}
name=""
id=""
>
<option value="seleccione">Seleccione</option>
{Array(parseInt(numberIni2))
.fill(1)
.map((value, key) => {
return (
<option value={numberIni2 - key}>{numberIni2 - key} Equipos</option>
);
})}
</select> {console.log(arraySelect)} Ubicados en la
{arraySelect.length === 0 && (
<div className="col-sm-2" style={{top:"-27px", right:"-135%"}}>
<button
type="submit"
className="btn btn-primary"
onClick={() => {
setSelect_select2(selectedNumbers[0]);
}}
>
crear
</button>
</div>
)}
</font> </label>
{Array(parseInt(numberIni2))
.fill(1)
.map((value, key2) => {
return (
<div>
{arraySelect2[key2] && (
<>
<h6>Segundos Clasificados Por Grupo</h6>
<label><font size="2">Clasificarán a Siguiente Fases Los de Mejor Promedio :
<select
onChange={(e) => handleChange(key2 + 1, e.target.value)}
name=""
id=""
>
<option value="seleccione">Seleccione</option>
{arraySelect2[key2].map((value, key3) => {
return (
<option value={arraySelect2[key2][key3]}>
{arraySelect2[key2][key3]} Equipos
</option>
);
})}
</select> Ubicados en la
{key2 === arraySelect.length - 1 && (
<div className="col-sm-2" style={{top:"-27px", right:"-135%"}}>
<button
type="submit"
className="btn btn-primary"
onClick={() => {
setSelect_select2(selectedNumbers[key2 + 1]);
}}
>
crear
</button>
</div>
)}
</font> </label>
</>
)}
</div>
);
})}
</div>
<div className="col-sm-2" style={{top:"-40px"}}>
{rows.map((e, index) => (
<Row
nombre={e.nombre}
index={index}
onChange={(index, value) =>
handleOnChange(index, value)
}
key={index}
/>
))}
</div>
</div>
{" "}
</font>{" "}
</label>
</font>{" "}
</label>
</>
)}
</div>
);
})}
</div>
) : (
<></>
)}
{numberIni2 && (
<input onClick={() => resetFormtodo()} type="button" value="Reiniciar" />
)}
</div>
)}
</div>
</div>
</div>
);
}
export default test;
//row2.js
const Row = (props) => {
const { onChange, onRemove, nombre, index } = props;
console.log(props);
return (
<div>
<h6> </h6>
<br/>
<br/>
<br/>
<input
disabled
value={nombre * 1 + 1 + " Posición"}
onChange={(e) => onChange(index, e.target.value)}
placeholder="Decrementar"
/>
</div>
);
};
export default Row;
This is the way to do it that I propose. It is the same but adapted to different cases.
1st CASE
You have to condition whether the two "create" buttons will be shown or not.
To condition the first one, we must verify that
arraySelect
it does not have any other array inside it, making sure that its property.length
is equal to zero:Y para condicionar el segundo botón verificamos que el valor de
key2
, que identificará a cada botón, sea igual al.length
dearraySelect
menos uno. Ya que ese será el último botón:Con esos cambios, todo el código quedaría así:
2° CASO
Hay que hacer exactamente lo mismo, pero adaptándolo un poco.
El primer botón lo condicionamos evaluando el array rows, ya que en este caso es la variable que contiene los objetos que serán renderizados.
Y esta vez la condición será que
rows
sea igual a 1, debido a que ya se está creando un objeto que se guarda previamente dentro de ese array:Then in the second button we use the array again
rows
and we also make another change since in this case there will always be one more object in the array. So then we have to validate that thekey2
is equal to.length
the array minus 2 :Finally, considering that the Row2.js file would have no changes, the rest of the code would look like this: