Autor Zpráva
pmasarik
Profil
Zdravím

Rád by som sa spítal či sa dá urobiť, niečo také že budem mat zobrazený input a pod ním link na ktorý ked kliknem sa zobrazí další prázdny input pre zadanie novej hodnoty.

Tie inputy by sa mohly pridávať kolko budem potrebovat, lebo popredu neviem kolko ich bude treba.
Našiel som len také riešenie, že sú tie inputy pripravené a skryté, ale to nie je ideálne riešenie.
Nemá niekto nejaký link s ukážkou ako na to???
pmasarik
Profil
Tak a už som našiel riešenie, ak by to ešte niekoho zaujímalo tak tu je zdroj.

http://javascript.internet.com/forms/adding-html-controls.html

Ale ak to nie je elegantné riešenie a niekto pozná lepšie budem rád ak mi dáte vedieť.
venca12
Profil
Ahoj, myslím si, že docela dobrý je i řešení pomocí objektu. Alespoň se celý web netváří, jako shluk nějakých náhodných funkcí, ale na každou funkci máš svůj objekt, který vykonává určitou funkci. Tedy tady je mé řešení:

Nejdříve nějaký externí soubor, například inputovnik.js. Je v něm uložený objekt, který má tři metody. fill, která načte seznam již existujících inputů v daném elementu (třeba divu) a uloží je do pole, abychom s nimi mohli později v objektu pracovat (přidávat/mazat). Potom add, vytvoří nový input a remove smaže input.
// Pridej odeber input


function Tinputovnik(linkId)
{


this.linkId = linkId; // idecko linkovaneho elementu do ktereho budu sazet inputy

this.inputArr = new Array(); // seznam inputu v elementu linkId

this.constructor = function()
{

}


// pridani inputu do toho elementu (vytvorim pomoci create element)
this.add = function()
{
var elem = document.getElementById(this.linkId);

var novy = document.createElement('input');
elem.appendChild(novy);

// pridam elemnt do seznamu elementu
this.inputArr.push(novy);
}

// ondstraneni posledniho inputu z elementu ()
this.remove = function()
{
var elem = document.getElementById(this.linkId);
var last = this.inputArr.pop();

if(last)elem.removeChild(last);
}

// naplni pole inputu jiz existujicimi inputy
this.fill = function()
{
var elem = document.getElementById(this.linkId);

if(elem)
for(var i=0;i<elem.getElementsByTagName('input').length;i++)
{
this.inputArr.push(elem.getElementsByTagName('input')[i]);
}
}

// volam konstruktor
this.constructor();

}

Teď už stačí do dokumentu vložit nějaký ten div do kterého se budou nové inputy přihazovat, vytvořit objekt inputovniku a volat jednotlivé metody v odkazech, pro přidání, nebo odebrání.
<div id="semChciInputy">


<input />
<input />

</div>

<script type="text/javascript" src="inputovnik.js"></script>
<script type="text/javascript">

var inputovnik = new Tinputovnik('semChciInputy');

window.onload=function(){inputovnik.fill();}

</script>


<a href="javascript:inputovnik.add();">pridej</a>
<a href="javascript:inputovnik.remove();">uber</a>


Btw. tohle je jenom kostra řešení, obsahuje jenom základní funkce a metody a jejich výstup není příliš košer. Doporučuji upravit metodu add a sice v ní se vytváří nový element input, ale nepřiřazuji mu žádný typ (defaultně je text, ale přeci jen by tam měl být přiřazený), nepřiřazuji mu žádnou třídu stylů, žádnou value, žádné id,....atp. další řešení je myslím si už na snadě.
pmasarik
Profil
RE: venca12
Dík za snahu, ale ja som v JS ako ryba na suchu, takže som to vôbec nepochopil :-)

Ale mám problém s tým scriptom čo som našiel a potrebujem poradiť.
Trochu som si upravil tú funkciu na vloženie tých inputov a používam to takto na input type="file" a jeden textarea.
Presnejšie problém je v tom že input type="file" nemá hodnotu value a pri pridaní nového inputu stratí tú čo bola vybraná. Nedá sa to nejako ošetriť?
Podla tohoto http://diskuse.jakpsatweb.cz/index.php?action=vthread&topic=20188&foru m=4&page=-1 asi nie, ale možno niekto pozná riešenie.



function createInput(id,value) {
return "<tr><th><label for='obrazok "+ id +"'>Obrázok:</label></th><td><input id='obrazok "+ id +"' type='file' name='obrazok[]' onChange='javascript:saveValue("+ id +",this.value)' /></td></tr><tr><th><label for='popis "+ id +"'>Popis k obrázku:</label></th><td><textarea name='popis[]' id='popis "+ id +"' rows='2' cols='70' onChange='javascript:saveValue("+ id +",this.value)'>"+ value +"</textarea></td></tr>";
}
venca12
Profil
pmasarik ::: To na tom nejsi zase tak špatně. Ovšem pouze v případě, že jsi suchozemská ryba :).

Problém na který odkazuješ do diskuse je trochu jiný než ten tvůj. Tam měl borec problém s tím, že po odeslání formuláře a jeho kontrole php skriptem se vyprázdní políčko input file. Jeho problém by se dal vyřešit kontrolou hodnot formuláře ještě před odesláním pomocí javascriptu.

Tvůj problém je takový, že funkce display(), kterou jsi použil z toho řešení na netu, pracuje tak, že při každém přidání, anebo odebrání prvku, přemaže kompletně celý formulář a vykreslí ho znovu. Tím pádem přijdeš i o všechna již vyplněná data. Ty to potřebuješ udělat tak, aby si nepřekresloval při každém přidání všechny prvky, ale jenom ten, se kterým momentálně pracuješ.

No a přesně tak jak to ty potřebuješ pracuje mé řešení :-).

Stručný popis: I když je Tinputovnik pojmenovany, jako function nenech se zmást tím klíčovým slovem function, protož je to třída. Všechny metody té třídy jsou potom deklarovány v ní, jako this.nazev = function() {}. Vlastnosti té třídy jsou deklarovány stejně, jenom s tim rozdílem, že jim nepřiřazuješ funkci, ale nějakou hodnotu. Tzn. this.property='ahoj'; a to je kromě prototypů vlastně celé OOP v javascriptu, alespoň myslím ;-).

Máme tedy třídu, z ní si uděláme objekt pomocí var inputovnik = new Tinputovnik('semChciInputy'); a voláme jeho metody. Metodu pro přidání záznamu add, pro odstranění remove pro načtení již existujících záznamů fill a pod.

Ty, pro to, aby ti to fungovalo podle tvých představ potřebuješ udělat dvě věci.

První je úprava metody add, tak aby ti přidávala to co chceš ty a ne jenom samotný oholený input. Předpokládám, že chceš přidávat řádek tabulky, tzn. úprava bude zhruba následující.
 this.add = function()

{
// tohle je element tabulky
var elem = document.getElementById(this.linkId);

// vytvorim radek tabulky tr
var tr = document.createElement('tr');
// vytvorim bunku tabulky th
var th = document.createElement('th');
// ted prilepim bunku tabulky th do radku tabulky tr
tr.appendChild(th);

// vytvorim input
var input = document.createElement('input');
// reknu inputu, ze ma byt file
input.typ='file';
// ted prilepim input do bunky tabulky th
th.appendChild(input);


// a nakonec vlepim radek do elementu tabulky
elem.appendChild(tr);



// pridam elemnt do seznamu elementu
this.inputArr.push(tr);
}


A druhá úprava je ta, že svojí tabulce, kam chceš přihazovat ty inputy nastavíš nějaké id např.: id="tabulka" a stejně id zadáš do objektu inputovnik, tzn. var inputovnik = new Tinputovnik('tabulka');.

Kdyby jsi si s tím nevěděl rady, tak napiš.
pmasarik
Profil
Uff dík za snahu.
Takže takto. Ten script čo som použil s tej stránky mi nejako nefunguje v IE tak som sa snažil pochopit ten tvoj script. Ale...
Nepochopil som moc dobre ako urobím všetky tie somariny čo potrebujem pri inpute aby fungoval, id name atd... navyše ja potrebujem porobiť aj textareu nie len inputy.

Ja jednoducho povedané s toho potrebujem toto:

<tr>
<th><label for='obrazokID'>Obrázok:</label></th>
<td><input id='obrazokID' type='file' name='obrazok[]' /></td>
</tr>
<tr>
<th><label for='popisID'>Popis k obrázku:</label></th>
<td><textarea name='popis[]' id='popisID' rows='2' cols='70'></textarea></td>
</tr>


Ten script s tým novým add som dal na http://www.pmasarik.info/ukazky/tinputovnik.html ale nejako to nerobí ani input s type="file".
EDIT -- už som to opravil input.type = "file"; // tu bola chyba

Ten script s tej stránky som rozchodil vo firefoxe tak ako potrebujem http://www.pmasarik.info/ukazky/newinput.php ale nefunguje mi to v IE a to je zle.
pmasarik
Profil
Už som zistil aj ako dat tomu inputu name

input.setAttribute("name", "list[]");

Ale stále som pako s toho ako urobím ten moj požadovaný kod aj s tym textarea.
Ak môžeš tak pomôž. Dik vopred.
venca12
Profil
Byl tam jeden problém a je tam jedno omezení. Skript

Problém byl v internet exploreru, kterému dělá přiřazení nově vytvořených elementů tr na tabulku. Tzn nefungovalo appendChild, vyřešeno tak, že se do tabulky vložilo tbody s jistým id a nově vytvořené elementy se vkládají do něj.

Omezení je v tom, že ty chceš dva řádky tabulky, ale přitom řádek je stěžejní element, na kterém to celé staví. Tzn. jeden tr, jeden záznam v poli, jedno zrušení atp. Pro dva by bylo řešení mnohem komplikovanější. Teď je všechno na jednom tabulkovém řádku, pokud jich budeš chtít víc, musíš si je přidat sám a skript upravit. Btw. myslím, že další úpravy skriptu si už odvodíš od již existujícího kódu.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html><head>


<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="PSPad editor, www.pspad.com"><title></title>

<script type="text/javascript">
// Pridej odeber input
function Tinputovnik(linkId)
{
this.linkId = linkId; // idecko linkovaneho elementu do ktereho budu sazet inputy
this.inputArr = new Array(); // seznam inputu v elementu linkId
this.constructor = function()
{
}

this.add = function()
{
var elem = document.getElementById(this.linkId);
// radek tabulky
var tr = document.createElement('tr');
// prvni bunka tabulky
var td1 = document.createElement('td');

var label = document.createElement('label');
label.htmlFor = 'input'+this.inputArr.length;
label.innerHTML = 'Obrazok:';
td1.appendChild(label);

// druha bunka tabulky
var td2 = document.createElement('td');

var input = document.createElement('input');
input.type = 'file';
input.id = 'input'+this.inputArr.length;
input.name = 'obrazok[]';
td2.appendChild(input);

// treti bunka tabulky
var td3 = document.createElement('td');

var label = document.createElement('label');
label.htmlFor = 'popis'+this.inputArr.length;
label.innerHTML = 'Popis k obrázku:';
td3.appendChild(label);

// ctvrta bunka tabulky
var td4 = document.createElement('td');

var textarea = document.createElement('textarea');
textarea.rows = '2';
textarea.cols = '70';
textarea.id = 'popis'+this.inputArr.length;
textarea.name = 'popis[]';
td4.appendChild(textarea);


tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tr.appendChild(td4);
elem.appendChild(tr);

this.inputArr.push(tr);
}
// ondstraneni posledniho inputu z elementu ()
this.remove = function()
{
var elem = document.getElementById(this.linkId);
var last = this.inputArr.pop();
if(last)elem.removeChild(last);
}
// naplni pole inputu jiz existujicimi inputy
this.fill = function()
{
var elem = document.getElementById(this.linkId);
if(elem)
for(var i=0;i<elem.getElementsByTagName('tr').length;i++)
{
this.inputArr.push(elem.getElementsByTagName('tr')[i]);
}
}
// volam konstruktor
this.constructor();
}
</script></head><body>
<script type="text/javascript">

var inputovnik = new Tinputovnik('sem');

window.onload=function(){inputovnik.fill();}

</script>

<form enctype="multipart/form-data" action="#" method="post">
<fieldset>
<legend>form</legend>

<table id="s">

<tbody id="sem">
<tr><th><input></th></tr>
<tr><th><input></th></tr>

</tbody>

</table>

<input name="edit" value="huhu" type="submit">
</fieldset>
</form>


<a href="javascript:inputovnik.add();">pridej</a>
<a href="javascript:inputovnik.remove();">uber</a>



</body></html>
pmasarik
Profil
Super chlape máš to u mňa. Keby si niekedy niečo potreboval tak napíš.
Ja som si to ešte upravil podla mojich potrieb a funguje to aj v IE.



this.add = function()
{
var elem = document.getElementById(this.linkId);
// tbody
var tbody = document.createElement('tbody');

// 1 radek tabulky
var tr1 = document.createElement('tr');

// prvni th + label
var th1 = document.createElement('th');
var label = document.createElement('label');
label.htmlFor = 'input'+this.inputArr.length;
label.innerHTML = 'Obrazok:';
th1.appendChild(label);

// prvni td + input
var td1 = document.createElement('td');
var input = document.createElement('input');
input.type = 'file';
input.id = 'input'+this.inputArr.length;
input.name = 'obrazok[]';
td1.appendChild(input);

tr1.appendChild(th1);
tr1.appendChild(td1);

// 2 radek tabulky
var tr2 = document.createElement('tr');

// druhy th + label
var th2 = document.createElement('th');
var label = document.createElement('label');
label.htmlFor = 'popis'+this.inputArr.length;
label.innerHTML = 'Popis k obrázku:';
th2.appendChild(label);

// druhe td + textarea
var td2 = document.createElement('td');
var textarea = document.createElement('textarea');
textarea.rows = '2';
textarea.cols = '70';
textarea.id = 'popis'+this.inputArr.length;
textarea.name = 'popis[]';
td2.appendChild(textarea);

tr2.appendChild(th2);
tr2.appendChild(td2);

tbody.appendChild(tr1);
tbody.appendChild(tr2);

elem.appendChild(tbody);
this.inputArr.push(tbody);
}
pmasarik
Profil
Nazdar venca12
Mám problém.

Na stránke kde chcem pridávat tie inputy používam aj [url=http://www.dgx.cz/trine/item/color-mixer-aneb-michatko
]http://www.dgx.cz/trine/item/color-mixer-aneb-michatko
[/url]
s nastvením ako pri tomto deme [url=http://www.dgx.cz/tools/colormixer/popup.php
]http://www.dgx.cz/tools/colormixer/popup.php
[/url]

Problém je ten že to miešatko prestalo fungovať, ked som tam dal ten inputovnik.
A prestalo fungovat aj remove inputov - EDIT remove som už vyriešil chyba bola u mna
Nevieš čím by to mohlo byť?

A ešte sa ťa chcem spítať na funkciu fill.
Teraz je tam getElementsByTagName('tr'), nemalo by tam byť vždy to čo určím vo funkcii add ako rodičivský prvok???
pmasarik
Profil
Už som vyriešil po svojom aj problem s nefungujucim miešatkom.
Pri vkladaní do HTML musí byť najskôr vložený script inputovníku až potom js pre miešatko :-)
Prečo je tomu tak neviem ale funguje to a to mi stačí...

Už neviem len načo je vo funkcii fill to getElementsByTagName('tr')
Nech tam dám čokolvek tak to stále funguje.
peta
Profil *
pmasarik
Se mi velice libi ta konstrukce scriptu :) V tom, aby se cert vyznal, tak inteligentne je to napsane :)

"Už neviem len načo je vo funkcii fill to getElementsByTagName('tr')"
Strelim od boku Ses si tim jistej, ze to funguje i v Opere? V Opere jsem mel s JS straslive problemy...

k tem upravam, pro zajimavost toto:
this.fill = function()
{
var elem = document.getElementById(this.linkId);
if(elem)
for(var i=0;i<elem.getElementsByTagName('tr').length;i++)

{
this.inputArr.push(elem.getElementsByTagName('tr')[i]);
}
}
->
function objGet(x)
{return document.getElementById(x);}

this.fill = function()
{
var e,i;
e = objGet(this.linkId);
if (Boolean(e))
{
e = e.getElementsByTagName("TR");
for (i=0;i<e.length;i++)
{
this.inputArr.push(e[i]);
}
}
}
pmasarik
Profil
RE:peta

Teraz neviem ako si to myslel, či je ten script uplne na p**u alebo je to OK.
Tomu tvojmu scriptu nerozumiem lebo js neovladam, takže tiež neviem čo to je.
A čuduj sa svete funguje to bez problemov v IE, FF aj Opere takže pre mna je venca12 javascriptový boss a jediný ktorý bol ochotný zatial poradiť :-)
peta
Profil *
pmasarik
Aha, tak kdyz JS nerozumis, asi nerozumis asi ani programovani, pak je kazda rada zbytecna. Na bosovani se ti muzu...

Mne slo o to, jakym zpusobem je to napsany a zda se v tom da vyznat.
Ted nevim, zda ma ceny ti to vysvetlovat, kdyz ses ten typek poradte mi, ja nic neumim a ani priklady na jakpsatweb jsem si neracil vyzkouset. Typicka lenost.
- misto document.getElementById(neco) jsem pouzil jinou funkci, ktera vraci totez "function objGet(x)" , vyhodou je, ze ji lze doplnit o dalsi funkce pro dalsi prohlizece, protoze getElementById() je bohuzel funkcni jen v lepsich prohlizecich.
Navic pro dalsi pouziti jsem usetril misto pri psani, kdyz 100x napisi
objGet(this.linkId)
nebo
document.getElementById(this.linkId)
ktere je 2x tak delsi a prave pro ty jine prohlizece bys to pak musel 100x prepisovat
- TR se pise velkym, protoze jen lepsi prohlizece umi pracovat s malymi pismeny. Mam pocit, ze stara opera prevadi vsechny tagy na VELKE pismena a tudiz vysledkem te funkce by bylo -1
- proc 2x opakovat elem.getElementsByTagName('tr')[i] ? Se to priradi do promenne a dal uz pracujes jen s ni. 2x volat vyhledavaci funkci mi prijde jako zbytecna zatez.
- proc pojmenovavat nedulezitou promennou uvnitr funkce jako elem, kdyz staci e? A hned se zvysi prehled fukce pri prohlizeni v textovem editoru. A pri te prilezitosti bych VAR z FOR() cyklu pro I presunul zvlast s "i,e"
S timto spoustu lidi nesouhlasi. Treba tvuj boss. Kazdy mame svuj styl, takze ja to pisi treba takto.

Mimochodem, nemas osetrene, co se ma stat v pripade, ze je TR prazdne?
A nejsem si ted uplne jistej, jestl ito plati i u INPUT, ale u SELECT treba v tech horsich prohlizecich se musi pouzit nejaka jina funkce nez
document.createElement('input'); .
IE5
var doc = select.ownerDocument;
if (!doc)
doc = select.document;
var opt = doc.createElement('OPTION');
opt.value = value;
opt.text = text;
select.options.add(opt, index);
Pro zajimavost :)
function objGet2(d,x) {d=d==0?document:d; return (d.getElementById?d.getElementById(x):d.all?d.all[x]:d.layers?d.layers [x]:null);}

To reseni, co poslal je jako dobre. Proti fukcnosti a zpusobu nemam namitek. Jenom tak doplneni. Aby sis nemyslel, ze je to tak jednoduche.
HTML je totiz delane jako staticky dokument a cokoliv dalsi dynamickeho navic uz meni podstatu kouzelneho napoje a dostavas se na ostrou hranu nekompatibility.
Flexa
Profil
Bezva debata.
JS sice není můj šálek, ale po chvilce testování se začal chovat podle mých představ.
Ještě do toho nacpu trochu PHP a bude to úplně dokonalý.
díky
Toto téma je uzamčeno. Odpověď nelze zaslat.