2022-08-02T16:34:22+02:00
2022-08-09T20:14:45+02:00
2022-08-09T20:30:29+02:00
M-anos
Egy korábbi kérdésben fejlesztett kódot (Dinamikus táblázat Javascripttel) tovább fejlesztenék, viszont egy kicsit eladtam.
Javascript segítségével egy táblázathoz új sorokat tudok hozzá adni. A sorok celláiba űrlap elemek kerülnek bele (beviteli mező, checkbox, legördülő lista).
Az űrlap elemeket két függvény segítségével oldanám meg (createFormElem és selectCreateElem). Ezeket a függvényeket hívom be oda, ahol vizsgálom a létrehozandó űrlap elemeket.
Amikor createFormElem függvény szépen vissza is adja az input típusokat a cellákba, viszont a selectCreateElem függvény sajnos nem adja vissza a cellákba a létrehozott legördülő listákat.
Mikor új sort adok hozzá a táblázathoz, és a selectCreateElem függvény lefut, akkor a következő hibaüzeneteket kapom:
Ha így szeretném hozzáadni a sor cellájához a generált legördülő listát cell.append(formSelectElem); akkor undefined értéket kapok a cellékban.
Ha pedig így szeretném a cellához hozzáadni a generált legördülő listát cell.appendChild(formSelectElem); akkor pedig "Uncaught TypeError: Node.appendChild: Argument 1 is not an object." hibaüzenetet kapom.
A fontos Javascript kódrészlet:
Javascript segítségével egy táblázathoz új sorokat tudok hozzá adni. A sorok celláiba űrlap elemek kerülnek bele (beviteli mező, checkbox, legördülő lista).
Az űrlap elemeket két függvény segítségével oldanám meg (createFormElem és selectCreateElem). Ezeket a függvényeket hívom be oda, ahol vizsgálom a létrehozandó űrlap elemeket.
if(emp.elementTyp == "text" || emp.elementTyp == "checkbox") {
const formInputElem = createFormElem(emp.elementTyp, emp.id, emp.name, emp.css, emp.placeholder);
cell.append(formInputElem);
}
if(emp.elementTyp == "select") {
const formSelectElem = selectCreateElem(emp.url, emp.id, emp.name);
cell.append(formSelectElem);
}
Mikor új sort adok hozzá a táblázathoz, és a selectCreateElem függvény lefut, akkor a következő hibaüzeneteket kapom:
Ha így szeretném hozzáadni a sor cellájához a generált legördülő listát cell.append(formSelectElem); akkor undefined értéket kapok a cellékban.
Ha pedig így szeretném a cellához hozzáadni a generált legördülő listát cell.appendChild(formSelectElem); akkor pedig "Uncaught TypeError: Node.appendChild: Argument 1 is not an object." hibaüzenetet kapom.
A fontos Javascript kódrészlet:
let formElements = [
{ elementTyp: 'text', id: 'oneID', name: 'oneName', css: 'form-control', placeholder: 'onePLC' },
{ elementTyp: 'select', url: 'https://api.frankfurter.app/latest', id: 'twoID', name: 'twoName' },
{ elementTyp: 'select', url: 'https://api.frankfurter.app/latest', id: 'threeID', name: 'threeName' },
{ elementTyp: 'text', id: 'FourID', name: 'fourName', css: 'form-control', placeholder: 'fourPLC' }
];
function addNewRow(tableIDS,formElements) {
let listTable = document.getElementById(tableIDS);
let row = listTable.tBodies[0].insertRow();
formElements.forEach(emp => {
let cell = row.insertCell();
if(emp.elementTyp == "text" || emp.elementTyp == "checkbox") {
const formInputElem = createFormElem(emp.elementTyp, emp.id, emp.name, emp.css, emp.placeholder);
cell.append(formInputElem);
}
if(emp.elementTyp == "select") {
const formSelectElem = selectCreateElem(emp.url, emp.id, emp.name);
cell.append(formSelectElem);
}
row.appendChild(cell);
});
let cell = row.insertCell();
let addBtn = document.createElement('input');
addBtn.setAttribute('type', 'button');
addBtn.setAttribute('value', '-');
addBtn.setAttribute('onClick', 'deleteRow("'+tableIDS+'",this)');
addBtn.setAttribute('class', 'btn btn-danger btn-sm');
cell.appendChild(addBtn);
row.appendChild(cell);
}
function createFormElem(type, id, name, css, placeholder) {
let inputText = document.createElement('input');
inputText.setAttribute('type', type);
inputText.setAttribute('id', id);
inputText.setAttribute('name', name);
inputText.setAttribute('class', css);
inputText.setAttribute('placeholder', placeholder);
return inputText;
}
function selectCreateElem(url, id, name) {
fetch(url)
.then((response) => response.json())
.then((data) => {
let selectEL = document.createElement("select");
selectEL.setAttribute('name', name);
selectEL.setAttribute('class', "form-select rounded-0");
selectEL.setAttribute('id', id);
let currencies = Object.entries(data.rates).forEach(([code, value]) => {
let optionEl = document.createElement("option");
optionEl.value = code;
optionEl.text = value;
selectEL.appendChild(optionEl);
});
return selectEL;
})
.catch((err) => console.log(err));
}
Mutasd a teljes hozzászólást!
Én így írnám át a selectCreateElem függvényt:
Ezt innentől async függvényből lehet meghívni "await selectCreateElem(...)" formában, vagy ha await nélkül hívod, akkor a kapott Promise objektumot kell a szokásos módon kezelni (hívsz rá then()-t, catch()-et, akármit).
De egyébként ha azt mondod hogy az await tiszta de a Promise nem, akkor valószínűleg az await-et sem érted teljesen. Az async és await Promise objektumok kényelmes gyártásáról és fogyasztásáról szól lényegében, csak a szintaxis elrejti előled magukat az objektumokat.
async function selectCreateElem(url, id, name) {
try {
const response = await fetch(url);
const data = await response.json();
const selectEL = document.createElement("select");
selectEL.setAttribute('name', name);
selectEL.setAttribute('class', "form-select rounded-0");
selectEL.setAttribute('id', id);
for (const [code, value] of Object.entries(data.rates)) {
const optionEl = document.createElement("option");
optionEl.value = code;
optionEl.text = value;
selectEL.appendChild(optionEl);
});
return selectEL;
} catch (err) {
console.log(err));
}
}
De egyébként ha azt mondod hogy az await tiszta de a Promise nem, akkor valószínűleg az await-et sem érted teljesen. Az async és await Promise objektumok kényelmes gyártásáról és fogyasztásáról szól lényegében, csak a szintaxis elrejti előled magukat az objektumokat.
Mutasd a teljes hozzászólást!
- Csaboka2válasza M-anos (16:34) részére
- 2022.08.02. 20:32
- permalink
Ha lenne egy forintom minden kérdező után, akik nem értették hogy az AJAX / fetch hívások aszinkron futnak le... akkor lenne vagy 50 forintom
Amikor hívsz egy fetch()-et, akkor a böngésző elindít egy HTTP kérést, de nem várja meg a választ. A különböző then(), catch() és egyéb callback-ek majd akkor futnak le, ha megérkezett a válasz (vagy soha, ha az oldalt előbb bezárják mint ahogy a válasz megérkezne). A callbackben már mindegy mit adsz vissza, a fetch()-et meghívó függvény addigra már rég visszatért, mégpedig undefined értékkel, mert hogy nem volt benne return utasítás.
Nézz utána az async/await témakörnek. Azon ugyan nem segítenek, hogy a HTTP válaszokat meg kell várni, de legalább a kódodat nem kell teleszórni egy rakás callback függvénnyel, amik a választ lekezelik.
Mondjuk az nem annyira egészséges, ha te DOM manipuláció közben küldesz HTTP kéréseket. A válasz megérkezéséig a felhasználó egy félkész DOM fát lát, amivel interakcióba is tud lépni. Barátságosabb lenne két fázisban: először elküldöd a szükséges kéréseket (közben a felhasználónak mutathatsz homokórát vagy pörgettyűt vagy ami éppen most divatos), aztán ha megvan minden adat, akkor egy menetben felfrissíted a DOM fát. Ráadásul a HTTP kérések futhatnak párhuzamosan, a Promise.all() függvény a barátod.Mutasd a teljes hozzászólást!- M-anosválasza Csaboka2 (20:32) részére
- 2022.08.03. 21:51
- permalink
Szia. Async/await az tiszta, ezt a függvényt meg tudom oldani, viszont a Promise az nekem még újdonság. Esetleg egy egyszerű példával el tudnád magyarázni, hogy is tudom a két dolgot egybe rakni, hogy szintaktikailag akkor helyes legyen? Tiszta sor, hogy a soronként megadandó űrlap elemeket, máshogy kell, hogy bejárjam (tehát a fetch-es lekéréseket külön kell kezelnem, hogy ne akkor generàodjanak le a lista elemek mikor új sort adok hozzá.).Mutasd a teljes hozzászólást!- Én így írnám át a selectCreateElem függvényt:
async function selectCreateElem(url, id, name) { try { const response = await fetch(url); const data = await response.json(); const selectEL = document.createElement("select"); selectEL.setAttribute('name', name); selectEL.setAttribute('class', "form-select rounded-0"); selectEL.setAttribute('id', id); for (const [code, value] of Object.entries(data.rates)) { const optionEl = document.createElement("option"); optionEl.value = code; optionEl.text = value; selectEL.appendChild(optionEl); }); return selectEL; } catch (err) { console.log(err)); } }
De egyébként ha azt mondod hogy az await tiszta de a Promise nem, akkor valószínűleg az await-et sem érted teljesen. Az async és await Promise objektumok kényelmes gyártásáról és fogyasztásáról szól lényegében, csak a szintaxis elrejti előled magukat az objektumokat.Mutasd a teljes hozzászólást! - M-anosválasza Csaboka2 (07:40) részére
- 2022.08.09. 14:29
- permalink
Módosítottam a kódomat, az általad megírt függvénnyel.
A probléma továbbra is fennáll ahol meg hívom a függvényt:
if(emp.elementTyp == "select") { const formSelectElem = selectCreateElem(emp.url, emp.id, emp.name); cell.appendChild(formSelectElem); } row.appendChild(cell); });
Viszont ha lecserélem az appendChild-et innerHTML-re - cell.innerHTML = formSelectElem; akkor a consolba kiírva visszatérnek az értékek (kép mellékleve).
Az érdekelne, hogy az appendChild esetén miért nem tér vissza az érték az innerHTML-el szemben.Mutasd a teljes hozzászólást!Csatolt állomány- prmoise.jpg29,14 KB
- Csaboka2válasza M-anos (14:29) részére
- 2022.08.09. 17:40
- permalink
Amikor azt írtam, hogy
Ezt innentől async függvényből lehet meghívni "await selectCreateElem(...)" formában, vagy ha await nélkül hívod, akkor a kapott Promise objektumot kell a szokásos módon kezelni (hívsz rá then()-t, catch()-et, akármit).
akkor nem arra gondoltam, hogy ne nyúlj semmihez a hívóban és minden jó lesz. Tényleg meg kéne értened a Promise témakört (ideértve az async és await működését), mert ha csak vaktában nyomkodsz dolgokat azzal nem fogsz boldogulni. Ha ez megvan, már azt sem lesz gond megérteni, hogy a konzol a Promise példány jelenlegi állapotát mutatja, nem azt az állapotot, amiben a log hívás idején volt.Mutasd a teljes hozzászólást!- M-anosválasza Csaboka2 (17:40) részére
- 2022.08.09. 20:14
- permalink
Igen, vannak még hiányosságok, nem is tagadom. Most tanulom a javascripttet. Eddig jquery-t használgattam, csak közben változott a helyzet, és nem szeretném azt használni, hanem inkább a modern javascript-tel szeretnék foglalkozni.Mutasd a teljes hozzászólást!
Címkék