Dependent form select with AJAX

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

Ahojte,
mám formulár, kde sa snažím spraviť 3 select boxy, závislé od hodnoty toho prvého.

Rozhodol som sa, že pôjdem podľa postupu https://blog.nette.org/…-and-pure-js

V layoute síce vykreslí labels a select boxy – first select, second select, third select a submit button, no po výbere hodnoty vo first select sa nenačítajú hodnoty do ostatných select boxov.

Viete mi prosím poradiť, s čím môže byť problém?

Ďakujem

presenter

<?php
namespace App\Presenters;

use Nette\Application\UI\Form;


class HomepagePresenter extends BasePresenter
{



    public function renderDefault()
    {
        $this->template->_form = $this['selectForm'];
    }


    /**
     * Load values to second select
     * @param int
     */
    public function handleFirstChange($value)
    {
        if ($value) {
            $secondItems = array(
                1 => 'First option ' . $value . ' - second option 1',
                2 => 'First option ' . $value . ' - second option 2'
            );

            $this['selectForm']['second']->setPrompt('Select')
                ->setItems($secondItems);

            $this['selectForm']['third']->setPrompt('Select from second');

        } else {
            $this['selectForm']['second']->setPrompt('Select from first')
                ->setItems(array());

            $this['selectForm']['third']->setPrompt('Select from first')
                ->setItems(array());
        }

        $this->invalidateControl('secondSnippet');
    }


    /**
     * Load values to third select
     * @param int
     */
    public function handleSecondChange($value)
    {
        if ($value) {
            $thirdItems = array(
                1 => 'Second option ' . $value . ' - third option 1',
                2 => 'Second option ' . $value . ' - third option 2'
            );

            $this['selectForm']['third']->setPrompt('Select')
                ->setItems($thirdItems);

        } else {
            $this['selectForm']['third']->setPrompt('Select from second')
                ->setItems(array());
        }

        $this->invalidateControl('thirdSnippet');
    }


    /********************** form **********************/


    protected function createComponentSelectForm()
    {
        $firstItems = array(
            1 => 'First option 1',
            2 => 'First option 2'
        );

        $form = new Form;
        $form->addSelect('first', 'First select:', $firstItems)
            ->setPrompt('Select');
        $form->addSelect('second', 'Second select:')
            ->setPrompt('Select from first');
        $form->addSelect('third', 'Third select:')
            ->setPrompt('Select from first');
        $form->addSubmit('send', 'Submit');

        $form->onSuccess[] = $this->processSelectForm;

        return $form;
    }


    /**
     * @param form
     */
    public function processSelectForm(Form $form)
    {
        // same as above
    }

}

latte

{define #content}

{form selectForm}
    {label first /} {input first}
    {snippet secondSnippet}
        {label second /} {input second}

        {snippet thirdSnippet}
            {label third /} {input third}
        {/snippet}

        {include #js}
    {/snippet}
    {input send}
{/form}

{/define}


{define #js}

<script type="text/javascript">
{include #jsCallback, input => first, link => firstChange}
{include #jsCallback, input => second, link => secondChange}
</script>

{/define}


{define #jsCallback}
{* same as above *}
{/define}

na konci @layout.latte pouzivam

    <script src="{$basePath}/dist/js/nette.ajax.js"></script>
    <script>
    $(function () {
        $.nette.init();
    });
    </script>
F.Vesely
Člen | 369
+
0
-

Presne tady bude problem.

{define #jsCallback}
{* same as above *}
{/define}

Nemuze se ti to prece prekreslovat, kdyz to po zmene selectboxu neposles ajaxem na server.

majo1
Člen | 103
+
0
-

jaj.. moja nepozornost..
najprv som skusal ten prvy navod, potom tento druhy a myslel som, ze tam ten callBack je definovany :)
kazdopadne, dakujem, funguje to :)

majo1
Člen | 103
+
0
-

je to asi taka primitivna chyba, ale ucim sa :)
snazil som sa do premennej $ziskaneIdCentra zapisat id strediska, ktore je ako value v 1. Select boxe.
Na zaklade tohoto ID chcem vyfiltrovat:

  • termin skibusu (druhy selectbox), IDE
  • zastavku (treti selectbox), NEJDE, pise len „najskor vyberte skibus“

viete prosim poradit?
dakujem

<?php
namespace App\Presenters;

use App\Model\ReservationformManager;
use Nette\Application\UI\Form;


class HomepagePresenter extends BasePresenter
{

    private static $ziskaneIdCentra;

    protected $reservationformManager;


    public function __construct(ReservationformManager $reservationformManager)
    {
        parent::__construct();
        $this->reservationformManager = $reservationformManager;
    }

    public function renderDefault()
    {
        // required to enable form access in snippets
        $this->template->_form = $this['selectForm'];
    }

    /**
     * Load values to second select
     * @param int
     */
    public function handleFirstChange($value)
    {
        if ($value) {
            self::$ziskaneIdCentra = $value;
            $resultSk = $this->reservationformManager->getSkibusSel(self::$ziskaneIdCentra);
            $secondItems = $resultSk->fetchPairs('idskibus', 'departureDatetime');

            $this['selectForm']['second']->setPrompt('-- vyberte --')
                ->setItems($secondItems);

            $this['selectForm']['third']->setPrompt('-- najskôr vyberte skibus --');

        } else {
            $this['selectForm']['second']->setPrompt('-- vyberte najskôr stredisko --')
                ->setItems(array());

            $this['selectForm']['third']->setPrompt('-- vyberte najskôr stredisko --')
                ->setItems(array());
        }

        $this->invalidateControl('secondSnippet');
    }

    public function handleSecondChange($value)
    {
        if ($value) {
            $resultSt = $this->reservationformManager->getStationSel(self::$ziskaneIdCentra); //$ziskaneIdCentra

                    $thirdItems = $resultSt->fetchPairs('idstation', 'city'); //city spojit s casom

            $this['selectForm']['third']->setPrompt('-- vyberte --')
                ->setItems($thirdItems);

        } else {
            $this['selectForm']['third']->setPrompt('-- najskôr vyberte skibus --')
                ->setItems(array());
        }

        $this->invalidateControl('thirdSnippet');
    }


    /********************** form **********************/


    protected function createComponentSelectForm()
    {
        $resultCe = $this->reservationformManager->getCenter();
        $firstItems = $resultCe->fetchPairs('idcenter', 'centerName');

        $form = new Form;
        $form->addSelect('first', 'Stredisko: ', $firstItems)
            ->setPrompt('-- vyberte --');
        $form->addSelect('second', 'Skibus - termín: ')
            ->setPrompt('-- vyberte najskôr stredisko--');
        $form->addSelect('third', 'Zastávka: ')
            ->setPrompt('-- vyberte najskôr stredisko--');
        $form->addSubmit('send', 'Submit');

        $form->onSuccess[] = $this->processSelectForm;

        return $form;
    }


    /**
     * @param form
     */
    public function processSelectForm(Form $form)
    {
        // $form->getValues() ignores invalidated input's values
        $values = $form->getHttpData();
        unset($values['send']);
        dump($values);

    }

}
F.Vesely
Člen | 369
+
+2
-
private static $ziskaneIdCentra;

Tohle vyhod, na tohle se staticke promenne nepouzivaji.

Proc potrebujes nejdrive vybrat skibus, nez dovolis vybrat zastavku? Nestaci ti jenom:

	/**
     * Load values to second select
     * @param int
     */
    public function handleFirstChange($value)
    {
        if ($value) {
            $resultSk = $this->reservationformManager->getSkibusSel($value);
            $secondItems = $resultSk->fetchPairs('idskibus', 'departureDatetime');

            $this['selectForm']['second']->setPrompt('-- vyberte --')
                ->setItems($secondItems);

            $resultSt = $this->reservationformManager->getStationSel($value); //$ziskaneIdCentra

            $thirdItems = $resultSt->fetchPairs('idstation', 'city'); //city spojit s casom

            $this['selectForm']['third']->setPrompt('-- vyberte --')
                ->setItems($thirdItems);

        } else {
            $this['selectForm']['second']->setPrompt('-- vyberte najskôr stredisko --')
                ->setItems(array());

            $this['selectForm']['third']->setPrompt('-- vyberte najskôr stredisko --')
                ->setItems(array());
        }

        $this->invalidateControl('secondSnippet');
    }
majo1
Člen | 103
+
0
-

ďakujem za radu, takto to je ideálne :)
už ma len jedna vec trápi,
ako tie selecty kvôli snippetom manuálne vyrenderovať do tohoto formátu

     <div class="form-group">
       <label n:name=second>Skibus*</label>
       <select n:name=second class="form-control">
             <option></option>
       </select>
     </div>

a do tohoto latte nehcem ťahať hlavné @layout.latte

Editoval majo1 (5. 2. 2016 15:56)

majo1
Člen | 103
+
0
-

chcem totiž, selectboxy doplniť do tohoto latte

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">

  <link rel="stylesheet" href="{$basePath}/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
  <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
  <link rel="stylesheet" href="{$basePath}/dist/css/AdminLTE.min.css">
  <link rel="stylesheet" href="{$basePath}/dist/css/skins/skin-blue.min.css">
  <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->
</head>
<body>




          <style>
          .alert-dismissable .close, .alert-dismissible .close { right: 0; }
          </style>
          <div n:foreach="$flashes as $flash" style="padding: 15px;">
            <div class="box-body alert alert-info alert-dismissable">
              <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
              <h4><i class="icon fa fa-info"></i> {$flash->message}</h4>
            </div>
          </div>

    <form n:name=reservationForm class=form>
    <div n:if="$form->hasErrors()" class="callout callout-warning">
        <h4>Chyba!</h4>
        <p n:foreach="$form->errors as $error">{$error}</p>
    </div>

    <div class="form-group">
       <label n:name=resdetail-center_idcenter>Stredisko*</label>
       <select n:name=resdetail-center_idcenter class="form-control">
             <option></option>
       </select>
     </div>
     <div class="form-group">
       <label n:name=resdetail-skibus_idskibus>Skibus*</label>
       <select n:name=resdetail-skibus_idskibus class="form-control">
             <option></option>
       </select>
     </div>
     <div class="form-group">
       <label n:name=resdetail-station_idstation>Zastávka*</label>
       <select n:name=resdetail-station_idstation class="form-control">
             <option></option>
       </select>
     </div>


     <div class="input-group">
       <label n:name=resdetail-numAdult>Počet dospelých*
         <div class="input-group">
         <input type="number" min="0" max="100" class="form-control" n:name=resdetail-numAdult>
         <div class="input-group-addon">
             <i class="fa fa-child"></i>
           </div>
         </div>
       </label>
     </div>
     <div class="input-group">
       <label n:name=resdetail-numJunior>Počet juniorov*
         <div class="input-group">
         <input type="number" min="0" max="100" class="form-control" n:name=resdetail-numJunior>
         <div class="input-group-addon">
             <i class="fa fa-child"></i>
           </div>
         </div>
       </label>
     </div>
     <div class="input-group">
       <label n:name=resdetail-numKid>Počet detí*
         <div class="input-group">
         <input type="number" min="0" max="100" class="form-control" n:name=resdetail-numKid>
         <div class="input-group-addon">
             <i class="fa fa-child"></i>
           </div>
         </div>
       </label>
     </div>
     <div class="input-group">
       <label n:name=resdetail-numTransportOnly>Len doprava*
         <div class="input-group">
         <input type="number" min="0" max="100" class="form-control" n:name=resdetail-numTransportOnly>
         <div class="input-group-addon">
             <i class="fa fa-bus"></i>
           </div>
         </div>
       </label>
     </div>


     <div class="input-group">
        <label n:name=custdetail-name>Meno*
          <div class="input-group">
          <input class="form-control" n:name=custdetail-name>
          <div class="input-group-addon">
              <i class="fa fa-user"></i>
            </div>
          </div>
        </label>
     </div>
     <div class="input-group">
         <label n:name=custdetail-surename>Priezvisko*
           <div class="input-group">
           <input class="form-control" n:name=custdetail-surename>
           <div class="input-group-addon">
               <i class="fa fa-user"></i>
             </div>
           </div>
         </label>
     </div>
     <div class="input-group">
        <label n:name=custdetail-telephone>Telefón*
          <div class="input-group">
          <input class="form-control" n:name=custdetail-telephone>
          <div class="input-group-addon">
              <i class="fa fa-phone"></i>
            </div>
          </div>
        </label>
     </div>
     <div class="input-group">
         <label n:name=custdetail-email>E-mail
           <div class="input-group">
           <input class="form-control" n:name=custdetail-email>
           <div class="input-group-addon">
               <i class="fa fa-envelope"></i>
             </div>
           </div>
         </label>
     </div>

    <p><input n:name=submit class="btn btn-primary"></p>
    </form>






   <script src="http://momentjs.com/downloads/moment.min.js"></script>
    <script src="{$basePath}/plugins/jQuery/jQuery-2.1.4.min.js"></script>{include #js}
    <script src="{$basePath}/bootstrap/js/bootstrap.min.js"></script>
    <script src="{$basePath}/dist/js/app.min.js"></script>
    <script src="{$basePath}/dist/js/demo.js"></script>
    <link rel="stylesheet" href="{$basePath}/plugins/timepicker/bootstrap-timepicker.min.css">
    <script src="{$basePath}/plugins/timepicker/bootstrap-timepicker.min.js"></script>

    <link href="//cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/build/css/bootstrap-datetimepicker.css" rel="stylesheet">
    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js"></script>
    <script src="//cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/src/js/bootstrap-datetimepicker.js"></script>
    <script type="text/javascript">
        $(function () {
            $('#datetimepicker2').datetimepicker({
                locale: 'sk',
                useCurrent: true,
                format: 'YYYY-MM-DD HH:mm'
            });
        });
    </script>
    <script>
      $(function () {
        //Timepicker
        $(".timepicker").timepicker({
          showInputs: false,
          showMeridian: false,
          minuteStep: 1,
          defaultTime: 'current',
          format: 'HH:mm'
        });
      });
    </script>


</body>
</html>

Ďakujem

F.Vesely
Člen | 369
+
0
-

Normalne je tam pridej a obal snippetem. Nechapu tvuj problem.

majo1
Člen | 103
+
0
-
  1. Funguje to. Ale chcel som sa vyhnut tomu, aby sa default.latte vykreslovalo v @layout.latte , co teraz robi :)
  2. Dalej pri submite hadze tracy chybu:

Model – Notice – Trying to get property of non-object

public function saveReservationform($reservationform)
25:        {
26:            $this->database->beginTransaction();
27:                **$idcust = $this->database->table("customers")->insert($reservationform->custdetail)->idcustomer;**
28:                $reservationform->resdetail->customer_idcustomer = $idcust;
29:                $this->database->table("reservations")->insert($reservationform->resdetail);
30:            $this->database->commit();
31:        }

asi bude niekde chyba v presenteri. tato funkcia sa vola po kliknuti tlacidla submit

    public function editorFormSucceeded($form, $values)
    {
        try {
            $values = $form->getHttpData();
            $this->reservationformManager->saveReservationform($values);
            $this->flashMessage('Rezervácia bola úspešne odoslaná. Ďakujeme.');
            //$this->redirect(':Reservationform:', $values->idreservation);
        } catch (UniqueConstraintViolationException $ex) {
            $this->flashMessage('Rezervácia s týmto ID už existuje!');
        }
    }

Editoval majo1 (5. 2. 2016 20:27)

CZechBoY
Člen | 3608
+
0
-

Ty values netahej z httpData… Uz si je beres pres parametr :-)

Jinak tezko rict, co z toho neni objekt. Vydumpuj si csechny promenny na tom radku a uvidis.

majo1
Člen | 103
+
0
-

no $values = $form->getHttpData(); som zakomentoval :-)
teraz pise SQLSTATE[23000]: Integrity constraint violation: 1048 Column ‚skibus_idskibus‘ cannot be null

sql:
INSERT INTO reservations
(numAdult, numJunior, numKid, numTransportOnly, center_idcenter, skibus_idskibus, station_idstation, customer_idcustomer)
VALUES (‚1‘, ‚2‘, ‚1‘, ‚5‘, 1, NULL, NULL, 56)

cize je asi niekde problem pri naplnani center_idcenter a skibus_idskibus do $values.

CZechBoY
Člen | 3608
+
0
-

Vydumpoval sis ty proměnný?

Koukám, že ten bug/feature z Nette 2.0 asi stále existuje a musí se používat $form->getHttpData() jako je v pla.nette v článku…

majo1
Člen | 103
+
0
-

do tracy som si dal vydumpovat $values:

array (5)
resdetail ⇒ array (7)
center_idcenter ⇒ „1“
skibus_idskibus ⇒ „2“
station_idstation ⇒ „1“
numAdult ⇒ „2“
numJunior ⇒ „0“
numKid ⇒ „1“
numTransportOnly ⇒ „0“

custdetail ⇒ array (4)
name ⇒ „Jozko“ (5)
surename ⇒ „Mrkvicka“ (8)
telephone ⇒ „0905 555 555“ (12)
email ⇒ „jozko@mrkvicka.sk" (17)
_submit ⇒ "Rezervovať skibus“ (18)
_token_ ⇒ „wvrg5df3culV5SbRSw2yvHtc3m6md3o0OKKyo=“ (38)
do ⇒ „reservationForm-submit“ (22)

($values = $form->getHttpData(); som odkomentoval, takze sa teraz vykonava) a zda sa , ze vsetky stlpce su teraz vyplnene a tracy aj tak pise Trying to get property of non-object

chyba vypisuje k riadku $idcust = $this->database->table(„customers“)->insert($reservationform->custdetail)->idcustomer;

Editoval majo1 (6. 2. 2016 10:27)

enumag
Člen | 2118
+
+1
-

@majo1 Snippety jsou na závislé selecty zbytečně složité, úplně stačí použít tenhle addon.

majo1
Člen | 103
+
0
-

ten doplnok som skúšal nainštalovať :) no nešlo to skrz nejakých minimum-requirements pri nette
tak som spravil tie select boxy podľa toho návodu na pla.nette ..

enumag
Člen | 2118
+
0
-

Můžeš upřesnit jakou chybu ti composer při instalaci házel? S tím doplňkem je to opravdu mnohem jednodušší. (Proto jsem jej v prvé řadě kdysi napsal.)

Editoval enumag (6. 2. 2016 10:49)

majo1
Člen | 103
+
0
-

zasielam moj vypis z cmd

`Microsoft Windows [Version 6.1.7601]
Copyright © 2009 Microsoft Corporation. Všetky práva vyhradené.

C:\Users\majo>cd c:\xampp\htdocs\nitransnetteproject

c:\xampp\htdocs\nitransnetteproject>composer require nasext/dependent-select-box

Using version ^2.1 for nasext/dependent-select-box
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
 – nette/nette v2.3.5 requires nette/application 2.3.5 → no matching package
found.
 – nette/nette v2.3.4 requires nette/application 2.3.4 → no matching package
found.
 – nette/nette v2.3.3 requires nette/application 2.3.3 → no matching package
found.
 – nette/nette v2.3.2 requires nette/application 2.3.3 → no matching package
found.
 – nette/nette v2.3.1 requires nette/application 2.3.2 → no matching package
found.
 – nette/nette v2.3.0 requires nette/application 2.3.1 → no matching package
found.
 – nette/nette v2.2.9 requires nette/application 2.2.6 → no matching package
found.
 – nette/nette v2.2.8 requires latte/latte 2.2.5 → no matching package found
.
 – nette/nette v2.2.7 requires nette/application 2.2.4 → no matching package
found.
 – nette/nette v2.2.6 requires nette/application 2.2.3 → no matching package
found.
 – nette/nette v2.2.5 requires nette/application 2.2.3 → no matching package
found.
 – nette/nette v2.2.4 requires nette/application 2.2.3 → no matching package
found.
 – nette/nette v2.2.3 requires nette/application 2.2.2 → no matching package
found.
 – nette/nette v2.2.2 requires nette/application 2.2.1 → no matching package
found.
 – nette/nette v2.2.12 requires nette/application 2.2.9 → no matching packag
e found.
 – nette/nette v2.2.11 requires nette/application 2.2.8 → no matching packag
e found.
 – nette/nette v2.2.10 requires nette/application 2.2.7 → no matching packag
e found.
 – nette/nette v2.2.1 requires nette/application 2.2.0 → no matching package
found.
 – nette/nette v2.2.0 requires nette/application 2.2.0 → no matching package
found.
 – Installation request for nasext/dependent-select-box ^2.1 → satisfiable b
y nasext/dependent-select-box[v2.1.0].
 – Conclusion: remove nette/application v2.3.9
 – Conclusion: don't install nette/application v2.3.9
 – nasext/dependent-select-box v2.1.0 requires nette/nette @dev → satisfiabl
e by nette/nette[v2.1.10, v2.1.11, v2.1.12, v2.1.9, v2.0.10, v2.0.11, v2.0.12, v
2.0.13, v2.0.14, v2.0.15, v2.0.16, v2.0.17, v2.0.18, v2.0.2, v2.0.3, v2.0.4, v2.
0.5, v2.0.6, v2.0.7, v2.0.8, v2.0.9, v2.1.0, v2.1.1, v2.1.2, v2.1.3, v2.1.4, v2.
1.5, v2.1.6, v2.1.7, v2.1.8, v2.2.0, v2.2.1, v2.2.10, v2.2.11, v2.2.12, v2.2.2,
v2.2.3, v2.2.4, v2.2.5, v2.2.6, v2.2.7, v2.2.8, v2.2.9, v2.3.0, v2.3.1, v2.3.2,
v2.3.3, v2.3.4, v2.3.5, v2.3.6, v2.3.7, v2.3.8].
 – nette/nette v2.3.6 requires nette/application 2.3.6 → satisfiable by nett
e/application[v2.3.6].
 – nette/nette v2.3.7 requires nette/application 2.3.7 → satisfiable by nett
e/application[v2.3.7].
 – nette/nette v2.3.8 requires nette/application 2.3.8 → satisfiable by nett
e/application[v2.3.8].
 – Can only install one of: nette/application[v2.3.6, v2.3.9].
 – Can only install one of: nette/application[v2.3.7, v2.3.9].
 – Can only install one of: nette/application[v2.3.8, v2.3.9].
 – nette/nette v2.0.10 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.11 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.12 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.13 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.14 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.15 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.16 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.17 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.18 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.2 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.3 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.4 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.5 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.6 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.7 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.8 conflicts with nette/application[v2.3.9].
 – nette/nette v2.0.9 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.0 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.1 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.10 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.11 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.12 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.2 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.3 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.4 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.5 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.6 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.7 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.8 conflicts with nette/application[v2.3.9].
 – nette/nette v2.1.9 conflicts with nette/application[v2.3.9].
 – Installation request for nette/application == 2.3.9.0 → satisfiable by ne
tte/application[v2.3.9].

Potential causes
A typo in the package name
The package is not available in a stable-enough version according to your min

imum-stability setting
see <https://groups.google.com/…c/discussion> f
or more details.

Read <https://getcomposer.org/…eshooting.md> for further commo
n problems.

Installation failed, reverting ./composer.json to its original content.

c:\xampp\htdocs\nitransnetteproject>`

enumag
Člen | 2118
+
+1
-

Jo, myslel jsem si že to bude v tomhle. Tenhle commit by to měl fixnout – zkus dev-master a dej vědět zda to funguje. Díky.

majo1
Člen | 103
+
0
-

akym prikazom mam nainstalovat dev-master? :)

enumag
Člen | 2118
+
0
-

V composer.json máš někde řádek:

"nasext/dependent-select-box": "^2.1"

(případně s jiným číslem verze).

Uprav to na

"nasext/dependent-select-box": "dev-master"

a pak composer update.

Editoval enumag (6. 2. 2016 16:52)

majo1
Člen | 103
+
0
-

ahoj :)
podarilo sa mi ten doplnok nainstalovat, no teraz pozeram Usage – a tie dependboxy su riesene tak trocha staticky.

ja potrebujem tahat moznosti do select boxov z databazy, kdezto v tvojom pripade sa rucne definuju:

$form->addDependentSelectBox('city', 'City', array($form["country"]), function ($values) use ($citySlovakia, $cityCzech, $cityUsa) {
            $data =  new \NasExt\Forms\Controls\DependentSelectBoxData();
            if ($values['country'] == 1) {
                return $data->setItems($citySlovakia);
            } elseif ($values['country'] == 2) {
                return $data->setItems($cityCzech);
            } elseif ($values['country'] == 3) {
                return $data->setItems($cityUsa);
            } else {
                return $data;
            }
        })->setPrompt('- Select -');

ci? :)

ja to potrebujem spravit tak, ze ked niekto cez administraciu prida „zastavku“, tak sa automaticky zobrazi aj v select boxe v tomto formulari dostupnom pre navstevnika stranky.

Editoval majo1 (7. 2. 2016 14:45)

CZechBoY
Člen | 3608
+
0
-

Vsak si ty informace sezen kde chces (treba v db, konfiguraku, najdi na google, …). Jen pro jednoduchost je v ukazce pole predvyplnene ukazkovymi daty.

enumag
Člen | 2118
+
0
-

To je jen example, tu callback funkci si samozřejmě implementuješ dle potřeby.

majo1
Člen | 103
+
0
-

chapem, ja teraz aj vyplnam pole udajmi z db, ale
nemozem vediet, aky udaj pribudne v buducnosti v tabulke a ako ho budem musiet zapodmienkovat vo addDependentSelectBox :)

viac ma laka opravit aktualny formular, ktory som robil cez pla.nette, kedze zavislost selectboxov funguje,
potrebujem len vyriesit

  • aby sa nenacitalo @layout.latte
  • chybu Trying to get property of non-object
public function saveReservationform($reservationform)
25:        {
26:            $this->database->beginTransaction();
27:                $idcust = $this->database->table("customers")->insert($reservationform->custdetail)->idcustomer; // chybu hlasi tracy pri tomto riadku
28:                $reservationform->resdetail->customer_idcustomer = $idcust;
29:                $this->database->table("reservations")->insert($reservationform->resdetail);
30:            $this->database->commit();
31:        }

dakujem :)

majo1
Člen | 103
+
0
-

Práve som vyriešil 1. problém, použil som v latte {layout "../@layoutForm.latte"}
Ešte sa musím potrápiť s tým nahrávaním hodnôt do DB.

Prosím Vás, nemáte nejaký tip, ako to vyriešiť?

premek_k
Člen | 172
+
0
-

Znovu: Myslím, že by sis měl projít alespoň dokumentaci, abys měl aspoň trochu přehled. Copy&paste programování bez znalosti základů nikam nepovede…

Pokud to přesto chceš zkusit, tak zkus takto:

<?php
	$row = $this->database->table("customers")->insert($reservationform->custdetail);
	$idcust = $row->idcustomer;
?>

Editoval premek_k (7. 2. 2016 17:27)

majo1
Člen | 103
+
0
-

@premek_k Ja myslím, že som niekde spravil nedopatrením chybu, ktorú neviem nájsť, možno ju prehliadam.
Keď píšeš komentár odkazujúci k dokumentácií, možno by bolo užitočné ma aj naviesť na nejakú konkrétnu dokumentáciu :)

premek_k
Člen | 172
+
0
-

JJ, @majo1, promiň, tady to je: https://doc.nette.org/cs/

majo1
Člen | 103
+
0
-

dakujem,
no opat vracia Trying to get property of non-object z riadku $row = $this->database->table(„customers“)->insert($reservationform->custdetail);

sranda je ta, ze ked som vo formulari nemal tie od seba zavisle select boxy (teda ani $values = $form->getHttpData(); pri ukladani formulara), tak to pekne fungovalo..

majo1
Člen | 103
+
0
-

pri vytahovani hodnot z formularu som skusil aj nieco ako:

$values = $form->getHttpData($form::DATA_LINE | $form::DATA_KEYS, ‚resdetail[]‘);

ale ta ista chyba.. :/

premek_k
Člen | 172
+
0
-

A máš tam vůbec dobře injectnutou tu $this->database? To, že by ten insert měl být v modelu teď neřešme…

Co ti vrátí dump($this->database);?

majo1
Člen | 103
+
0
-

v baseManager

    protected $database;

    public function __construct(Context $database)
    {
        $this->database = $database;
    }

insert mam v modeli…

dump mi nic nevrati, len tracy oznamuje chybu, aj barDump som skusal.

majo1
Člen | 103
+
0
-

pre upresnenie,

toto je moj model

<?php

namespace App\Model;

use App\Model\BaseManager;
use Nette\Database\Table\IRow;
use Nette\Database\Table\Selection;
use Nette\Utils\ArrayHash;

class ReservationformManager extends BaseManager
{
    const
            TABLE_NAME = 'reservations',
            COLUMN_ID = 'idreservation',
        CUSTOMERSTABLE_NAME = 'customers',
        CUSTOMERSCOLUMN_ID = 'idcustomer',
            SKIBUSTABLE_NAME = 'skibuses',
            SKIBUSCOLUMN_ID = 'idskibus',
        STATIONTABLE_NAME = 'stations',
        STATIONCOLUMN_ID = 'idstation',
            CENTERTABLE_NAME = 'centers',
            CENTERCOLUMN_ID = 'idcenter';





    public function saveReservationform($reservationform)
    {
        $this->database->beginTransaction();

            //$idcust = $this->database->table("customers")->insert($reservationform->custdetail)->idcustomer;
            $row = $this->database->table("customers")->insert($reservationform->custdetail);
            $idcust = $row->idcustomer;

            $reservationform->resdetail->customer_idcustomer = $idcust;
            $this->database->table("reservations")->insert($reservationform->resdetail);

        $this->database->commit();
    }





    public function getCenter()
    {
        return $this->database->table(self::CENTERTABLE_NAME)->order(self::CENTERCOLUMN_ID . ' ASC');
    }

    public function getStation()
    {
        return $this->database->table(self::STATIONTABLE_NAME)->order(self::STATIONCOLUMN_ID . ' ASC');
    }

    public function getStationSel($value)
    {
        return $this->database->table(self::STATIONTABLE_NAME)->order(self::STATIONCOLUMN_ID . ' DESC')->where('center_idcenter = ?', $value);
        //return $this->database->table(self::STATIONTABLE_NAME)->select('CONCAT(city,departureTime) AS spojenyCasMesto')->order(self::STATIONCOLUMN_ID . ' DESC')->where('center_idcenter = ?', $value);
    }

    public function getSkibus()
    {
        return $this->database->table(self::SKIBUSTABLE_NAME)->order(self::SKIBUSCOLUMN_ID . ' DESC')->limit(10);
    }

    public function getSkibusSel($value)
    {
        return $this->database->table(self::SKIBUSTABLE_NAME)->order(self::SKIBUSCOLUMN_ID . ' DESC')->limit(10)->where('centers_idcenter = ?', $value);
    }
}

toto presenter

<?php

namespace App\Presenters;

use App\Model\ReservationformManager;
use App\Presenters\BasePresenter;
use Nette\Application\BadRequestException;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
use Nette\Database\UniqueConstraintViolationException;
use Tracy\Debugger;

Debugger::enable();


class ReservationformPresenter extends BasePresenter
{
    private static $ziskaneIdCentra;

    protected $reservationformManager;


    public function __construct(ReservationformManager $reservationformManager)
    {
        parent::__construct();
        $this->reservationformManager = $reservationformManager;
    }

    public function renderDefault()
    {
        $this->template->_form = $this['reservationForm'];
    }

    public function handleFirstChange($value)
    {
        if ($value) {
            $resultSk = $this->reservationformManager->getSkibusSel($value);
            $secondItems = $resultSk->fetchPairs('idskibus', 'departureDatetime');

            $this['reservationForm']['resdetail-skibus_idskibus']->setPrompt('-- vyberte --')
                ->setItems($secondItems);

            $resultSt = $this->reservationformManager->getStationSel($value); //$ziskaneIdCentra

            $thirdItems = $resultSt->fetchPairs('idstation', 'city'); //city spojit s casom

            $this['reservationForm']['resdetail-station_idstation']->setPrompt('-- vyberte --')
                ->setItems($thirdItems);

        } else {
            $this['reservationForm']['resdetail-skibus_idskibus']->setPrompt('-- vyberte najskôr stredisko --')
                ->setItems(array());

            $this['reservationForm']['resdetail-station_idstation']->setPrompt('-- vyberte najskôr stredisko --')
                ->setItems(array());
        }

        $this->invalidateControl('secondSnippet');
    }

    public function handleSecondChange($value)
    {
        if ($value) {
            $resultSt = $this->reservationformManager->getStationSel(); //$ziskaneIdCentra

            $thirdItems = $resultSt->fetchPairs('idstation', 'city'); //city spojit s casom

            $this['reservationForm']['resdetail-station_idstation']->setPrompt('-- vyberte --')
                ->setItems($thirdItems);

        } else {
            $this['reservationForm']['resdetail-station_idstation']->setPrompt('-- najskôr vyberte skibus --')
                ->setItems(array());
        }

        $this->invalidateControl('thirdSnippet');
    }

    protected function createComponentReservationForm()
    {

        $form = new Form;

        $sub1 = $form->addContainer('resdetail');
        $sub2 = $form->addContainer('custdetail');

        $sub1->addText('numAdult', 'Počet dospelých:')
            ->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
            ->setDefaultValue('0')
            ->setType('number')->setRequired();
        $sub1->addText('numJunior', 'Počet juniorov:')
            ->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
            ->setDefaultValue('0')
            ->setType('number')->setRequired();
        $sub1->addText('numKid', 'Počet detí:')
            ->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
            ->setDefaultValue('0')
            ->setType('number')->setRequired();
        $sub1->addText('numTransportOnly', 'Len doprava:')
            ->addRule(Form::RANGE, 'Musí byť v rozsahu %d až %d', array(0, 100))
            ->setDefaultValue('0')
            ->setType('number')->setRequired();

        $resultCe = $this->reservationformManager->getCenter();
        $firstItems = $resultCe->fetchPairs('idcenter', 'centerName');


        $sub1->addSelect('center_idcenter', 'Stredisko: ', $firstItems)
            ->setPrompt('-- vyberte --');
        $sub1->addSelect('skibus_idskibus', 'Skibus - termín: ')
            ->setPrompt('-- vyberte najskôr stredisko--');
        $sub1->addSelect('station_idstation', 'Zastávka: ')
            ->setPrompt('-- vyberte najskôr stredisko--');

        $sub2->addText('name', 'Meno:')
            ->setType('text')->setRequired();
        $sub2->addText('surename', 'Priezvisko:')
            ->setType('text')->setRequired();
        $sub2->addText('telephone', 'Telefónne číslo:')
            ->setType('text')->setRequired();
        $sub2->addText('email', 'E-mail:');

        $form->addProtection('Váš časový limit vypršal. Odošlite prosím formulár znovu.');

        $form->addSubmit('submit', 'Rezervovať skibus');
        $form->onSuccess[] = [$this, 'editorFormSucceeded'];

        return $form;
    }

    public function editorFormSucceeded($form, $values)
    {
        try {
            $values = $form->getHttpData($form::DATA_LINE | $form::DATA_KEYS, 'resdetail[]');
            //$values = $form->getHttpData();
            Debugger::barDump($values, 'values insert');
            $this->reservationformManager->saveReservationform($values);
            $this->flashMessage('Rezervácia bola úspešne odoslaná. Ďakujeme.');
            //$this->redirect(':Reservationform:', $values->idreservation);
        } catch (UniqueConstraintViolationException $ex) {
            $this->flashMessage('Rezervácia s týmto ID už existuje!');
        }
    }
}

ali
Člen | 342
+
0
-

Kdyz uz pises ze ti dump nic nevraci je hodne podezrele, musi ti vyhodit aspon NULL, zkus tohle:

protected $database;

public function __construct(Context $database)
{
	dump($database);
    $this->database = $database;
}
majo1
Člen | 103
+
0
-

vymazal som cache a skusil som spravit nasl.:

abstract class BaseManager extends Object
{
protected $database;

public function __construct(Context $database)
{
dump($this->database);
$this->database = $database;
 }
}

a tracy pise Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.

ked dam Skip error, tak napise navrchu stranky (pravdepodobne dump): „null“

premek_k
Člen | 172
+
0
-

Máš v tom guláš, vůbec nerozumíš struktuře.

Pokud nikdo, tak ráno odpovím, už jsem v posteli

majo1
Člen | 103
+
0
-

skúšal som už všeličo.., pretože dump mi nič nevracal

premek_k
Člen | 172
+
+2
-

Nejdříve se omlouvám za mé poslední tvrzení, že v tom máš guláš – přehlídl jsem se a neprávem tě osočil. Beru to zpět.

Jinak v metodě editorFormSucceeded vrať zpět tu konstrukci $values = $form->getHttpData();.
Takto bude ve $values array hodnot z formuláře, struktura je vidět v některém z předchozích tvých příspěvků.

Do modelu do saveReservationForm tedy předáváš array, proto s tím musíš i takto pracovat. Třeba takto (když tak si uprav názvy klíčů toho pole, nevím, jak to tam máš přesně):

<?php
    public function saveReservationform($reservationformValues)
    {
        $this->database->beginTransaction();
        $row = $this->database->table("customers")->insert($reservationformValues['custdetail']);
		if (!$row){
			$this->database->rollback();
			return FALSE;
		}

		$reservationformValues['resdetail']['customer_idcustomer'] = $row->idcustomer;
		$row = $this->database->table("reservations")->insert($reservationformValues['resdetail']);
		if (!$row){
			$this->database->rollback();
			return FALSE;
		}
        $this->database->commit();
		return TRUE;
    }
?>

Takto by to mělo fungovat. Snad mi něco neuniká, nejsem taky žádný guru, jen se snažím pomoct.

majo1
Člen | 103
+
+1
-

Ďakujem za ochotu a za pomoc, už mi to je jasné a funguje to ako má :)

majo1
Člen | 103
+
0
-

@premek_k prosím ťa, vedel by si mi ešte poradiť,
ako pri inserte $reservationformValues[‚custdetail‘] očekovať, či už v tabuľke je daný e-mail a ak je, tak spraviť iba update?

normálne by som použil ON DUPLICATE KEY UPDATE ale klientov som začal ukladať zo začiatku cez primary key idcustomer, čo je INT inkrementálne. Mal som použiť ako PK nejaký jedinečný údaj ako e-mail.. :/

už to asi pôjde ťažko zmeniť :)

Ďakujem

premek_k
Člen | 172
+
0
-

Jednoduše nějak takto:

    public function saveReservationform($reservationformValues)
    {
        $this->database->beginTransaction();
		$row = $this->database->table("customers")->where(['email'=> $reservationformValues['custdetail']['email']])->fetch();
 		if (!$row) {
        	$row = $this->database->table("customers")->insert($reservationformValues['custdetail']);
		}
        if (!$row){
            $this->database->rollback();
            return FALSE;
        }
		:
		:
		:

    }
mates
Člen | 36
+
0
-

premek_k napsal(a):

$this->database->beginTransaction();
$row = $this->database->table(„customers“)->where([‚email‘⇒ $reservationformValues[‚custdetail‘][‚email‘]])->fetch();
if (!$row) {
$row = $this->database->table(„customers“)->insert($reservationformValues[‚custdetail‘]);
}

@premek_k Zajistí ta transakce, že mezi těmi dvěmi příkazy nikdo nevloží nový záznam do tabulky customers? Resp. tabulka customers se v transakci čtením zamkne pro zápis? Standardně, nebo se to tak musí nastavit?

premek_k
Člen | 172
+
0
-

Podle mě se to chová dle aktuálního nastavení mysql, ale jistý si nejsem.