Ajax do handle na vybrání hodnoty ze selectu
- unjustolaf
- Člen | 29
Zdravim borci,
Snažím se vytvořit select pod produktem v mém e-shopu kde by bylo rúzné množství daného produktu a ve chvíli kdy uživatel vybere nějakou hodnotu z tohoto selectu nastane handle který tuto vybranou hodnotu uloží do proměnné a ta se potom uloží do šablony odkud jí mohu poslat jako parametr. Nechci aby uživatel musel klikat na tlačítko a tím potvrzoval dané množství produktu a proto jsem se rozhodl poprvé v mém životě na něco použít ajax.
Postupoval jsem následovně.
- Stáhl jsem si soubor nette.ajax.js z tohoto githubu
- Tento soubor jsem si nahrál do složky www/js/
- Do @layout.latte jsem dal odkaz
<?php
<body>
<header>
{include "Components/header.latte"}
</header>
<div n:foreach="$flashes as $flash" class="flash-{$flash->type}">{$flash->message}</div>
{include content}
<footer>
{include "Components/footer.latte"}
</footer>
{block scripts}
<script src="http://code.jquery.com/jquery-3.3.1.slim.js" integrity="sha256-fNXJFIlca05BIO2Y5zh1xrShK3ME+/lYZ0j+ChxX2DA=" crossorigin="anonymous"></script>
<script src="{$basePath}/js/nette.ajax.js"></script> //viz zde
<script src="{$basePath}/bootstrap/js/bootstrap.min.js"></script>
<script src="{$basePath}/js/main.js"></script>
<script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
{/block}
</body>
</html>
?>
- Do main.js jsem dal následující kód (vše podle návodu na githubu)
<?php
$(function () {
$.nette.init();
});
?>
- V této fázi jsem si myslel že mám ajax úspěšně naimplementovaný a začel jsem zkoušet vlákna jako je např. toto Ale nic nefungovalo a vždy když jsem vybral hodnotu ve svém selectu žádný ajax nenastal. Po 5 hodinách jsem už vyzkoušel všechny vlákna zde na fóru ve kterých se jedná o onChange selectu a nic mi nefungovalo, žádný ajax nikdy nenastal a nikdy jsem se nedostal do handle který jsem si vytvořil. Teď už jsem tak zoufalý, že píši sem a žádám vás o pomoc.
Nyní jsem kompletně vyčistil všechny mé pokusy a mám čistý kód do kterého bych chtěl tento ajax implementovat. Jsem tedy za 4. krokem (viz výše) a mám toto:
item.latte
<?php
{block content}
...
<form n:name="selectAmount" method="GET">
<select n:name="amount" class="form-control">
</select>
</form>
...
<style>
// Zde potřebuji fungující ajax, který pozná když uživatel vybere nějakou možnost ze selectu se jménem amount a pošle jeho hodnotu do mého handleSelectAmount(), kde s ní budu dále pracovat
</style>
?>
ShopPresenter.php
<?php
protected function createComponentSelectAmount()
{
$form = new Form;
$form->addSelect('amount', 'Vyberte množství:', [
'1' => '10g',
'2' => '50g',
'3' => '100g',
])->setDefaultValue('1');
$form->onSuccess[] = [$this, 'selectAmountSuccess'];
return $form;
}
public function selectAmountSuccess(Form $form)
{
}
public function handleRefresh($value){
//zde bych chtěl obdržet value selectu po jejím vybrání uživatele
}
?>
Prosím poraďte mi jak na to, jsem už zoufalý. Vždy se snažím vše vymyslet sám ale tentokrát už opravdu nevím co dál.
Předem všem děkuji
- japlavaren
- Člen | 404
dovod preco ti to nefunguje je, ze aby sa zavolalo ajaxove volanie musi ho nieco spustit. ajax plugin ktory pouzivas ma na to triedy ktorymi oznacis co ma byt ajaxove: https://github.com/…tte.ajax.js/#…
to co chces ty bude vyzadovat obsluzny js kod. tak ako to mas navrhnute
potrebujrd toto:
na tym selectboxom sledovat udalost change a pri change zavolat rucne
jQuery.ajax call na url tvojho handle
nieco ako:
<script>
$(function(){
$.nette.init();
$('#{$form[amount]->htmlId}').change(function() {
$.ajax({
method: 'get',
url: {link refresh!},
data: {value: $(this).val()}
});
});
});
</script>
takto nejak by ti to mohlo fungovat
- unjustolaf
- Člen | 29
japlavaren napsal(a):
dovod preco ti to nefunguje je, ze aby sa zavolalo ajaxove volanie musi ho nieco spustit. ajax plugin ktory pouzivas ma na to triedy ktorymi oznacis co ma byt ajaxove: https://github.com/…tte.ajax.js/#…
to co chces ty bude vyzadovat obsluzny js kod. tak ako to mas navrhnute potrebujrd toto:
na tym selectboxom sledovat udalost change a pri change zavolat rucne jQuery.ajax call na url tvojho handle
nieco ako:<script> $(function(){ $.nette.init(); $('#{$form[amount]->htmlId}').change(function() { $.ajax({ method: 'get', url: {link refresh!}, data: {value: $(this).val()} }); }); }); </script>
takto nejak by ti to mohlo fungovat
Píše mi to unknown macro {value} a podtrhava radek data: {value: $(this).val()} nemá to náhodou být {‚value‘: $(this).val()}?
A ještě se chci zeptat, když bych chtěl otestovat jestli mi do handleRefresh prišla ta hodnota value a udělám to takto:
<?php
public function handleRefresh($value)
{
dump($value);
die();
}
?>
Tak se po vybrání hodnoty ze selectboxu absolutně nic nestane takže ten ajax bud furt nefunguje nebo jsem z toho uz fakt jelen.
- unjustolaf
- Člen | 29
GEpic napsal(a):
zapiš to takto (ano, s tou mezerou, ať se to nevyhodnocuje jako latte zápis):
{ value: $(this).val() }
Provedl jsem, ale handle Refresh se stále nevykoná
<?php
public function handleRefresh($value)
{
dump($value);
die();
}
?>
Možná to takhle nelze, pokud něco dělám špatně upozorněte mě prosím, ale takhle ja vypisuji promene v metodach odjakziva.
- Mistrfilda
- Člen | 76
Ahoj,
v situaci kdy se má volat handle, je dole v tracy debug baru vidět ajax panel (jestli tedy používáš novou verzi nette, 2 panely nad sebou – tracy a ajax)? Jinak zkus místo dump a die použít bdump a kouknout jestli něco nevypíše do ajax debug baru dole.
- unjustolaf
- Člen | 29
Mistrfilda napsal(a):
Ahoj,
v situaci kdy se má volat handle, je dole v tracy debug baru vidět ajax panel (jestli tedy používáš novou verzi nette, 2 panely nad sebou – tracy a ajax)? Jinak zkus místo dump a die použít bdump a kouknout jestli něco nevypíše do ajax debug baru dole.
Ahoj, tak nad tracy debug barem nemám žádný ajax panel to za prvé a verzi nette bych měl mít aktuální, tedy pokud stačí přepsat verzi nette v composer.json a v terminalu dat composer update ve slozce projektu. Bdump jsem zkoušel bez úspěchu, nemyslím si, že se handleRefresh vubec zavolá, ajax podle mě nic nědělá.
- Mistrfilda
- Člen | 76
Zkus dát do jakkékoliv šablony presenteru
<a class="ajax" n:href="test!">KLIK</a>
a do presenteru
public function handleTest()
{
bdump("AJAX call");
}
Jestli toto nefunguje tak bude problém s načítaním nette.ajax knihovny, kde teď voláš $.nette.init()? Prohlizecova console zadne chybi nehlasi?
- unjustolaf
- Člen | 29
Mistrfilda napsal(a):
Zkus dát do jakkékoliv šablony presenteru
<a class="ajax" n:href="test!">KLIK</a>
a do presenteru
public function handleTest() { bdump("AJAX call"); }
Jestli toto nefunguje tak bude problém s načítaním nette.ajax knihovny, kde teď voláš $.nette.init()? Prohlizecova console zadne chybi nehlasi?
Toto mi vyhodí klasický dump s textem „AJAX call“.
To je zvláštní jsem si jistý že do prohlížečové konzole jsem se předtím koukal a nic tam nebylo – teď tam je:
- TypeError: $.ajax is not a function – a když ho rozkliknu
localhost:8888/e-shop/e-shop/www/js/nette.ajax.js:225:25
requestHandler
localhost:8888/e-shop/e-shop/www/js/nette.ajax.js:48:14
dispatch
code.jquery.com/jquery-3.3.1.slim.js:5182:16
add/elemData.handle
code.jquery.com/jquery-3.3.1.slim.js:4991:6
- ReferenceError: $ is not defined.
Editoval unjustolaf (30. 8. 2018 1:27)
- Mistrfilda
- Člen | 76
Dobře, tím pádem je nette.ajax načteno a mělo by fungovat jestli funguje příklad co jsem poslal. Dej sem prosím část latte souboru kde se snažíš ajax volat, obalujes ještě dané scipty do blocku?
- unjustolaf
- Člen | 29
Celé moje latte:
<?php
{block content}
<div class="container">
<div class="row mt-5">
<div class="col-lg-9">
<div class="card">
<img style="width: auto; height: auto" class="card-img-top img-fluid" src="{$basePath}/{$item->item_image}" alt="">
<div class="card-body">
<h3 class="card-title">{$item->item_name}</h3>
<h4 style="color: red">{$item->item_price},- Kč</h4>
<p class="card-text">{$item->item_content}</p>
{if $item->item_evaluation == NULL}
<span class="text-muted"><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i></span>
{elseif $item->item_evaluation < 0.5}
<span class="text-muted"><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i></span>
{elseif $item->item_evaluation >= 0.5 && $item->item_evaluation < 1}
<span class="text-muted"><i class="fas fa-star-half"></i></span>
{elseif $item->item_evaluation >= 1 && $item->item_evaluation < 1.5}
<span class="text-muted"><i class="fas fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i></span>
{elseif $item->item_evaluation >= 1.5 && $item->item_evaluation < 2}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star-half"></i></span>
{elseif $item->item_evaluation >= 2 && $item->item_evaluation < 2.5}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i></span>
{elseif $item->item_evaluation >= 2.5 && $item->item_evaluation < 3}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star-half"></i></span>
{elseif $item->item_evaluation >= 3 && $item->item_evaluation < 3.5}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="far fa-star"></i><i class="far fa-star"></i></span>
{elseif $item->item_evaluation >= 3.5 && $item->item_evaluation < 4}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star-half"></i></span>
{elseif $item->item_evaluation >= 4 && $item->item_evaluation < 4.5}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="far fa-star"></i></span>
{elseif $item->item_evaluation >= 4.5 && $item->item_evaluation < 5}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star-half"></i></span>
{elseif $item->item_evaluation == 5}
<span class="text-muted"><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i></span>
{/if}
{if $item->item_evaluation == NULL}
<span>Doposud nebylo přidáno žádné hodnocení produktu</span>
{elseif $item->item_evaluation <= 0.5}
<span> {$item->item_evaluation} hvězdiček</span>
{elseif $item->item_evaluation >= 0.5 && $item->item_evaluation < 1}
<span> {$item->item_evaluation} hvězdičky</span>
{elseif $item->item_evaluation >= 1 && $item->item_evaluation < 1.5}
<span> {$item->item_evaluation} hvězdička</span>
{elseif $item->item_evaluation >= 1.5 && $item->item_evaluation < 2}
<span> {$item->item_evaluation} hvězdiček</span>
{elseif $item->item_evaluation >= 2 && $item->item_evaluation < 2.5}
<span> {$item->item_evaluation} hvězdičky</span>
{elseif $item->item_evaluation >= 2.5 && $item->item_evaluation < 3}
<span> {$item->item_evaluation} hvězdiček</span>
{elseif $item->item_evaluation >= 3 && $item->item_evaluation < 3.5}
<span> {$item->item_evaluation} hvězdičky</span>
{elseif $item->item_evaluation >= 3.5 && $item->item_evaluation < 4}
<span> {$item->item_evaluation} hvězdiček</span>
{elseif $item->item_evaluation >= 4 && $item->item_evaluation < 4.5}
<span> {$item->item_evaluation} hvězdičky</span>
{elseif $item->item_evaluation >= 4.5 && $item->item_evaluation < 5}
<span> {$item->item_evaluation} hvězdiček</span>
{elseif $item->item_evaluation == 5}
<span> {$item->item_evaluation} hvězdiček</span>
{/if}
<form n:name="selectAmount" class="ajax" method="GET">
<select n:name="amount" class="form-control">
</select>
</form>
<a class="ajax" n:href="test!">KLIK</a>
<div class="mt-3">
<a n:href="addToCart!, 'itemid' => $item->item_id, 'categoryid' => $item->category_id" style="color: white; background-color: red" class="btn btn-lg">
<i class="fas fa-cart-plus"></i> Přidat do košíku
</a>
</div>
</div>
</div>
<div class="card card-outline-secondary my-4">
<div class="card-header">
Recenze produktu
</div>
<div class="card-body">
{foreach $reviews as $review}
{if $review['review']->review_content == NULL}
<p style="color: #8c8c8c">Bez podrobnějšího hodnocení.</p>
{else}
<p>{$review['review']->review_content}</p>
{/if}
{if $review['review']->item_evaluation == 1}
<big class="text-muted">★ ☆ ☆ ☆ ☆</big><br>
{elseif $review['review']->item_evaluation == 2}
<big class="text-muted">★ ★ ☆ ☆ ☆</big><br>
{elseif $review['review']->item_evaluation == 3}
<big class="text-muted">★ ★ ★ ☆ ☆</big><br>
{elseif $review['review']->item_evaluation == 4}
<big class="text-muted">★ ★ ★ ★ ☆</big><br>
{else}
<big class="text-muted">★ ★ ★ ★ ★</big><br>
{/if}
<small class="text-muted">Hodnocení přidal <span style="color: blue">{$review['review']->review_author_name}</span> {$review['review']->date_created}</small>
<hr>
{/foreach}
{if $user_review == NULL}
<a n:href="Shop:addReview, 'itemid' => $item->item_id, 'categoryid' => $item->category_id" class="btn btn-success">Zanechat recenzi</a>
{elseif $user_review == "notLoggedIn"}
<a class="btn btn-warning">Na přidání recenze se musíte přihlásit</a><br><br>
<a class="btn btn-success" n:href="Sign:in">Přihlásit se nyní</a>
{else}
<a class="btn btn-warning">Už jste ponechal recenzi na toto zboží</a>
{/if}
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="box">
<div class="box-icon">
<span><i class="fas fa-briefcase-medical fa-3x"></i></span>
</div>
<div class="info">
<p class="text-center">Výrobek není určen pro lidskou konzumaci. Výrobek je určen pouze pro vzdělávací/výzkumné účely.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(function(){
$.nette.init();
$('#{$form[amount]->htmlId}').change(function() {
$.ajax({
method: 'get',
url: {link refresh!},
data: { value: $(this).val() }
});
});
});
</script>
?>
- Mistrfilda
- Člen | 76
Zkus ukončít {block content} za posledním divem
</div>
</div>
</div>
{/block}
a script část obalit do
{block scripts}
{include parent}
<script>
$(function(){
$.nette.init();
$('#{$form[amount]->htmlId}').change(function() {
$.ajax({
method: 'get',
url: {link refresh!},
data: { value: $(this).val() }
});
});
});
</script>
{/block}
- unjustolaf
- Člen | 29
Mistrfilda napsal(a):
Zkus ukončít {block content} za posledním divem
</div> </div> </div> {/block}
a script část obalit do
{block scripts} {include parent} <script> $(function(){ $.nette.init(); $('#{$form[amount]->htmlId}').change(function() { $.ajax({ method: 'get', url: {link refresh!}, data: { value: $(this).val() } }); }); }); </script> {/block}
Hmm tohle něco udělalo, ted kdyz nactu stránku vyhodí se mi error Undefined variable: form na řádku $(‚#{$form[amount]->htmlId}‘).change(function() { a v konzoli SyntaxError: invalid increment/decrement operand.
- Mistrfilda
- Člen | 76
Jo sorry, moje chyba, dej prosím id selectu natvrdo přes
<select n:name="amount" id="selectid" class="form-control">
a pak změnit řádek ve scriptu z
$('#{$form[amount]->htmlId}').change(function() {
na
$('#selectid').change(function() {
Editoval Mistrfilda (30. 8. 2018 2:06)
- unjustolaf
- Člen | 29
Mistrfilda napsal(a):
Jo sorry, moje chyba, dej prosím id selectu natvrdo přes
<select n:name="amount" id="selectid" class="form-control">
a pak změnit řádek ve scriptu z
$('#{$form[amount]->htmlId}').change(function() {
na
$('#selectid').change(function() {
Proboha vůbec se neomlouvej, si můj zachránce. Ke stavu aplikace, tohle pomohlo, ted se dostanu na stranku bez erroru (i konzole je prazdna), ale kdyz kliknu na polozku v selectu napise mi to v konzoli TypeError: $.ajax is not a function
EDIT: Používal jsem slim verzi jquery která má smazané funkce jako např ajax takže stačilo prohodit verzi za uncompressed a ted uz si myslis vse funguje jak má
Editoval unjustolaf (30. 8. 2018 2:13)
- unjustolaf
- Člen | 29
No tak vše opravdu funguje jak má, teď už jen přemýšlím jaký způsob zvolit z handleRefresh abych si dostal tuto proměnou value zpět do template a podle ní vykreslil cenu ke zvolenému množství produktu.
Napadlo mě to dělat takhle i když vám se to asi bude zdát asi hloupé, mě v tuto chvíli nic jiného nenapadá.
<?php
public function handleRefresh($value){
$this->redirect("Shop:item", array("itemid" => $this->getParameter("itemid"), "amount" => $value));
}
?>
Problém je že se žádný redirect nevykoná :(