Ajax form – jak vykonat JS po úspěšném submit?

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

Ahoj,
mám ajax formulář, který se zobrazuje v modálním dialogu. Po úspěšném potvrzení formuláře bych chtěl tento dialog zavřít javascriptem. Jaké mám možnosti? Javascriptový onsubmit mi nestačí, protože to ještě nevím, jestli jsou data ve formu validní.
Předem díky za rady.

Editoval dreken (11. 10. 2014 11:07)

enumag
Člen | 2118
+
+1
-

Budeš muset celý formulář odesílat ajaxem a podívat se co ti server vrátí.

SvvimX
Člen | 65
+
0
-

Používám to tak, že mám presenter, který má formulář a metodu pro zpracování, v šabloně je jen ten formulář (bez layoutu).

Ajaxově načítám tendle presenter do modal okna – a odesílám ho ajaxem. Při chybě ve formuláři ti server vrátí 200 OK a normálně HTML ze šablony – kde je formulář s daty a errory – tím nahradíš obsah modal okna.

Při správném odeslání mi server vrátí redirect (protože po úspěšném odeslání presenter přesmeruje), což v JS odchytíš a zavřeš modal okno. Pokud by to nebylo JS, tak se přesměruje, na tu správnou stránku, což je takový bonus.

Další chyby a jejich kódy si v tom presenteru můžeš doimplementovat a reagovat si na ně dle libosti.

steelbull
Člen | 241
+
0
-

Veeeeelmi pekne prosim, nenasiel by sa nejaky funkcny priklad, na ktory by som mohol pouzit?

Dakujem.

SvvimX
Člen | 65
+
0
-

Celý příklad asi není ani potřeba, mít presetner a formulář je snad jasné. Javascript, který toto dělá:

		$.ajax({
    type: "POST",
    url: $(this).attr("action"),
    data: $(this).serialize(), // serializes the form's elements.
    success: function(data)
    {
        if (data.redirect) {
            window.location.href=data.redirect; // presmeruje, zde si muzes zavrit modal okno a nekam napsat, ze je to OK
        }
        else {
            $("#Modal-addItemToIndex").find(".modal-content").html(data); // zmena obsahu modal okna, protoze nedoslo k redirectu, tedy ve formu byly chyby
        }
    }
});
steelbull
Člen | 241
+
0
-

SvvimX: velmi pekne dakujem za odpoved

…a ked mam viacero formularov na jednej stranke? Data si z formulara odoslem, ale ako ich mam v presenteri prijat, resp. ako zistim, ze data ktoreho formulara boli odoslane?

SvvimX
Člen | 65
+
0
-

https://doc.nette.org/cs/forms#… $form->onSuccess[] – jiná metoda pro každý formulář

steelbull
Člen | 241
+
0
-

Priklad:

Formular:

class LrProjectFormFactory {

    private $context;
    private $translator;



    /**
     * Load database context
     */
    function __construct($context, $translator) {
	$this->context = $context;
	$this->translator = $translator;
    }



    /**
     * Create form
     */
    function create($data = NULL) {

	// Create new instance
	$form = new Form();

	$form->method = 'post';
	$form->getElementPrototype()->addAttributes(array('id' => 'lrProjectForm'));

	$form->addText('pdts_number', $this->translator->translate('lr_projects.form.pdts_number').':')
		->setAttribute('class', 'form-control')
		->setDefaultValue(($data == NULL) ? NULL : $data->pdts_number)
		->setRequired($this->translator->translate('lr_projects.form.please_insert_the_pdts_number'));

	$form->addText('title', $this->translator->translate('lr_projects.form.title').':')
		->setAttribute('class', 'form-control')
		->setDefaultValue(($data == NULL) ? NULL : $data->title)
		->setRequired($this->translator->translate('lr_projects.form.please_insert_the_title'));

	$form->addText('description', $this->translator->translate('lr_projects.form.description').':')
		->setAttribute('class', 'form-control')
		->setDefaultValue(($data == NULL) ? NULL : $data->description);

	$form->addHidden('id')
		->setDefaultValue(($data == NULL) ? NULL : $data->id);

	$form->addProtection();

	// Validate form
	$form->onValidate[] = function($form) {
	    $projectsModel = new Model\ProjectsModel($this->context);
	    $data = $form->getValues();

	    // Check, if project exists
	    if ($projectsModel->checkUnique($data)) {
		$form['pdts_number']->addError($this->translator->translate('lr_projects.form.pdts_number_error_unique'));
	    }
	};

	return $form;
    }

}

Presenter:

class LrPresenter extends BaseSecuredPresenter {


    /**
     * Render add view for create and save new labRequest
     */
    public function renderAdd() {

        //Call function to RenderForm
        $form = (new LrFormFactory($this->context, $this->translator))->create();
        $typeForm = (new LrTypeFormFactory($this->context, $this->translator))->create();

        //Takto riesim defaultny formular, ale neviem com mam robit s
        if ($form->isSuccess()) {
            $model = new Model\LabRequestsModel($this->context);
            $data = $form->getValues();

            // Try to save data
            try {
                $model->saveLabRequest($data);
                $this->flashMessage($this->translator->translate('flash.record_was_saved'), 'success');
                $this->redirect('Lr:default');
            } catch (\PDOException $e) {
                $this->flashMessage($this->translator->translate('flash.error_while_saving_record'), 'danger');
                $this->redirect('Lr:default');
            }
        }

        // Load WuModel Form
        $formWuModel = (new WuModelFormFactory($this->context, $this->translator))->create();

        //Send data to form
        $this->template->form = $form;
         $this->template->typeForm = $typeForm;
    }

AJAX:

$(document).ready(function () {

    $('button.form-submit').each(function () {
        $(this).click(function () {
            var target = $(this).attr('form-target');

            $('form#' + target).submit(function (event) {
                event.preventDefault();
                var $this = $(this);
                var url = $this.attr('action');
                var dataToSend = $this.serialize();
                var posting = $.post(url, dataToSend);
                posting.done(function (data) {
                    $('div.data').append(data);
                });

            });
        });
    });

});

Skoncil som na tom, ze neviem, kam mam data odoslat a taktiez neviem, ako ich v Nette prijat. Ale mozno ze povies, ze je to cele zle :(

akadlec
Člen | 1326
+
0
-

Špatně pracuješ s formulářem, nezpracováváš jej v eventu ale vlastním způsobem. Podívej se do dokumentace jak se pracuje s formuláři.

steelbull
Člen | 241
+
0
-

Urobil som to, ako ste mi poradili, ale narazil som na problem. Ako customizovat formular ako komponent? Da sa to?

Editoval steelbull (5. 11. 2014 17:25)

steelbull
Člen | 241
+
0
-

SvvimX: takže prerobil som všetko podľa Teba, je to skutočne podstatne lepšie, ale: stále to neviem zajaxovať:

Form:

/**
 * Create form
 */
public function create($data = NULL) {

    // Create new instance
    $form = new UI\Form;

    // Form data
    $form->method = 'post';

    $form->getElementPrototype()->addAttributes(array('id' => 'lrTypeForm'));
    $form->getElementPrototype()->addAttributes(array('class' => 'ajax'));

    $form->addText('title', $this->translator->translate('lr_types.form.title') . ':')
            ->setAttribute('class', 'form-control')
            ->setDefaultValue(($data == NULL) ? NULL : $data->title)
            ->setRequired($this->translator->translate('lr_types.form.title'));

    $form->addText('description', $this->translator->translate('lr_types.form.description') . ':')
            ->setAttribute('class', 'form-control')
            ->setDefaultValue(($data == NULL) ? NULL : $data->description);

    $form->addHidden('id')
            ->setDefaultValue(($data == NULL) ? NULL : $data->id);

    $form->addSubmit('pokus');

    $form->addProtection();

    $form->onSuccess[] = array($this->instance, $this->callback);

    return $form;
}

Presenter:

/**
  * LrTypeForm create
  *
  * @return type
  */
 public function createComponentLrtypeform() {
     $form = (new LrTypeFormFactory($this, 'LrTypeFormSuccess', $this->context, $this->translator))->create();
     return $form;
 }



 /**
  * LrTypeForm Success
  *
  * @param Form $form
  */
 public function lrTypeFormSuccess(Form $form) {

     $model = new Model\LrTypesModel($this->context);

     $data = $form->getValues();

     try {
         $model->saveLrType($data);
         $this->flashMessage($this->translator->translate('flash.record_was_saved'), 'success');
     } catch (\PDOException $e) {
         $this->flashMessage($this->translator->translate('flash.error_while_saving_record'), 'danger');
     }
     $this->redirect('this');
 }

Latte:

<div class="modal fade" id="addTypeModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">{_cp.close}</span></button>
                <h4 class="modal-title" id="myModalLabel">{_lr.modals.create_lr_type}</h4>
            </div>
            <div class="modal-body">
                {control lrtypeform}
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">{_cp.cancel}</button>
                <button type="button" class="btn btn-primary form-submit" form-target="lrTypeForm">{_cp.save}</button>
            </div>
        </div>
    </div>
</div>

a do layout.latte som vlozil:

$.ajax({
    type: "POST",
    url: $(this).attr("action"),
    data: $(this).serialize(), // serializes the form's elements.
    success: function(data)
    {
        if (data.redirect) {
            window.location.href=data.redirect; // presmeruje, zde si muzes zavrit modal okno a nekam napsat, ze je to OK
        }
        else {
            $("#Modal-addItemToIndex").find(".modal-content").html(data); // zmena obsahu modal okna, protoze nedoslo k redirectu, tedy ve formu byly chyby
        }
    }
});

Editoval steelbull (5. 11. 2014 20:08)

akadlec
Člen | 1326
+
0
-

Stále ten form vytváříš špatně, předávání těch dat v konstruktoru formu je dost nepochopitelné a pokud to chceš řešit takto tak šáhni po továrničce.

Z toho ajaxu ti nefunguje konkrétně co?