Livesearch pomocí Ajax v Nette
- wicked
- Člen | 290
Zdravím,
našel jsem toto vlákno, které se tím zabývá, ale nějak to nemohu rozchodit.
Jde o to, že když přidám vše zmíněné od Vojty Dobeše
Homepage:
public function handleSearch($term)
{
$this->template->results = $this->produkty->findAll()->where('nazev', $term);
$this->redrawControl('results');
}
latte:
{snippet results}
{foreach $results as $result}
...
{/foreach}
{/snippet}
$('#{$control["searchForm"]['search']}').on('change input', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!}
'data': {
term: value
}
});
}
});
Tak už na mě laděnka řvě: Undefined variable: results
Na netu jsem vyštrachal toto přiřazení k tomu formuláři
$this->template->results = $this['searchForm'];
Takže od laděnky mám klid, ale pořád se nemohu dopídit toho, jak to zprovoznit…
Mohl by mi prosím někdo poradit?
Editoval wicked (13. 1. 2015 10:24)
- Etch
- Člen | 403
$this->template->results = $this['searchForm'];
Proč by v results měl být formulář?? V results by měl být defaultně prázdný array popřípadě by se v šabloně mělo kontrolovat jestli je daná proměná nadefinovaná. Tedy buď:
$this->template->results = array();
nebo
{snippet results}
{ifSet $results}
{foreach $results as $result}
...
{/foreach}
{/ifSet}
{/snippet}
V JS máš pak podle mě špatně selector, protože ač si tím nejsem
jistý, tak si myslím, že {$control["searchForm"]['search']}
nevrací ID prvku, ale mělo by tam být něco jako:
$('#{$control["searchForm"]['search']->htmlId}').on('change input', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!}
'data': {
term: value
}
});
}
});
Navíc si stejně myslím, že daný selector by měl být udělaný obecněji a neměl by využívat konstrukce typu „#$control[…]“, protože si tím naprosto zazdíš možnost tento JS přesunout do externího souboru a tedy i variantu, kdy JS načítáš na konci <body>.
Editoval Etch (13. 1. 2015 10:46)
- wicked
- Člen | 290
Tak jsem to upravil podle Tebe, tedy:
$this->template->results = array();
a script
<script>
$(function () {
$('#{$control["searchForm"]['search']->htmlId}').on('change input', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!}
'data': {
term: value
}
});
}
});
});
</script>
A vypisovat to chci takto:
{snippet results}
<div id="naseptavac">
<table class="wp-nap">
<tr n:foreach="$results as $item">
<td class="nasp-img"><img src="{$item->nazev}"></td>
{*<td class="nasp-nazev">{$item->nazev}</td>
<td class="nasp-cena">{$item->cena_dph}/td>
<td class="nasp-zob"><a href="#"><button>zobrazit</button></a></td>*}
</tr>
</table>
</div>
{/snippet}
Jenže mě to pořád nic nevrací …nic se neprovede …
Mimochodem když kouknu na zdrojak aplikace, tak není toto divné?
je to v tom JS
'url': "\/cyklozbozi\/www\/?do=search"
Editoval wicked (13. 1. 2015 11:09)
- Etch
- Člen | 403
Naváže se opravdu event na daný input? Zjistit se to dá jednoduše následujícím JS:
<script>
$(function(){
$('#{$control["searchForm"]['search']->htmlId}').on('change input', function () {
alert(1);
});
});
</script>
Provede se vůbec ten ajax request a vrátí potřebná data?? Nejlépe to můžeš zjistit ve firebugu.
- wicked
- Člen | 290
Ale ID toho inputu má ten JS správně …
<input type="text" name="search" placeholder="Přehazovačka, koutoučové brzdy, horské kolo ..." id="frm-searchForm-search" required data-nette-rules='[{"op":":filled","msg":"Pole mus\u00ed b\u00fdt vypln\u011bno!"}]'></td>
script jsem upravil takto, již to reaguje:
<script>
$(function(){
$('#frm-searchForm-search').on('change input', function () {
alert(1);
});
});
</script>
Editoval wicked (13. 1. 2015 15:52)
- David Matějka
- Moderator | 6445
@wicked a nebylo to nejak escapovany?
Spravne bys to mel vypisovat asi takhle:
$('#' + {$control["searchForm"]['search']->htmlId})
- wicked
- Člen | 290
Jenže když tedy upravím ten script na toto:
<script>
$(function () {
$('#frm-searchForm-search').on('change input', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!}
'data': {
term: value
}
});
}
});
});
</script>
Stále se nic neděje, jak to mohu v tom firebugu odchytnout? Respektivě není ještě divná ta cesna v tom url?
'url': "\/cyklozbozi\/www\/?do=search"
- wicked
- Člen | 290
matej21 napsal(a):
@wicked a nebylo to nejak escapovany?
Spravne bys to mel vypisovat asi takhle:$('#' + {$control["searchForm"]['search']->htmlId})
Ano, i takto to funguje :)
Každopádně co tam je ještě špatně? že se nic neděje? Respektivě jak to ochdytit v tom firebugu? když tam nastavím ten ajax
<script>
$(function(){
$('#' + "frm-searchForm-search").on('change input', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': "\/cyklozbozi\/www\/?do=search" // tohle mě uděla {link search}
'data': {
term: value
}
});
}
});
});
</script>
Tak se nic němění …
- Etch
- Člen | 403
Nic se neděje znamená co? Neproběhne ajax request nebo se nepřekreslí snippet?
JS si tam dej následující. Tam by měla být na 100% jistota, že se to na daný input chytne, pokud má opravdu id „#frm-searchForm-search“
<script>
$(function () {
$('#frm-searchForm-search').on('change', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!}
'data': {
term: value
}
});
}
});
});
</script>
- wicked
- Člen | 290
Mám to teď takto:
default.latte
<script>
$(function () {
$('#frm-searchForm-search').on('change', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!}
'data': {
term: value
}
});
}
});
});
</script>
{snippet results}
<div id="naseptavac">
<table class="wp-nap">
<tr n:foreach="$results as $item">
<td class="nasp-img"><img src="{$item->nazev}"></td>
</tr>
</table>
</div>
{/snippet}
Presenter:
public function handleSearch($term) {
$this->template->results = $this->produkty->findAll()->where('nazev', $term);
$this->redrawControl('results');
}
public function renderDefault() {
$this->template->results = array();
}
public function createComponentSearchForm() {
$form = new Form();
// Vyhledavaci pole
$form->addText('search', '')
->setRequired('Pole musí být vyplněno!')
->setAttribute('placeholder', 'Přehazovačka, koutoučové brzdy, horské kolo ...')
->getControlPrototype();
// Vyber typu
$form->addSelect('typ', '', array(
'bazarove' => 'Bazarové',
'nove' => 'Nové',
'oboji' => 'Bazarové i nové'
))->setPrompt('Typ zboží ...');
// Odesilaci tlacitko
$form->addSubmit('send', 'Hledat zboží')
->getControlPrototype()
->class('btn btn-info');
// Zavolame metodu searchBoxSuccedded po uspesnem odeslani
$form->onSuccess[] = $this->searchBoxSuccedded;
return $form;
}
Ale když začnu psát do pole, tak se snipet vubec neprekresluje, nic to nevypisuje …
- wicked
- Člen | 290
wicked napsal(a):
matej21 napsal(a):
handle se vola pred render. A v render nastavujes results na
array()
jenže když v render neuvedu results tak to na me rve, ze neni definovano $results … tak na co to mám nastavit tedy?
Odstanil jsem render z preenteru a do sablony pridal {ifset $results} za {snippet} takto:
{snippet results}
{ifset $results}
<div id="naseptavac">
<table class="wp-nap">
<tr n:foreach="$results as $item">
<td class="nasp-img"><img src="{$item->nazev}"></td>
<td class="nasp-nazev">{$item->nazev}</td>
<td class="nasp-cena">{$item->cena_dph}/td>
<td class="nasp-zob"><a href="#"><button>zobrazit</button></a></td>
</tr>
</table>
</div>
{/ifset}
{/snippet}
Ale stále se mi nic nevykresluje … snazim se v tom firebugu najit jak si overit zda to neco posila nebo ne, ale take marne …
- Etch
- Člen | 403
Zjisti si něco o životním cyklu presenteru.
public function actionDefault(){
$this->template->results = array();
}
Ve firebugu to je vidět v záložce „konzole“.
Editoval Etch (13. 1. 2015 17:38)
- wicked
- Člen | 290
Etch napsal(a):
Zjisti si něco o životním cyklu presenteru.
public function actionDefault(){ $this->template->results = array(); }
Ve firebugu to je vidět v záložce „konzole“.
Tak v debugeru jedine co je tak bylo
**SyntaxError: missing } after property list
‚data‘: {**
pridal jsem do scriptu „,“ takze :
<script>
$(function () {
$('#frm-searchForm-search').on('change', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!},
'data': {
term: value,
}
});
}
});
});
</script>
A ted v konzoli vidim akorad:
Error: Bootstrap's JavaScript requires jQuery
...(typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requi...
bootstrap.js (line 7, col 43)
ReferenceError: jQuery is not defined
}(window, document, jQuery));
fancybox.js (řádek 2018)
ReferenceError: $ is not defined
$(function () {
main.js (řádek 1)
"NetworkError: 500 Internal Server Error - http://aitee.savana-hosting.cz/cyklozbozi/www/css/open-sans/OpenSans-Light.ttf"
OpenSan...ght.ttf
"NetworkError: 500 Internal Server Error - http://aitee.savana-hosting.cz/cyklozbozi/www/css/open-sans/OpenSans-Bold.ttf"
OpenSans-Bold.ttf
"NetworkError: 500 Internal Server Error - http://aitee.savana-hosting.cz/cyklozbozi/www/css/open-sans/OpenSans-Regular.ttf"
OpenSan...lar.ttf
"NetworkError: 500 Internal Server Error - http://aitee.savana-hosting.cz/cyklozbozi/www/css/open-sans/OpenSans-BoldItalic.ttf"
OpenSan...lic.ttf
"NetworkError: 500 Internal Server Error - http://aitee.savana-hosting.cz/cyklozbozi/www/css/open-sans/OpenSans-Semibold.ttf"
OpenSan...old.ttf
Já už fakt nevím …
tady je ještě ten main.js
$(function () {
$.nette.init();
});
$(document).ready(function () {
$(".fancybox").fancybox({
openEffect: "none",
closeEffect: "none"
});
});
function dotaz() {
if (window.confirm("Opravdu si přejete provést tuto akci?"))
{
return true;
}
else
return false;
};
Editoval wicked (13. 1. 2015 17:48)
- wicked
- Člen | 290
Všechno v @layout.latte v <head>
<script src="{$basePath}/js/bootstrap.js"></script>
<script src="{$basePath}/js/fancybox.js"></script>
<script src="{$basePath}/js/main.js"></script>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/jquery-2.1.1.js"></script>
<script src="{$basePath}/js/nette.ajax.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
{include #header}
a pak v default.latte
{block header}
<script>
$(function () {
$('#frm-searchForm-search').on('change', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!},
'data': {
term: value,
}
});
}
});
});
</script>
{/block}
Všechny linky samozdřejmně funkční
- wicked
- Člen | 290
wicked napsal(a):
Přiznám se uplně bez mučení jquery je pro mě španělská vesnice …
Tento script jsem našel zde v jednom vlákně a psal ho @vojtech.dobes tak jsem jej chtěl použít … hlavně mě moc nekamenuj …
Přepsal jsem to na keyup místo on a konecne v konzili mám
GET http://aitee.savana-hosting.cz/cyklozbozi/www/?do=search&term=as
200 OK
318ms
jquery-2.1.1.js (řádek 8623)
ParametryHlavičkyOdezvaJSONCookies
{"state":[],"snippets":{"snippet--results":" <div id=\"naseptavac\">\n <table class=\"wp-nap\">\n\n\n <\/table>\n <\/div>\n"}}
Ale stále se mi nic ve snippetu, respektivě v tom kodu kde mám foreach (viz víše) nic neděje …
- wicked
- Člen | 290
Omlouvá se, teď už je to moje blbost … samoždřejmně mě to ted vypíše ale pouze pokud zadám přesný název do vyhledávání musím upravit sql aby to bralo jen část (předpokládám like :) )
EDIT: ne ted, ale porád je to moje blbost ;)
DĚKUJI VŠEM ZA POMOC!
Takto jsem ještě upravil handle:
public function handleSearch($term) {
$this->template->results = $this->produkty->findAll()->where('nazev LIKE ?', '%'.$term.'%');
$this->redrawControl('results');
}
Editoval wicked (13. 1. 2015 18:52)
- wicked
- Člen | 290
Etch napsal(a):
OT: No měl by sis tam upravit více věcí… například includování neexistujícího bloku „header“ nebo smyčku v přesměrování v „admin“ sekci…
O té smičce vím :) zatím řeším jiné věci :)
A ohledně toho includování .. v layoutu mam {include #header} a v potom v sablonach vzdy {block header}{/block} to je něco špatně?
- Etch
- Člen | 403
Mnoha způsoby… nejjednodušší je například:
<script>
$(function () {
$('#frm-searchForm-search').on('keyup', function () {
var value = $(this).val();
if (value.length >= 2) {
$.nette.ajax({
'url': {link search!},
'data': {
term: value,
}
});
}else{
$('div#naseptavac').hide();
}
});
});
</script>
Editoval Etch (13. 1. 2015 22:11)