Více tlačítek u formuláře

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

Dobrý den,
může mě někdo napsat, jak v ajaxu rozpoznat kterým tlačítkem byl formulář odeslaný?
Například jednoduchý formulář:

protected function createComponentAjaxForm()
{
    $form = new Form();
    $form->addText('txt', 'txt:', 20, 20)
        ->addRule($form::FILLED, '%label musí být zadaný.<br />');
    $form->addSubmit('ano', 'Ano');
    $form->addSubmit('ne', 'Ne');
    // název a oddělení jsem odstranil
    $form->onSuccess[] = callback($this, 'ajaxFormSubmitted');
    $form->getElementPrototype()->class("ajax");
    return $form;
}

public function ajaxFormSubmitted(Form $form)
{
    try {
        $values = $form->getValues();
        $this->flashMessage('Info |'.Rand(1,1000)."|", 'success');
        Debugger::FireLog("odeslán formulář");

        // isSubmittedBy zde nejde... (v ajaxu)
        if($this->isAjax()) {
            $this->invalidateControl('testHodnota');
            $this->invalidateControl('flash');
        } else {
            $this->redirect('this');
        }
    } catch (IOException $e) {
        $form->addError($e->getMessage());
    }
}

Šablona:

{block content}
{snippet testHodnota}
{$ajaxHodnota}
{/snippet}
{control ajaxForm}
{/block}

Render:

public function renderAjax(){
    $this->template->ajaxHodnota = Rand(1,1000);
}

Na zajaxování mám:
jquery-ajax, jquery.ajaxform.js s dodáním:

		....
		// submit button
		if (this.is(":submit")) {
			form = this.parents("form");
			sendValues[this.attr("name")] = this.val() || "";
// dodáno 1.6.2012
this.get(0).form["nette-submittedBy"] = this.get(0); //tohle přidat

		// form
		}...

Tady na fóru každý jen napíše, že to nějak dořešil, ale ani v kuchařce, nebo jak to udělat pro laika jsem se nikde nedočetl…

Editoval tatyalien (8. 6. 2012 8:23)

Vojtěch Dobeš
Gold Partner | 1316
+
+1
-
$form->submitted->name;
tatyalien
Člen | 239
+
0
-

To mě hodí ve firelogu:
Trying to get property of non-object in …\app\presenters\TestPresenter.php:336, zde přistupuji zrovna k $form->submitted->name…

fr
Člen | 8
+
0
-

a co $form->isSubmitted()->name ?

tatyalien
Člen | 239
+
0
-

To už jsem taky zkoušel, stejný výsledek… „Trying to get property of non-object…“

Ot@s
Backer | 476
+
0
-

tatyalien napsal(a):

To už jsem taky zkoušel, stejný výsledek… „Trying to get property of non-object…“

A používáš $form->submitted->name v ajaxFormSubmitted, že?

fr
Člen | 8
+
0
-

ve Vrtak-CZ-nette-doctrine-sandbox-7672583 to funguje (Nette 2.0-dev released on 2012–02–03, PHP 5.3)

tatyalien
Člen | 239
+
0
-

JJ, moje verze je Nette Framework 2.0.3

public function ajaxFormSubmitted(Form $form)
{
    try {
        $values = $form->getValues();
        $this->flashMessage('Info |'.Rand(1,1000)."|", 'success');
        // nefunguje:
        // Debugger::FireLog($form->submitted->name);
        // Debugger::FireLog($form->submitted->name());
        // Debugger::FireLog($form->isSubmitted()->name);


        if($this->isAjax()) {
            $this->invalidateControl('testHodnota');
            $this->invalidateControl('flash');
        } else {
            $this->redirect('this');
        }
    } catch (IOException $e) {
        $form->addError($e->getMessage());
    }
}
Foowie
Člen | 269
+
0
-
tatyalien
Člen | 239
+
0
-

To jsem zkoušel, ale neodesílalo se mě nic ajaxově, možná dělám něco blbě…
měl jsem:

protected function createComponentAjaxForm()
{
    $form = new Form();
    $form->addText('txt', 'txt:', 20, 20)
        ->addRule($form::FILLED, '%label musí být zadaný.<br />');
    //$form->addSubmit('ano', 'Ano';
    //$form->addSubmit('ne', 'Ne');


    $form->addSubmit('ano', 'Ano')->onClick[] = callback($this, 'ajaxAno');
    $form->addSubmit('ne', 'Ne')->onClick[] = callback($this, 'ajaxNe');
    // název a oddělení jsem odstranil
    //$form->onSuccess[] = callback($this, 'ajaxFormSubmitted');
    $form->getElementPrototype()->class("ajax");
    return $form;
}

k tomu zpracování ajaxAno, ajaxNe, ale neprovedlo se.

Nemůže prosím někdo uploudnout řešení, které funguje, ať se můžu podívat, jak to tedy rozjet?

Ascaria
Člen | 187
+
0
-

Na straně javascriptu je potřeba namířit ajax ne na formulář, ale na jeho tlačítko:

$('#{!$form['send']->HtmlId}').ajaxSubmit();

TO se pak do odesílaného postu přidá a nette forms pak poznají, že to bylo odesláno ním.

// Finální odeslání formuláře
$form->onSuccess[] = array($this, 'recapitulationSubmited');

public function recapitulationSubmited(Form $form)
    {
    // Pokud to bylo potvrzené submitem send, zpracujeme validní formulář
    if($form['send']->isSubmittedBy())
    }

Editoval Ascaria (8. 6. 2012 13:00)

Foowie
Člen | 269
+
0
-
$form->addSubmit('ano', 'Ano')->onClick[] = callback($this, 'ajaxAno');
$form['ano']->getElementPrototype()->class("ajax");
tatyalien
Člen | 239
+
0
-

Fowie:

//
//$form['ano']->getElementPrototype()->class("ajax"); je pouze na celej formulář, správně to je:
//$form['ano']->setAttribute('class', 'ajax');

        $form->addSubmit('ne', 'Ne')->onClick[] = callback($this, 'ajaxNe');
        $form->addSubmit('ano', 'Ano')->onClick[] = callback($this, 'ajaxAno');
        $form['ano']->setAttribute('class', 'ajax');
        $form['ne']->setAttribute('class', 'ajax');

kde jsem si musel pak opravit

public function ajaxAno(SubmitButton $button)
{
    try {
        // načtení hodnot dodáním getForm()
        $values = $button->getForm()->getValues();
        $this->flashMessage('Ano', 'success');
        //nedaří se mě zajaxovat tento formulář
        if($this->isAjax()) {
            $this->invalidateControl('testHodnota');
            $this->invalidateControl('flash');
        } else {
            $this->redirect('this');
        }
    } catch (IOException $e) {
        $form->addError($e->getMessage());
    }
}

Ale stejně se ajaxově neodešle.

Ascaria: Asi jsem natvrdlej, ale nevím kam přesně nacpat

$('#{!$form['send']->HtmlId}').ajaxSubmit();

Protože zajaxování mám:

<script type="text/javascript" charset="utf-8" n:syntax="off">
jQuery.ajaxSetup({
    cache: false,
    dataType: 'json',
    success: function (payload) {
        if (payload.snippets) {
            for (var i in payload.snippets) {
                $('#' + i).html(payload.snippets[i]);
            }
        }
    }
});
// odesílání odkazů
$('a.ajax').live('click', function (event) {
    event.preventDefault();
    $.get(this.href);
});

// odesílání formulářů
$('form.ajax').live('submit', function (event) {
    event.preventDefault();
    $.post(this.action, $(this).serialize());
});
</script>

Editoval tatyalien (8. 6. 2012 13:24)

Ascaria
Člen | 187
+
0
-

mohlo by fungovat

<script type="text/javascript" charset="utf-8" n:syntax="off">
// odesílání formulářů
$('form.ajax :submit').on('click', function(event) {
    event.preventDefault();
    $(this).ajaxSubmit();
});
</script>
tatyalien
Člen | 239
+
0
-

Vyřešeno
Ascaria: super!!! Díky moc, toto to vyřešilo ;)

Řešení:

protected function createComponentAjaxForm()
{
    $form = new Form();
    $form->addText('txt', 'txt:', 20, 20)
        ->addRule($form::FILLED, '%label musí být zadaný.<br />');
    $form->addSubmit('ano', 'Ano');
    $form->addSubmit('ne', 'Ne');
    // název a oddělení jsem odstranil
    $form->onSuccess[] = callback($this, 'ajaxFormSubmitted');
    $form->getElementPrototype()->class("ajax");
    return $form;
}
public function ajaxFormSubmitted(Form $form)
{
    try {
        $values = $form->getValues();
        $this->flashMessage('Info |'.Rand(1,1000)."|", 'success');
        $this->flashMessage('Funguje |'.$form->submitted->name."|", 'success');
        Debugger::FireLog($form->submitted->name);
        if($form['ano']->isSubmittedBy()) {
            Debugger::FireLog("ANO");
            $this->flashMessage('ano', 'success');
        }
        if($form['ne']->isSubmittedBy()) {
            Debugger::FireLog("NE");
            $this->flashMessage('ne', 'success');
        }
        //nedaří se mě zajaxovat tento formulář
        if($this->isAjax()) {
            $this->invalidateControl('testHodnota');
            $this->invalidateControl('flash');
            //$this->invalidateControl('testFormAjax');
            $form->setValues(array("txt"=>""));
        } else {
            $this->redirect('this');
        }
    } catch (IOException $e) {
        $form->addError($e->getMessage());
    }
}

A dodání:

<script type="text/javascript" charset="utf-8" n:syntax="off">
jQuery.ajaxSetup({
    cache: false,
    dataType: 'json',
    success: function (payload) {
        if (payload.snippets) {
            for (var i in payload.snippets) {
                $('#' + i).html(payload.snippets[i]);
            }
        }
    }
});
// odesílání odkazů + stránkování
$('a.ajax, .paginator a').live('click', function (event) {
    event.preventDefault();
    $.get(this.href);
});

// odesílání formulářů
$('form.ajax').live('submit', function (event) {
    event.preventDefault();
    $.post(this.action, $(this).serialize());
});

// Toto dodáno na rozpoznání tlačítka
$('form.ajax :submit').on('click', function(event) {
    event.preventDefault();
    $(this).ajaxSubmit();
});
</script>
bojovyletoun
Člen | 667
+
0
-

Případně jde použít javascriptová metoda click() na daném prvku.

Ascaria
Člen | 187
+
0
-

Jenom dodám jestě, že ten „form.ajax live submit“ neni potřeba když tam máš skript co napojuje tlačítka.

Dále pokud invaliduješ formulář a ajaxem ho refreshneš, je potřeba na něj zmíněný skript s „:submit“ navázat znovu a nette init taky. Ideálně při vkládání snippetů:

for (var i in payload.snippets) {
    $('#' + i).html(payload.snippets[i]);
    $('#' + i).find('form.ajax :submit').on('click', function(event) {
        event.preventDefault();
        $(this).ajaxSubmit();
    });
    $('#' + i).find('form').each(function() {
        Nette.initForm(this);
    });
}

Editoval Ascaria (8. 6. 2012 16:27)