Validace formuláře a ajax

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

Vytvářím si formulář s validačními pravidly a pro jeho odeslání používám:

<script>
$("form.ajax").live("submit", function () {
    $(this).ajaxSubmit(function (payload) {
      jQuery.nette.success(payload);
        if (payload.alert) {
         alert(payload.alert)
        }
    });
</script>

Vše funguje přesně podle mých představ až na jednu drobnost, validace proběhne dvakrát za sebou, to znamená, že se dvakrát za sebou zobrazí hláška o nesplnění validačního pravidla.
Co dělám špatně?
Díky. Standa

phx
Člen | 651
+
0
-

Neni problem v PHP casti – zkus to odladit bez JS.

Editoval phx (4. 10. 2010 14:59)

scerny
Člen | 25
+
0
-

Už jsem to našel, měl jsem na úplně jiném místě onoho template tento kód:

<script>
  $(":button").click(function(){
      $("#dialog").dialog("close");
});
</script>

Zajištuje zavření modálního okna, kde mám ten formulář. Musím to vyřešit nějak jinak, asi přímo v tom prvním scriptu.
Děkuju za nakopnutí, moc mi to pomohlo.

scerny
Člen | 25
+
0
-

Tak jsem se unáhlil :-(.
Ani odstranení uvedené části nepomohlo. Osekal jsem funkci ajaxového odesílání formu na absolutní minimum:

<script>
$("form.ajax").live("submit", function () {
 $(this).ajaxSubmit()
    return false;
});
</script>

Stále se validace provede dvakrát.

Když změním funkci na:

<script>
$("form.ajax :submit").live("click", function () {
..
</script>

tak se validuje správně jenom jednou, ale zase se form neodešle ajaxově, ale normálně. Podobný problém se řešil tady ,ale
mě se formulář odesílá správně jen jednou.

assassik
Člen | 43
+
0
-

možná to je jen chyba z kopírování, ale chybý tam pár závorek na konci

scerny
Člen | 25
+
0
-

assassik napsal(a):

možná to je jen chyba z kopírování, ale chybý tam pár závorek na konci

jj, to je jenom náznak prvního řádku, to měly naznačit ty tečky.

natrim
Člen | 73
+
0
-

pouzij neco takovedleho

<script>
  $("form.ajax").live('submit',function(){
        $("form.ajax :submit:first").click(); //zde dej co se ma zavolat za tlacitko pokud uzivatel odesle form jinak.. obcas se to stane
        return false;
    });

    $("form.ajax :submit").live('click',function(){
        $(this).ajaxSubmit();
        return false;
    });
</script>
scerny
Člen | 25
+
0
-

Při použití tohoto kódu proběhne validace opravdu jen jednou, ale zase se neprovede odeslání formuláře když jsou validace OK. Je to pravděpodobně proto, že se neprovede ajaxSubmit(). Už jsem otestoval desítky možností a ani jedna nebyla správná. Jsou tři možné výsledky, Buď se validuje dvakrát, nebo se neodešle form a ve třetím případě se odešle, ale ne jako Ajax. Chtěl jsem z Nette používat validace, protože si myslím, že jsou dobře udělané a bude mě mrzet když to nepůjde použít.

natrim
Člen | 73
+
0
-

Co používáš za verui nette? na 0.9.6 funguje tento ajaxsubmit správně.

<script>
jQuery.fn.extend({
    ajaxSubmit: function (callback) {
        var form;
        var sendValues = {};

        // submit button
        if (this.is(":submit")) {
            form = this.parents("form");
            sendValues[this.attr("name")] = this.val() || "";

        // form
        } else if (this.is("form")) {
            form = this;

        // invalid element, do nothing
        } else {
            return null;
        }



        // validation
        if (form.get(0).onsubmit && !form.get(0).onsubmit()) return null;
        if (this.is(":submit")) {
         if (this.get(0).onclick && !this.get(0).onclick()) return null;
        }

        // get values
        var values = form.serializeArray();

        for (var i = 0; i < values.length; i++) {
            var name = values[i].name;

            // multi
            if (name in sendValues) {
                var val = sendValues[name];

                if (!(val instanceof Array)) {
                    val = [val];
                }

                val.push(values[i].value);
                sendValues[name] = val;
            } else {
                sendValues[name] = values[i].value;
            }
        }

        // send ajax request
        var ajaxOptions = {
            url: form.attr("action"),
            data: sendValues,
            type: form.attr("method") || "get"
        };

        if (callback) {
            ajaxOptions.success = callback;
        }

        return jQuery.ajax(ajaxOptions);
    }
});
</script>

je to lehounce poupraveny standardni ajaxsubmit

Editoval natrim (6. 10. 2010 13:08)

scerny
Člen | 25
+
0
-

Používám NetteFramework-1.0dev-PHP5.2 z 11.5.2010
a ajaxSubmit

/**
* AJAX form plugin for jQuery
*
* @copyright Copyright © 2009 Jan Marek
* @license MIT
* @link http://nettephp.com/…as/ajax-form
* @version 0.1
 */

Nemáš k tomu kousek funkčního kódu?

Editoval scerny (6. 10. 2010 13:34)

scerny
Člen | 25
+
0
-

Zjistil jsem, že problém dvojitého upozornění validace se netýká IE, ale Firefoxu (v jiných prohlížečích jsem to zatím netestoval). To se to těžko optimalizuje :-(.

natrim
Člen | 73
+
0
-

kousek kodu uz jsem ukazoval

a tady je celej muj jquery.nette.js

jinak zkus nekam hodit kousek toho html a js ktere nefunguje a mrknu se jestli si tam neceho nevsimnu

scerny
Člen | 25
+
0
-

v presenteru vytvářím komponentu formu:

<?php
  function createComponentEditForm()
    {
    $groups = $this->servicesModel->readGroups();
    $dph_type = $this->servicesModel->readDPHType();

        $form = new AppForm();
        $form->getElementPrototype()->class('ajax');
        $form->addHidden('ID');
        $form->addText('Code', 'Kód: ', 10,10);
        $form->addText('Unit', 'Jednotka: ', 10,10);
        $form->addSelect('Group_ID', 'Skupina: ',$groups);
        $form->addText('Description', 'Popis: ', 50, 100)
            ->addRule(Form::FILLED, 'Zadejte prosím popis služby.');
        $form->addText('Price', 'Cena: ', 10)
            ->addRule(Form::FILLED, 'Zadejte prosím cenu služby.')
            ->addRule(Form::FLOAT, 'Cena musí být číslo.');
        $form->addSelect('DPH_ID', 'DPH: ',$dph_type);
        $form->addTextArea('Notes','Poznámky: ',80,3);
        $form->addButton('back', 'zpět');
        $form->addSubmit('save', 'uložit');
        $form->onSubmit[] = callback($this, 'saveFormSubmitted');
      return $form;
    }
?>

v template ji si vytvořím vlatní formulář (včetně záložek):

<div id="dialog" title="Editace záznamu">
 <div id="tabs">
     <ul>
        <li><a href="#tabs-1">Hlavní</a></li>
        <li><a href="#tabs-2">Další</a></li>
    </ul>
 {$form->render('begin')}
 <div id="tabs-1">
 <Table width="100%">
   <tr>
    <td>{$form['Code']->label}</td><td>{$form['Code']->control}</td>
    <td>{$form['Description']->label}</td><td>{$form['Description']->control}</td>
   </tr>
   <tr>
    <td>{$form['Unit']->label}</td><td>{$form['Unit']->control}</td>
    <td>{$form['Group_ID']->label}</td><td>{$form['Group_ID']->control}</td>
   </tr>
   <tr>
    <td>{$form['Price']->label}</td><td>{$form['Price']->control}</td>
    <td>{$form['DPH_ID']->label}</td><td>{$form['DPH_ID']->control}</td>
   </tr>
   </Table>
 </div>
 <div id="tabs-2">
   <div>{$form['Notes']->label}<BR>{$form['Notes']->control}</div>
 </div>
</div>
<BR>
<div align="right">
{$form['back']->control} {$form['save']->control}
{$form->render('end')}
</div>
</div>

A po načtení dokumentu JavaScript (kromě jiného)

<script>
$("#dialog").hide();
$("#tabs").tabs();
$("form.ajax").live("submit", function () {
    $(this).ajaxSubmit(function (payload) {
      jQuery.nette.success(payload);
        if (payload.alert) {
         alert(payload.alert)
        }
      $("#dialog").dialog("close");
      $("#table_services").flexReload();
    });

    return false;
});

  $(":button").click(function(){
      $("#dialog").dialog("close");
});
</script>

Na stránce je ještě flexigrid na kterém je tlačítko, které zobrazí formulář na tom divu #dialog.

S.

natrim
Člen | 73
+
0
-

nevidim tam nic zvlastniho,ale zkus ten script napsat spise takto

<script>
$("#dialog").hide();
$("#tabs").tabs();
$("form.ajax").live("submit", function () {
	$("form.ajax :submit:first").click();
	return false;
});

$("form.ajax :submit").live('click',function(){
	$(this).ajaxSubmit(function (payload) {
	      jQuery.nette.success(payload);
        		if (payload.alert) {
		         alert(payload.alert)
		        }
		        $("#dialog").dialog("close");
		        $("#table_services").flexReload();
	});
        return false;
    });

$(":button").click(function(){
      $("#dialog").dialog("close");
});
</script>

Editoval natrim (12. 10. 2010 8:19)

scerny
Člen | 25
+
0
-

Nevím proč, ale tento select vůbec nezabere

<script>
$("form.ajax :submit").live('click',function(){
...
</script>
natrim
Člen | 73
+
0
-

hm difny, zkus to pres idcka

fidLi
Člen | 41
+
0
-

není to tím, že tam chybí ; za tím alertem? Mimochodem, mě se validace provádí 2×, a skript v ajax submit pod $(this).ajaxSubmit(function () {alert("done");}); se vůbec nezobrazí

Editoval fidLi (13. 10. 2010 20:33)

scerny
Člen | 25
+
0
-

Momentálně mi to připadá, jako různá interpretace JavaScriptu v různých prohlížečích. IE8 tento problém není.

fidLi
Člen | 41
+
0
-

v mozile se odešle formulář, ale neprovede se funkce v ajax submit, a v IE se to ani ajhaxově neodešle

scerny
Člen | 25
+
0
-

Tak to je šílená alchymie, já můžu s jistotou říct, že takto napsaný script:

<script>
$("form.ajax").live("submit", function () {
    $(this).ajaxSubmit(function (payload) {
      jQuery.nette.success(payload);
        if (payload.alert) {
         alert(payload.alert);
        }
    });

    return false;
});
</script>

se na IE chová tak jak očekávám, to znamená, že se odešle ajaxově a vrátí se payload. V mozile také, akorát když nějaké validační pravidlo nevyhový, tak se upozornění ozve 2×.

fidLi
Člen | 41
+
0
-

napadá mě, chyba, která se může u mě objevovat… Musí se nějak nadefinovat payload? nebo e může rovnou použít?

scerny
Člen | 25
+
0
-

Já to používám takto:

<?php
    try{
        $this->servicesModel->saveRow($values,$values['ID']);
          if(!$this->isAjax())
        {
           $this->flashMessage('Vaše data byla uložena.');
           $this->redirect('default');
        } else {
            $this->payload->alert = 'Vaše data byla uložena.';
         }
     } catch(ErrorException $e){
          $this->payload->alert = 'Vaše nebyla uložena | důvodem je '.$e->getMessage();
      }
?>
fidLi
Člen | 41
+
0
-

když sem odstranil proměné v payloadu, ale payload poslal prázdný, tak se alespon v alertu objevi undefined – asi po 5 vterinach. To znamena, ze to nekde spatne komunikuje, pomoc…

scerny
Člen | 25
+
0
-

Moc tomu nerozumím, dej sem alespoň kus zdrojáku.

fidLi
Člen | 41
+
0
-

Tak se mi podařilo to spravit, nikoliv však záležitost s dvojitou validací. Od Bellyho jsem se dostal k vláknu: https://forum.nette.org/cs/1300-neco-jako-nette-js-s-jquery?pid=17872#p17872.
Avšak to když provedu, tak se formulář neodesílá ajaxově.

Editoval fidLi (18. 10. 2010 15:26)

fidLi
Člen | 41
+
0
-

vyřešil jsem dvojitou validaci, i svůj problém, mů problém : https://forum.nette.org/cs/5728-ajax-textove-pole-iterace-nefunguje?pid=43347#p43347 a dvojitá validace? Nikdy nevykresluj jeden týž submit button vícekrát než jednou, kdyžtak jich udělej víc.. a pokud ani to nepomůže, tak najdi absolutní cestu v hledani prvku, tedy $('form.ajax > div.formular > table > tr > td > atd :submit').live(....
doufám, že pomůže