Obsah stránky v databázi – nejlepší řešení
- Desttro
- Člen | 126
Zdarvím,
chci se zeptat, jak nejlépe zobrazit HTML obsah z databáze.
Mám web, kde je stejná struktura – menu, patička a v pravo je dependent
selectbox pro vyhledávání a má se měnit jenom obsah.
Mám to řešené takhle:
{block content}
{$post['content']|noescape}
<div class="col-md-3 col-lg-3">
<section class="region-sidebar-second">
<!-- TADY JE SEARCH CAR -->
<section class="block block-search-car well well-primary">
<h2 class="block-title">Hledat auto</h2>
<div class="block-content">
<form n:name=searchForm class="views-exposed">
<div class="field field-manufacture">
<select n:name=manufacturer class="selectpicker" data-style="btn">
</select>
</div><!-- /.field -->
<div n:snippet=searchSnippet class="field field-model">
<select n:name=model class="selectpicker" data-style="btn">
</select>
</div><!-- /.field -->
<div class="field field-manufacture">
<select n:name=fuel class="selectpicker" data-style="btn">
</select>
</div><!-- /.field -->
<div class="group-years">
<label>Rok</label>
<div class="field field-min-year">
<select n:name=yearfrom class="selectpicker" data-style="btn">
</select>
</div><!-- /.field -->
<div class="field field-max-year">
<select n:name=yearto class="selectpicker" data-style="btn">
</select>
</div><!-- /.field -->
</div><!-- /.group-years -->
<div class="group-years">
<label>Cena</label>
<div class="field field-min-year">
<select n:name=pricefrom class="selectpicker" data-style="btn">
</select>
</div><!-- /.field -->
<div class="field field-max-year">
<select n:name=priceto class="selectpicker" data-style="btn">
</select>
</div><!-- /.field -->
</div><!-- /.group-years -->
<button n:name=send class="btn btn-primary btn-lg btn-block">
Hledat
</button><!-- /.views-exposed -->
</form>
</div><!-- /.block-content -->
</section><!-- /.block-search-car -->
<script>
{include #jsCallback, input => manufacturer, link => firstChange}
</script>
{define #jsCallback}
$('#{$control["searchForm"][$input]->htmlId}').on('change', function() {
$.nette.ajax({
type: 'GET',
async: false,
url: '{link {$link}!}',
data: {
'value': $(this).val(),
}
});
});
{/define}
{control contactBox}
{control advertismentBox}
</section>
</div><!-- /.column 3 -->
problém je, že nefunguje AJAX – něco vyberu a nejede to.
Všude v ostatních templatách to funguje, ale tady kde se má „dynamicky“ měnit obsah to nejde.
Děkuji za radu
- Desttro
- Člen | 126
Práve se to generuje správně,
dokonce to v Network dá spráný odkaz, když vyberu např. BMW, ale další
select už nevyfiltruje modely aut.
Tohle mi to dělalo i když jsme to chtěl dát do komponenty, musím to mít
v každém presenteru zvlášť.
Tady je obrázek: http://s24.postimg.org/…x/select.jpg
je to děláno podle tohoto návodu: https://blog.nette.org/…-and-pure-js
- Desttro
- Člen | 126
Aha to je špatně, obsahuje to zase znovu tu stránku.
Ale nevím proč to dělá, má to být stejně jako u toho druhého – má
tam být snipet
http://s24.postimg.org/…/select3.jpg
tady je to správně:
http://s15.postimg.org/…/sleect2.jpg
- Desttro
- Člen | 126
aha :)
public function handleFirstChange($value)
{
if ($value) {
$modelItems = $this->getModel($value);
$this['searchForm']['model']->setPrompt('Model (nerozhoduje)')
->setItems($modelItems);
} else {
$this['searchForm']['model']->setPrompt('Nerozhoduje')
//->setItems(array());
->setItems(array());
}
$this->invalidateControl('searchSnippet');
}
dám tady i metodu getModel (ta by m ěla být v pořádku)
public function getModel($manufacturer)
{
$row = $this->database->table('cars')
->select('DISTINCT model')
->where('manufacturer = ?', $manufacturer)
->order('model ASC')
->fetchPairs('model', 'model');
return ($row) ? $row : NULL;
}
- trejjam
- Backer | 65
Zkus přejít na tu adresu /?post=11&do=firstChange&value=BMW a potom debugovat, např zda se Ti skutečně provede metoda handle. Primitivní test je třeba toto (zobrazí se „BMW“):
function handleFirstChange($value) {
dump($value);
$this->terminate();
}
Nevím jakou verzi Nette používáš ale invalidateControl je deprecated použij redrawControl.
- Desttro
- Člen | 126
No když to udělám jak v HomepagePresenteru tak v PostPresenteru tak mi to vyhodí u obou:
"BMW" (3)
Když dám tento odkaz:
www/post/?postId=11&do=firstChange&value=BMW
tak se to bez prblému přepne. Problém je v tom, že když to přepnu
v tomto selectboxu na presenteru PostPresenter, tak to udělá odkaz
takový:
/www/post/?postId=11&do=firstChange&value=BMW
a vadí tam to amp; – když to z toho odkazu smažu tak se to zase přepne v pohodě.
Co se týče routů, moc se v tom nevyznám a udělal jsem si podle návodu router pro AdminModule a FrontModule. Klidně bych byl rád za „hezké odkazy“
Tohle je můj RouterFactory.php:
namespace App;
use Nette,
Nette\Application\Routers\RouteList,
Nette\Application\Routers\Route,
Nette\Application\Routers\SimpleRouter;
/**
* Router factory.
*/
class RouterFactory
{
/**
* @return \Nette\Application\IRouter
*/
public function createRouter()
{
$router = new RouteList();
// Admin
$router[] = new Route('admin/<presenter>/<action>/<id>', array(
'module' => 'Admin',
'presenter' => 'Admin',
'action' => 'default',
'id' => NULL,
));
// Front
$router[] = new Route('<presenter>/<action>/<id>', array(
'module' => 'Front',
'presenter' => 'Homepage',
'action' => 'default',
'id' => NULL,
));
return $router;
}
}
Editoval Desttro (8. 1. 2015 8:25)
- trejjam
- Backer | 65
Ah, zkus toto:
{include #jsCallback, input => manufacturer, link => firstChange}
{define #jsCallback}
<script>
$('#{$control["searchForm"][$input]->htmlId}').on('change', function() {
$.nette.ajax({
type: 'GET',
async: false,
url: {link {$link}!}, //takto by latte mělo poznat že jsi v js a escapovat jako v js, tedy bez &
data: {
'value': $(this).val(),
}
});
});
</script>
{/define}
- Desttro
- Člen | 126
S tím to neudělá v Network žádný dotaz, nefunguje to s zádnou variantou:
{include #jsCallback, input => manufacturer, link => firstChange}
{define #jsCallback}
<script>
$('#{$control["searchForm"][$input]->htmlId}').on('change', function() {
$.nette.ajax({
type: 'GET',
async: false,
url: {link {$link}!}, //takto by latte mělo poznat že jsi v js a escapovat jako v js, tedy bez &
data: {
'value': $(this).val(),
}
});
});
</script>
{/define}
<script>
{include #jsCallback, input => manufacturer, link => firstChange}
</script>
{define #jsCallback}
$('#{$control["searchForm"][$input]->htmlId}').on('change', function() {
$.nette.ajax({
type: 'GET',
async: false,
url: {link {$link}!},
data: {
'value': $(this).val(),
}
});
});
{/define}
<script>
{include #jsCallback, input => manufacturer, link => firstChange}
</script>
{define #jsCallback}
<script>
$('#{$control["searchForm"][$input]->htmlId}').on('change', function() {
$.nette.ajax({
type: 'GET',
async: false,
url: '{link {$link}!}',
data: {
'value': $(this).val(),
}
});
});
</script>
{/define}
Neudělá to v Networks žádný dotaz
Editoval Desttro (8. 1. 2015 14:42)
- Desttro
- Člen | 126
Tak jsem to nakonec vyřešil na základě tohoto příspěvku pomocí replace: https://forum.nette.org/…e-link-s-amp
- Etch
- Člen | 403
Odkaz přidej ke každému inputu do data atributu
data-link="..."
formuláři nastav třídu „searchform“ nebo nějakou příhodnou a pak prostě jednoduše použij následující JS
<script>
$('.searchform :input').on('change', function(){
$.nette.ajax({
type: 'GET',
async: false,
url: $(this).data('link'),
data: {
'value': $(this).val()
}
});
});
</script>
EDIT:
Používání selectorů jako například:
$('#{$control["searchForm"][$input]->htmlId}')
je většinou cesta do pekel.
Editoval Etch (11. 1. 2015 13:10)
- Etch
- Člen | 403
Měl by tam být link na který půjde ajax požadavek. Takže pokud bych se měl držet toho co si uvedl tedy:
{include #jsCallback, input => manufacturer, link => firstChange}
tak by to vypadalo následovně:
<select n:name=manufacturer class="selectpicker" data-link="{link firstChange!}" data-style="btn">
</select>
<select n:name=model class="selectpicker" data-link="{link secondChange!}" data-style="btn">
</select>
...
...
...
Koukal jsem na ten návod na planette a bohužel se mi zdá, že to tam @TomášVotruba s tím JS nechtěně zbytečně překombinoval a udělal daný JS extrémně jednoúčelovej. To co jsem zde uvedl já funguje stejně a přijde mi to na první pohled jako srozumitelnější a univerzálnější (šel by udělat ještě univezálnější) zápis a navíc lze vyčlenit do exteního JS.
EDIT:
Ještě doplním tu univerzálnější variantu:
<script>
$.nette.ext('dependentFormInput', {
load: function(){
$('form :input[data-sel-dependent-link]').off('change').on('change', function(){
$.nette.ajax({
type: 'GET',
async: false,
url: $(this).data('selDependentLink'),
data: {
'value': $(this).val()
}
});
});
}
});
</script>
tohle s chytne na všechny inputy, které mají nasteven data atribut „data-sel-dependent-link“ a lze to tedy použít naprosto univerzálně. Pokud je tedy potřeba přidat třeba další závislej input, tak stačí napsat signál a přidat ho tomu inputu do data atributu a o samotný JS už se člověk nemusí starat.
Editoval Etch (12. 1. 2015 4:13)