Obsah stránky v databázi – nejlepší řešení

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

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

marioff
Člen | 69
+
0
-

a vysledny vygenerovany HTML kod je v poriadku?

Desttro
Člen | 126
+
0
-

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

marioff
Člen | 69
+
0
-

a ked rozkliknes co obsahuju vratene data ? kedze vratilo 200 OK

Desttro
Člen | 126
+
0
-

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

marioff
Člen | 69
+
0
-

cize asi bude chyba v spracovani toho signalu.. pozri ci to mas tam ok

Desttro
Člen | 126
+
0
-

marioff napsal(a):

cize asi bude chyba v spracovani toho signalu.. pozri ci to mas tam ok

jsem začátečník, můžu porposit kde ten signál najdu? děkuji

marioff
Člen | 69
+
0
-

ja tiez :D

signal je ta metoda v presenteri ktora zacina na handle , cize v tomto pripade handleFirstChange … skopiruj ju sem ak neni moc velka

resp. ci ju vobec mas…

Editoval marioff (7. 1. 2015 15:29)

Desttro
Člen | 126
+
0
-

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
+
0
-

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
+
0
-

Už vím kde je problém,
je to např. tím ?post když tam není nic tak to funguje, ale kdyz je např /catalog/ nebo ten post tak to nejde.
Jde to nějak vyřešit?

trejjam
Backer | 65
+
0
-

Omlouvám se překoukl jsem se mělo by to být ?postId=… (viz Tvůj screen).
Záleží na tvém routeru (handle se vztahuje k dané komponentě).

Desttro
Člen | 126
+
0
-

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&amp;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
+
0
-

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 &amp;
		            data: {
		                'value': $(this).val(),
		            }
		        });
	        });
</script>
{/define}
Desttro
Člen | 126
+
0
-

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 &amp;
            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
+
0
-

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
+
0
-

Popravdě… stejně nechápu, proč ten link nemáš v data atributu. Tohle mi přijde krapet ďábelské.

Desttro
Člen | 126
+
0
-

No dělal jsem to podle toho návodu, jiné řešení mě nenapadlo

Etch
Člen | 403
+
0
-

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)

Desttro
Člen | 126
+
0
-

vím že je to blbá otázka, ale co přesně mám dát do data atributu? Npasal jsi tam tři tečky, co by tam mělo být?
děkuji

Etch
Člen | 403
+
0
-

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)

Desttro
Člen | 126
+
0
-

Díky zkusím