vyhladavaci formular a strankovanie

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
fliper333
Člen | 36
+
0
-

Ahojte,

Mam problem s Nette Forms a strankovanim vystupu. V skratke. Mam obrovsky vyhladavaci formular (cca 20 poloziek). Vyplnim hodnoty podla ktorych chcem vyhladavat a dam odoslat (pomocou POST). Zobrazenie prvej stranky + strankovania funguje bez problemov, avsak ak kliknem na dalsiu stranku (GET ?pg=2) tak sa mi logicky formular vymaze a nezobrazi sa ani dalsia stranka s vysledkami.

Spravil som to tak, ze pole form->getValues() som po odoslani formulara ulozil do $_SESSION[‚searchValues‘] a pri prechode na dalsiu stranku pomocou form->setDefaults tam tieto udaje znovu vlozim, unsetnem $_SESSION[‚searchValues‘] a pomocou javascriptu formu odoslem… S tymto riesenim vsak nie som velmi spokojny a hladam sposob ako to urobit elegantnejsie. Cely framework Nette nepouzivam, pretoze si na to zatial netrufam.

Zdrojak posielam nizsie, lebo prispevok je dlhsi ako 10.000 znakov a nedovoli mi to sem dat.

fliper333
Člen | 36
+
0
-
<?php

    class exportTask
    {

        var $form;
        var $pg, $numPages;
        var $searchValues;

        function __construct($searchValues = array())
        {
            $this->searchValues = $searchValues;
            $this->form = $this->getForm();
        }

        function getNumPages($values)
        {
            $result = dibi_BIRD::query('SELECT COUNT(*) FROM [bird_task] WHERE %and', $values);
            return ceil($result->fetchSingle() / ITEMS_PER_PAGE) - 1;
        }

        function getPg($pg)
        {
            return ($pg) ? (($pg == 'last') ? $this->numPages : (($pg <= $this->numPages) ? abs(intval($pg)) : 0)) : 0;
        }

        function getForm()
        {
            $form = new NForm('search');

            $form->addSelect('id_region', 'Region:', $this->getRegions())
                 ->getControlPrototype()->class('select-xlong');

            $form->addText('attuid', 'ATTUID:')
                 ->getControlPrototype()->class('input-long');

            $form->addText('part_number', 'Part number:')
                 ->getControlPrototype()->class('input-long');


            ...


            $form->addSubmit('search', 'Search');
            $form->addSubmit('export', 'Export');

            $form->getRenderer()->wrappers['pair']['.required'] = NULL;
            $form->getRenderer()->wrappers['control']['.required'] = NULL;

            foreach ($form->getComponents() as $formContol)
            {
                $formContol->getControlPrototype()->addClass('border');
            }

            return $form;
        }

        function search($values)
        {
            $result = dibi_BIRD::query('SELECT * FROM [bird_task] WHERE %and %lmt %ofs', $values, ITEMS_PER_PAGE, $this->pg * ITEMS_PER_PAGE);
            return $result->fetchAll();
        }

        function getFormValues()
        {
            $values = array();
            foreach ($this->form->getValues() as $key => $value) $values[$key] = $value;
            foreach ($values as $key => & $val) if ($val == NULL) unset($values[$key]); // delete empty keys from values

            if (isset($values['id_customer']))
            {
                $values['bird_task.id_customer'] = $values['id_customer'];
                unset($values['id_customer']);
            }

            if (isset($values['time_spent']))
            {
                $values[] = array('time_spent ' . $values['time_spent_type'] . ' %f', $values['time_spent']);
                unset($values['time_spent']);
            }

            unset($values['time_spent_type']);

            if (isset($values['date_range']))
            {
                if ($values['date_range'] == 'custom')
                {
                    $values[] = array('date >= %s', dateMysql($values['date_from']));
                    $values[] = array('date <= %s', dateMysql($values['date_to']));
                    unset($values['date_from']); unset($values['date_to']);
                } else {
                    $dateFilter = functions::dateRange($values['date_range']);
                    $values[] = array('date >= %s', $dateFilter['from']);
                    $values[] = array('date <= %s', $dateFilter['to']);
                }
                unset($values['date_range']);
            }

            return $values;
        }

        function processForm($pg)
        {
            if ($this->form->isSubmitted())
            {
                if ($this->form->isValid())
                {
                    $values = array();
                    foreach ($this->form->getValues() as $key => $value) $values[$key] = $value;
                    $this->searchValues = $values;
                    $values = $this->getFormValues();
                    $this->numPages = $this->getNumPages($values);
                    $this->pg = $this->getPg($pg);
                    return $this->search($values);
                }
            } else {
                $this->form->setDefaults($this->searchValues);
            }
        }

    }
fliper333
Člen | 36
+
0
-
require (MOD_DIR . '/export/exportTask.php');

$pg = (isset($_GET['pg'])) ? $_GET['pg'] : NULL;

if (isset($_SESSION['searchValues']))
{
    $searchValues = $_SESSION['searchValues'];
    unset($_SESSION['searchValues']);
} else {
    $searchValues = array();

}

if (isset($_POST['attuid']))
{
    $submitForm = false;
} else {
    $submitForm = true;
}


$task = new exportTask($searchValues);

$smarty->assign('data', $task->processForm($pg));
$smarty->assign('numPages', $task->numPages); // total number of pages
$smarty->assign('pg', $task->pg); // actual page
$smarty->assign('form', $task->form);
$smarty->assign('showUser', true);
$smarty->assign('showControls', false);
$smarty->assign('required', functions::getRequiredPairs());
$smarty->assign('excelNames', functions::getExcelNames());
$smarty->assign('submitForm', $submitForm);

$_SESSION['searchValues'] = $task->searchValues;
{extends file="index.tpl"}
{block name=body}

{include file='result.tpl' actionResult=$actionResult length='long'}
{include file="export/task/form.tpl" scope=parent}
{include file="listTask.tpl" scope=parent}

{if $submitForm}
    <script type="text/javascript">
        $('#frm-search').submit();
    </script>
{/if}

<div id="clear"></div>

{/block}
Pavel Kouřil
Člen | 128
+
0
-

Možná teď plácnu uplnou blbost; ale PROČ vyhledávací formulář neposíláš přes GET? A pak neuděláš akorát $form->setDefaults($_GET)? :)

Přecijen – je lepší, aby si člověk mohl vyhledání bookmarknout, ne? :)

fliper333
Člen | 36
+
0
-

mas pravdu, nakoniec som to spravil cez GET. to setDefaults tam pri metode GET ani nie je potrebne :) cez POST som to chcel robit koli tomu, ze som mal spraveny univerzalny skript na strankovanie ktory som mal vsade includnuty, a nechcel som ho prerabat, ale nakoniec som nemal inu moznost :)

joe
Člen | 313
+
0
-

Takhle přes GET to bude asi nejlepší, taky mám trošku větší vyhledávací formulář + záznamy se stránkováním. Chtěl bych ho zAJAXovat, jak to kdo děláte, aby stránkování bralo v potaz ty parametry v URL?

powercz
Člen | 12
+
0
-

joe napsal(a):

Mrkni se do dokumentace

joe
Člen | 313
+
0
-

@powercz:
Myslel jsem trochu něco jiného. Mně jde o tohle – mám adresu se záznamy, formulářem na filtrování a stránkováním:

example.com/list

Odkazy na této stránce pro paginator pak budou

example.com/list?paginator-page=1
example.com/list?paginator-page=2

Když formulář (GET) odešlu, pak se v adrese objeví:

example.com/list?do=formFilter-submit&param1=value1&param2=value2&...

A teď chci mít v paginatoru odkazy:

example.com/list?do=formFilter-submit&param1=value1&param2=value2&...&paginator-page=1
example.com/list?do=formFilter-submit&param1=value1&param2=value2&...&paginator-page=2


Tady asi přichází na řadu persistentní parametry… ale i když budu mít třeba 30 inputů ve formuláři? A nebo jeden s hashem.
Ale to se mi přidají parametry i do URL kam nechci. Mám mít presenter Items (pro seznam a stránkování) a Item (pro konkrétní)?

Editoval joe (22. 7. 2011 15:09)

joe
Člen | 313
+
0
-

Tak pořád nějak tápu nad tím, jak mám udělat ten filtrační formulář s hodně inputama a stránkováním. Můžete sem někdo prosím napsat, jak jste to řešili nebo jak byste to udělali?

Filtrační formulář posílám přes GET (možnost zkopírování adresy & možnost přímé změny URL, nechci nahrazovat všechny parametry za hash, co si budu ukládat do DB). Po odeslání formuláře nepřesměrovávám (snad nemusím?) a v URL mi zůstane tedy něco jako ?do=filterForm-submit&... následuje hromada parametrů :)

Tak jsem si poradil tak, že po odeslání formuláře jsou v paginatoru odkazy vedoucí na ?paginator-page=..&do=filterForm-submit&...

To všechno funguje. V případě normálních poždavků bych nemusel řešit to, co bude následovat. AJAX, protože odkazy jsou ve tvaru, kde zpracovávají signál odeslání formuláře, celý ten formulář se při AJAXu generuje znovu, i když to není vůbec potřeba. Otázkou je, jak to udělat jinak, abych ho při AJAX požadavku znovu nevytvářel. Poradíte někdo? Díky