Jednoduche vyhladavanie v databaze

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

Ahojte, mam napisaný jednoduchý kód na vyhľadávanie ktorý je snáď správne

<?php
   public function searchsucceeded($searchword)
	{
	$selection = $this->database->findAll->select('*')->where("name LIKE ?", "%$searchword%");
	return $selection;
    }

    protected function createComponentsearchForm()
	{
		$form = new Form;
		$form->addText('name', 'Vyhladať ban, vložte nick zabanovaného hráča')
			->setRequired('Vyhladať ban, vložte nick zabanovaného hráča');
		$form->addSubmit('search', 'Hľadať')
			->setAttribute('class', 'default')
			->onClick[] = $this->searchsucceeded;
	}

?>

nasledne takto nejako vyzera findAll v modely:

<?php
	public function findAll()
	{
		return $this->database->table('banlist');
	}
?>

Rad by som z toho spravil nieco take: http://funedit.com/…84876495.jpg?x

bohuzial absolutne netusim ako prepojit tento kod s @layout.latte aby som tam zanechal vsetky prvky tak ako doteraz s rozdielom ze cely ten system bude na nette nie a objektovo nie ako doteraz. Vlastne ani neviem ci to mam napisane spravne.
Takto nejako vyzeral povodny formular:

<?php
	<form action="index.php" method="POST">
      <input type="text" style="margin-top:10px;" placeholder="Vyhľadať ban... (Zadajte nick hráča)" name="nickS" class="span10" required="required">
      <input type="submit" value="Hľadať" name="sSubmit" class="btn btn-primary span2">
    </form>

?>

Ak je tu niekto kto by mi s tym pomohol budem mu vdacny.

jiri.pudil
Nette Blogger | 1028
+
0
-

Pravděpodobně hledáš manuální vykreslování.

Andurit
Člen | 131
+
0
-

Skôr som dúfal v nejake konkrétne riešenie ako dokumentáciu, bohuzial z nej som to velmi nepochopil

Mysteria
Člen | 797
+
0
-

Název by měl být protected function createComponentSearchForm() { (velký S)
Do šablony pak dáš tohle:

{form searchForm}
{input name}
{input search}
{/form}

A nastylovat si to můžeš jak chceš v CSSkách, přes jeho IDčko, konkrétně tenhle by měl mít #frm-searchForm.

Andurit
Člen | 131
+
0
-

Vďaka za odpoveď, niečo podobne som skúšal už predtým, bohužial mi to vyhodilo error:
Cannot read an undeclared property Nette\Forms\Controls\SubmitButton::$onSuccess. Kedze som videl onSuccess videl pouzivat uz Xkrat , predpokladal som ze robim nieco zle. Nejake rady teda na tento onSuccess?

Edit: Upravil som si formular a uz sa tam formular zobrazuje, sice hadze error ale snad na to pridem , vďaka za pomoc

Editoval Andurit (19. 11. 2013 21:03)

Mysteria
Člen | 797
+
0
-
$form->addSubmit('search', 'Hľadať')
            ->setAttribute('class', 'default')
            ->onClick[] = $this->searchsucceeded;

bych upravil podle návodu (zmiňovaného nahoře) na:

$form->addSubmit('search', 'Hľadať')
    ->setAttribute('class', 'default')
    ->onClick[] = callback($this, 'searchSucceeded');

Ono vlastně, když na to koukám, tak i to searchSucceeded, tak bych to viděl takhle:

public function searchSucceeded(Form $form) {
	return $this->database->findAll->select('*')->where('name LIKE ?', "%" . $form->getValues()->search . "%");
}

Ty vlastně té metodě předáš celej formulář, takže všechny data, který obsahuje. A ty konkrétní data z políček získáš pomocí $form->getValues(), který ti vrací objekt, přes kterej se pomocí názvu toho inputu dostaneš k jeho hodnotám.

Jinak pokud už to máš nějak předělaný a pořád ti to nejde, tak sem zase hoď aktuální kód a chybu co ti to píše a pokud budu vědět, tak rád pomůžu díky nostalgii na moje úplné začátky s Nette. :D

EDIT: Nebo pokud chceš zkoumat řešení sám, tak se můžeš inspirovat jak řeším vyhledávání já (nezaručuju, že je to 100% správná cesta, kdyžtak můžete i mě někdo opravit, kdyby to bylo extra špatně ;)).

public function renderList($search = '') {
        $data = $this->repository->getAll($search);
}

protected function createComponentSearchForm() {
        $form = new Form();
		$form->addText('search')->setDefaultValue($this->search)->setAttribute('placeholder', 'Vyhledávání; jednotlivé výrazy oddělujte mezerou a poté stiskněte Enter...');
        $form->onSuccess[] = callback($this, 'searchSubmit');
        return $form;
    }

public function searchSubmit(Form $form) {
		$this->redirect(':Front:Server:list', array($form->getValues()->search));
    }

Přičemž $this->repository->getAll($search) není nic jinýho, než (trošku) složitější obdoba tvýho dosavadního kódu v searchSucceeded.

Editoval Mysteria (19. 11. 2013 22:49)

Andurit
Člen | 131
+
0
-

Mám to nejako takto:

<?php
public function searchsucceeded($searchword)
	{
	$selection = $this->banned->findAll->select('*')->where("name LIKE ?", "%$searchword%");
	return $selection;
    }

    protected function createComponentSearchForm()
	{
 		$form = new Form;
        $form->addText('name', 'Vyhľadať ban...vložte nick hráča');
        $form->addSubmit('search', 'Hľadať');
        $form->onSuccess[] = callback($this, 'searchsucceeded');
        return $form;
	}

?>

Pricom po odoslaní formulára mi to hádže chybu : Call to undefined method Nette\Callback::select() , pripadne where(). Doteraz som mal dojem select a where su preddefinovane. Zrejme sa mýlim alebo mam chybu niekde inde.

Toto je z modelu:

<?php
	public function findAll()
	{
		return $this->database->table('banlist');
	}
?>

p.s. skúsil som použit aj tvoj placeholder, prave dlhsie som uvažoval ako ho tam rozumne vložiť. Bohužiaľ vždy s chybou Cannot read an undeclared property BannedPresenter::$search.

Mysteria
Člen | 797
+
0
-

Předpokládám, že v $this->banned je instalace té třídy, který obsahuje tu metodu findAll(), takže ti tam v tom volání chybí ().

return $this->banned->findAll()->select('*')->where("name LIKE ?", "%$searchword%");

Ten placeholder ti takhle nejde?

$form->addText('name', 'Vyhľadať ban...vložte nick hráča')->setAttribute('placeholder', 'Něco');
Andurit
Člen | 131
+
0
-

Mal si pravdu, skoda tie () som si mohol všimnuť. Placeholder som urobil chybu. Teraz uz vidim kde ked si tu dal tento posledny priklad.

Každopádne k veci. /banned/?do=searchForm-submit krasne žiaden error, kedze hore mam v render default nieco ako : $this->template->banned = $this->banned->findAll()->order(‚id‘)->order(‚admin‘);
tak sa mi LOGICKY vzdy nacita toto a nie výsledok môho formu. Pošlem tu celý prezenter skus na to mrknut ak mas cas.

<?php
<?php

use Nette\Application\UI\Form;


class BannedPresenter extends BasePresenter
{
	/** @var AlbumRepository */
	private $banned;


	public function inject(Banned $banned)
	{
		$this->banned = $banned;
	}


	protected function startup()
	{
		parent::startup();
		echo "SOM PICA";
	}

	public function LoggedUser()
	{
		if (!$this->user->isLoggedIn()) {
			if ($this->user->logoutReason === Nette\Http\UserStorage::INACTIVITY) {
				$this->flashMessage('Bol si odhlasený.');
			}
			$this->redirect('banned', array('backlink' => $this->storeRequest()));
		}
	}


	/********************* view default *********************/


	public function renderDefault()
	{
		$this->template->banned = $this->banned->findAll()->order('id')->order('admin');
		$vp = new VisualPaginator($this, 'vp');
		$paginator = $vp->getPaginator();
		$paginator->itemsPerPage = 20;
		$paginator->itemCount = $this->template->banned->count('*');
		$this->template->banned = $this->banned->findAll()->order('id, admin')->limit($paginator->itemsPerPage,$paginator->offset);
	}


	/********************* views add & edit *********************/


	public function renderAdd()
	{
		$this['albumForm']['save']->caption = 'Add';
		//$this['searchForm']['search']->caption = 'Hľadať';
	}

	public function renderEdit($id = 0)
	{
		$form = $this['albumForm'];
		if (!$form->isSubmitted()) {
			$banned = $this->banned->findById($id);
			if (!$banned) {
				$this->error('Record not found');
			}
			$form->setDefaults($banned);
		}
	}


	/********************* view delete *********************/


	public function renderDelete($id = 0)
	{
		$this->template->banned = $this->banned->findById($id);
		if (!$this->template->banned) {
			$this->error('Record not found');
		}
	}


	/********************* component factories *********************/


	/**
	 * Edit form factory.
	 * @return Form
	 */
	protected function createComponentAlbumForm()
	{
		$this->LoggedUser();
		$form = new Form;
		$form->addText('name', 'Zabanovany:')
			->setRequired('Vlozte nick zabanovaneho hraca.');

		$form->addText('reason', 'Dovod:')
			->setRequired('Prosim vlozte dovod banu.');

		$form->addSubmit('save', 'Save')
			->setAttribute('class', 'default')
			->onClick[] = $this->albumFormSucceeded;

		$form->addSubmit('cancel', 'Cancel')
			->setValidationScope(NULL)
			->onClick[] = $this->formCancelled;

		$form->addProtection();
		return $form;
	}


	public function albumFormSucceeded($button)
	{
		$values = $button->getForm()->getValues();
		$id = (int) $this->getParameter('id');
		if ($id) {
			$this->banned->findById($id)->update($values);
			$this->flashMessage('Ban bol upravený.');
		} else {
			$this->banned->insert($values);
			$this->flashMessage('Ban bol pridany.');
		}
		$this->redirect('default');
	}


	protected function createComponentDeleteForm()
	{
		$form = new Form;
		$form->addSubmit('cancel', 'Cancel')
			->onClick[] = $this->formCancelled;

		$form->addSubmit('delete', 'Delete')
			->setAttribute('class', 'default')
			->onClick[] = $this->deleteFormSucceeded;

		$form->addProtection();
		return $form;
	}


	public function deleteFormSucceeded()
	{
		$this->banned->findById($this->getParameter('id'))->delete();
		$this->flashMessage('Ban bol zmazany!');
		$this->redirect('default');
	}


	public function formCancelled()
	{
		$this->redirect('default');
	}

	public function searchsucceeded($searchword)
	{
	return $this->banned->findAll()->select('*')->where("name LIKE ?", "%$searchword%");
    }

    protected function createComponentSearchForm()
	{
 		$form = new Form;
        $form->addText('name', 'Vlož nick hráča')->setAttribute('placeholder', 'Vyhľadať ban...vložte nick hráča');
        $form->addSubmit('search', 'Hľadať');
        $form->onSuccess[] = callback($this, 'searchsucceeded');
        return $form;
	}
}
?>
Mysteria
Člen | 797
+
0
-

To bylo jasné už od začátku, ale nejdřív jsem chtěl abys vyřešit ten form.

public function searchsucceeded($searchword) {
    return $this->banned->findAll()->select('*')->where("name LIKE ?", "%$searchword%");
}

Tohle je už z podstaty špatně, protože co ono to udělá. Vrátí ti to sice nový data, ale ty zase vzápětí přemažeš tím co máš v renderDefault().

Takže to udělej jako to mám já výše. Tímhle po odeslání formuláře přesměruješ na metodu renderDefault() ale spolu s tím předáš jako parametr to klíčové slovo.

public function searchsucceeded($searchword) {
	$this->redirect('default', array($searchword));
    }

Takže pak upravíš renderDefault na

public function renderDefault($searchWord = null) {
	if (is_null($search)) {
      		$this->template->banned = $this->banned->findAll()->order('id')->order('admin');
	} else { $this->template->banned = $this->banned->findAll()->select('*')->where("name LIKE ?", "%$searchWord%"); }
	...

Když nebude odeslanej žádnej formulář, tak $searchWord bude null, takže načteš všechno jako doteď, pokud odešleš form, tak v něm bude to klíčové slovo a načteš jenom ty co odpovídají tomu LIKE.

Andurit
Člen | 131
+
0
-

Keď to podávaš takto znie to logicky, a je to vcelku jasne. Každopádne, nepochopil som celkom to $search (prakticky tam aj tak hlasi undefined variabile), predpokladam ze tam malo byt $searchword, stranka sa aktualne ale presmeruje na default ale bez vykreslenia len vysledkov z vyhladavania

<?php
public function renderDefault($searchWord = null)
	{
		$this->template->banned = $this->banned->findAll()->order('id')->order('admin');
		$vp = new VisualPaginator($this, 'vp');
		$paginator = $vp->getPaginator();
		$paginator->itemsPerPage = 20;
		$paginator->itemCount = $this->template->banned->count('*');
		if (is_null($searchWord)){
		$this->template->banned = $this->banned->findAll()->order('id, admin')->limit($paginator->itemsPerPage,$paginator->offset);
		} else { $this->template->banned = $this->banned->findAll()->select('*')->where("name LIKE ?", "%$searchWord%"); }
	}
?>
<?php
return  $this->redirect('default', array($searchword));?>
?>

p.s. Link vyzera takto: localhost/www/banned/ takze redirectujem spravne ?

Editoval Andurit (21. 11. 2013 3:11)

Mysteria
Člen | 797
+
0
-

Žádnej return tam nebude, jenom čistě

$this->redirect('default', array($searchword));

Po odeslání formuláře bys měl bejt přesměrován na něco jako localhost/www/banned/?searchword=hledany_vyraz (za předpokladu, že jsi neměl nějak routování aplikace).

Třeba budeš mít štěstí a už to půjde. :)

Andurit
Člen | 131
+
0
-

Bohužiaľ bez zmeny, ani URL nič.. je nejako mozne aby si mi na seba dal nejaky viac interaktivny kontakt, ako SKYPE/ ICQ alebo nieco podobne (ak budem moc otravovat ,vzdy je tam magicke tlacitko IGNORE :P)

p.s. Kamos mi pred chvilkou poradil to zapisat takto:

<?php
$this->redirect('default', array('searchword' => $searchword));
?>

ak dam to searchword do uvodzoviek tak je link krasny searchword=searchword inak je to stale to iste :P

Editoval Andurit (22. 11. 2013 15:42)