Jednoduche vyhladavanie v databaze
- Andurit
- Člen | 131
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.
- Andurit
- Člen | 131
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
$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
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
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
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
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
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
Žá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
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)