Načtení prvků formuláře přes foreach
- Ladis-s
- Člen | 53
Snažím se vytvořit továrničku na formulář, který bude obsahovat seznam odkazů a u nich checkboxy. Tyto odkazy mám uložené v poli $odkazy a formulář se bez problémů vypíše, ale po odesláí formuláře se data ztratí.
<?php
foreach($odkazy as $klic => $odkaz){
$form->addHidden("odkaz_".$klic, $odkaz);
$form->addCheckbox("check_".$klic, $odkaz);
}
?>
Když zkusím do továrničky vložit prvek bez použití foreach, tak se také zobrazí a po odeslání jsou data z formuláře v pořádku:
<?php
$form->addHidden("odkaz_"."1", $odkazy[1]);
$form->addCheckbox("check_"."1", $odkazy[1]);
?>
Nevíte si s tím někdo rady?
- Ladis-s
- Člen | 53
hrach napsal(a):
podivej se na addContainer
Díky za radu, to je určitě efektivnější řešení.
Ale pořád to dělá stejný problém.
Když dám následující kód, tak po odeslání formuláře dostanu
prázdné pole.
<?php
$form->addContainer('odkazy');
foreach($odkazy as $klic => $odkaz){
$form['odkazy']->addHidden($klic, $odkaz);
}
?>
S tímto použitím vše funguje
<?php
$form->addContainer('odkazy');
$form['odkazy']->addHidden(1, $odkazy[1]);
?>
- Ladis-s
- Člen | 53
redhead napsal(a):
A vytváří se tyto pole i po submitnutí? Něco mi říká, že po submitu máš pole $odkazy prázdné a formulář pak neví, které hodnoty vlastně jsou jeho.
Nebo pošli víc kódu.
Právě, že se nevytváří i po submitnutí. Načtení toho pole trvá
trošku déle, tak jsem doufal, že stačí, když jsou hodnoty uložené v tom
formuláři.
Teď to mám tak, že pole načítám v továrničce. Předtím jsem ho zkušel
načítat v render, ale stejně to nepomohlo.
Kde bych ho tedy měl zpracovat, abych k němu měl přístup i po
submitnutí?
- Ladis-s
- Člen | 53
redhead napsal(a):
Pošli celý (relativně k problému) kód.
<?php
protected function createComponentOdkazyForm($name)
{
$form = new AppForm($this, $name);
include_once('../libs/simple_html_dom.php');
$id_webu = $this->request->params['id_webu'];
$link = WebModel::URLWebu($id_webu);
// načte HTML kód cílového linku
$html = file_get_html($link);
$odkazy = array(); // odkazy na podstránky
$e = $html->find('a');
for($i=0 ; $i<sizeof($e) ; $i++){
// vybere pouze odkazy mirici na vlastni domenu
// porovna nalezeny odkaz s adresou webu / vybere pouze domenu
if( str_replace("www.","", parse_url( $e[$i]->href , PHP_URL_HOST)) == str_replace("www.","", parse_url( $link , PHP_URL_HOST)) ){
// rozparsuji URL
$path = parse_url($e[$i]->href);
// vytahu z URL pouze relativni cestu bez parametru
$pathinfo = pathinfo($path['path']);
// možné koncovky stránek
$extensions = array("", "htm", "html", "php", "php5", "asp");
if(!isset($pathinfo['extension']))$pathinfo['extension']="";
// zkontroluje, jestli daný odkaz má koncovku stránky
if( in_array($pathinfo['extension'], $extensions) ){
if( !in_array($e[$i]->href, $odkazy) ) {
array_push($odkazy, $e[$i]->href);
}
}
}
}
$html->clear();
$form->addHidden('id_webu',$this->request->params['id_webu']);
$form->addHidden('pocet',sizeof($odkazy));
$form->addContainer('odkazy');
foreach($odkazy as $klic => $odkaz){
$form['odkazy']->addHidden($klic, $odkaz);
$form['odkazy']->addCheckbox($klic, $odkaz);
}
$form->addSubmit('send', 'Přidat');
$form->onSubmit[] = array($this, 'odkazyFormSubmitted');
}
public function odkazyFormSubmitted($form)
{
$data = $form->getValues();
print_r($data['odkazy']);
exit;
// vlozi do databaze
$id_stranky = StrankaModel::insert($data);
$this->flashMessage("Stránka \"".$data['nazev']."\" byla úspěšně přidána.");
$this->redirect('SpravaStranek:default', array('id_webu' => $data['id_webu']) );
}
?>
- redhead
- Člen | 1313
Tak mé postřehy:
- rozhodně parsování toho html, ať už to děláš pročkoliv, dát do nějakého modelu. Tady je to fuj fuj.
- pokud to trvá déle (což je asi logické), můžeš si to výsledné pole cachovat (na straně modelu – na model vždy jenom zavoláš metodu, která vrátí buď nové pole z parsování, pokud není v cache, anebo pole z cache a tím se zbavíš náročné operace parsování)
- dáváš dvěma prvkům stejné jména
$klic
(u hidden a checkboxu; docela se divím, že to neřve). Měl bys je odlišit třeba'hidden_'.$klic
a'check_'.$klic
(nebo něco podobného, to je na tobě)
Další chyby jsem nenašel. Zkus si třeba dumpnout to pole $odkazy. Ať už při normálním zobrazení nebo při odeslání v něm musí být stejné elementy.
Editoval redhead (16. 9. 2010 12:07)
- Patrik Votoček
- Člen | 2221
Fuj! include_once('../libs/simple_html_dom.php');
používej
RobotLoader
Fuj! $id_webu = $this->request->params['id_webu'];
používej (když už musíš)
$this->getParam(‚id_webu‘);
Fuj! celkově takovéhle věci do továrničky nepatří hoď si to do speciálních metod nejlépe modelu (mluvím o tom parsování).
- Ladis-s
- Člen | 53
S Nette začínám stejně jako MVC, tak v tom mám trochu guláš.
parsování jsem hodil teda do modelu, takže továrnička je takto:
<?php
protected function createComponentOdkazyForm($name)
{
$form = new AppForm($this, $name);
$id_webu = $this->getParam('id_webu');
$link = WebModel::URLWebu($id_webu);
$odkazy = StrankaModel::nactiStranky($link);
$form->addHidden('id_webu',$id_webu);
$form->addHidden('pocet',sizeof($odkazy));
$form->addContainer('odkazy');
foreach($odkazy as $klic => $odkaz){
$form['odkazy']->addCheckbox("check_".$klic, $odkaz);
}
$form->addSubmit('send', 'Přidat');
$form->onSubmit[] = array($this, 'odkazyFormSubmitted');
}
?>
Po submitnutí forruláře to zpracovávám takto:
<?php
public function odkazyFormSubmitted($form)
{
$data = $form->getValues();
$link = WebModel::URLWebu($data['id_webu']);
$odkazy = StrankaModel::nactiStranky($link);
// prida datum pridani
$ulozit = array();
$ulozit['datum_pridani'] = new DateTime();
print_r($data['odkazy']);
exit;
// vlozi do databaze
$id_stranky = StrankaModel::insert($data);
$this->flashMessage("Stránka \"".$data['nazev']."\" byla úspěšně přidána.");
$this->redirect('SpravaStranek:default', array('id_webu' => $data['id_webu']) );
}
?>
Stále nefukční. Nějak nechápu ten princip. Když formulář generuji, tak to tam jednotlivé prvky v pořádku vygeneruje, tzn. při odeslání formuláře by se měly hodnoty těch prvků odeslat. Nebo to chápu špatně?
Jinak za rady ohledně kódu díky, upravím si to.
- redhead
- Člen | 1313
Nemyslel jsem, že to pole $odkazy máš tvořit i v submit metodě. Tam to pole stejně nikde nepoužíváš. Šlo mi o to, že ta továrnička se provede v obou requestech (a v obou musí vygenerovat stejný formulář), proto jsem myslel to dumpnutí pole $odkazy (v továrničce) – uvidíš jesli se generuje stejný formulář, stejné prvky podle stejného pole $odkazy.
A kdyžtak si dumpni celé pole $data (values z formuláře), jestli se ti odešlo i ty napevno daný data (id_webu, pocet)
- Patrik Votoček
- Člen | 2221
Moc nechápu kde je problém… V submit metodě nemá
$odkazy = StrankaModel::nactiStranky($link);
co dělat to se ti
načte už v továrničce.
Btw pro dump se v Nette používá dump($val);
.
PS: Necituj zbytečně celý předchozí příspěvek za*** se tím fórum (citaci jsem odstranil).
- Ladis-s
- Člen | 53
Z té submit metody jsem to vyhodil a na dump používám:
Debug::dump($odkazy);
Už od začátku mám problém s tím, že když v továrničce načtu pole
$odkazy a vypíšu si z něj nějaký prvek formuláře pomocí přímého
indexu, např. $form->addHidden(‚odkaz‘,$odkazy[1]); , tak se v pohodě
vygeneruje a při odeslání je uložen v poli $data, tak jak by to mělo
být.
Ovšem když na to použiju foreach, nebo for cyklus, tak to záhadně
nefunguje. I když ho nechám projít třeba jen jednu iteraci.
- arron
- Člen | 464
Ladis-s napsal(a):
Nějak nechápu ten princip. Když formulář generuji, tak to tam jednotlivé prvky v pořádku vygeneruje, tzn. při odeslání formuláře by se měly hodnoty těch prvků odeslat. Nebo to chápu špatně?
Cele to funguje tak, ze Nette si pri odeslani nenecha podstrcit jen tak
nejake hodnoty, ale kontroluje, jestli v tom formulari takove hodnoty opravdu
ocekavas. Takze to, ze se neco ze stranky posle jeste vubec neznamena, ze se to
ve formulari objevi. Cili napr. pokud pri zobrazeni formulare pridas nejaky
checkbox, odesles jeho hodnotu, ale pri submitu ho uz do toho formulare
nepridas, tak se Ti ani neobjevi v ->getValues()
. Je to
jednoduse proto, aby se ty hodnoty nedaly podvrhnout. Osobne bych asi hledal
chybu nekde timto smerem…
- arron
- Člen | 464
Ladis-s napsal(a):
Aha, tak to je asi ten problém. Takže je to někde v tom, že to pole $odkazy už není načtené ve fci pro zpracování formuláře.
Anebo se do nej nactou nejake jine hodnoty. Nette si pak mysli, ze odeslane hodnoty jsou podvrh a tak je zahodi…
Když se spouští tato obslužná fce, tak se ještě jednou volá továrnička?
Nez se spusti obsluzna submit funkce, tak se zavola tovarnicka.
Ale když nad tím přemýšlím, tak mi nejde dohlavy to co jsem psal v #14
Jo, je to divny a rekl bych, ze ta chyba bude tak moc trivialni, ze se pak budeme divit, ze jsme to nevideli driv (a takove jsou nejhorsi)…