Přihlašování uživatelů přes ajax

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

Zdravím,

už několik hodin bojuju s přihlašováním přes ajax. Mám ve vyskakovacím okně formulář pro přihlášení. Rád bych, aby když někdo zadá špatné údaje, tak mu to vypsalo hlášku – bez refreshe stránky. Pokud se přihlásí, může se provést redirect. Zápasím opět s Ajaxem, jak už to u mě bývá.

Mám formulář:

namespace App\FrontModule\Forms;

use Nette,
    Nette\Application\UI\Form,
    App\Model\Customers,
    Nette\Security\User;


class SignCustomerFormFactory extends Nette\Object
{
    /** @var User */
    private $user;
    /** @var Customers @inject */
    public $customers;



    public function __construct(User $user)
    {
        $this->user = $user;
    }


    /**
     * @return Form
     */
    public function create()
    {
        $form = new Form;
        $form->addText('email', '')
            ->setRequired('Zadejte prosím e-mail.')
            ->setAttribute('placeholder', 'E-mail')
            ->setAttribute('class', 'form-control');

        $form->addPassword('password', '')
            ->setRequired('Zadejte prosím heslo.')
            ->setAttribute('placeholder', 'Heslo')
            ->setAttribute('class', 'form-control');

        $form->addSubmit('send', 'Přihlásit')
            ->setAttribute('class', 'login loginmodal-submit');

        //$form->onSubmit[] = [$this, 'handleformSucceeded'];
        //$form->onSuccess[] = array($this, 'handleformSucceeded');
        return $form;
    }


//toto pri ajaxu vubec pouzivat nebudu, ne?
    public function handleformSucceeded($form, $values)
    {


        $this->user->setExpiration('1 day', TRUE);

        try {
            $this->user->getStorage()->setNamespace('Front');
            $this->user->login($values->email, $values->password); //pri normalnim requestu se prihlasim
        } catch (Nette\Security\AuthenticationException $e) {
            $form->addError($e->getMessage()); //tyto hlášky bych rád předával do modal okna s přihlášením
        }
    }

}

Protože chci aby to vyskakovací okno bylo na všech podstránkách mám to v BasePresenteru:

namespace App\FrontModule\Presenters;

use Nette,
    App\Model\Settings,
    App\FrontModule\Forms\SignCustomerFormFactory;


/**
 * Base presenter for all application presenters.
 */
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    /** @var  Settings @inject */
    public $settings;
    /** @var SignCustomerFormFactory @inject */
    public $factory;

    public function beforeRender()
    {
        parent::beforeRender(); // TODO: Change the autogenerated stub

        $this->template->settings = $this->settings->getSettings();
    }

    /**
     * Check if user is logged in Frontend area
     * @param $element
     */
    public function checkRequirements($element)
    {
        $this->getUser()->getStorage()->setNamespace('Front');
        parent::checkRequirements($element);
    }

    /**
     * Login form
     * @return Nette\Application\UI\Form
     */
    protected function createComponentSignInForm()
    {
        $form = $this->factory->create();
        return $form;
    }


}

Ten vypisuji takto:

{form signInForm}
    {snippet signInError}{/snippet}

    <div class="form-group">
        {input email}
    </div>
    <div class="form-group">
        {input password}
    </div>
    {input send}
{/form}

Javascript, který se to stará.

<script>
    $(document).ready(function(){
        $('.loginmodal-submit').click(function (e) {
            e.preventDefault();
            $.nette.ajax({
                url: {link Homepage:signIn},
                type: 'POST',
                data: {
                    email: $('#frm-signInForm-email').val(),
                    pass: $('#frm-signInForm-password').val()
                },
                success: function (payload) {
                    console.log(payload);
                }
            });
        });
    });
</script>

a nakonec v HompegePresenter mám SignIn:

    public function handleSignIn($email, $pass)
    {
//Tady bych chtel potom napojit fci  $this->user->login($email, $pass); ktera je ted uvedena v SignCustomerFormFactory
        dump($email);
        if ($this->isAjax()) {
            $this->payload->message = 'success';
            $this->sendPayload();
        }
    }

Laděnka zaznamená že se vysílá ajax, bohužel to po mě chce šablonu SignIn. Což je určitě špatně, při ajaxu by to přece žádnou šablonu nemělo chtít. Každopádně ikdyž ji vytvořím a mám ji prázdnou, tak stejně se mi payload neodešle.
Moje představa je taková, že v tom handleSignIn bude podobná logika jako je v SignCustomerFormFactory::handleformSucceeded jenom s tím rozdílem, že chyby budu posílat přes payload a zobrazovat.
Je mé řešení logicky správně a je potřeba ho trochu odladit nebo je to celé špatně a správně se to dělá úplně jinak?
Předem diky.

ViPEr*CZ*
Člen | 811
+
0
-

No a vleze to vůbec do téhle metody handleSignIn ?
Není problém v tomhle url: {link Homepage:signIn} když jde o FrontModul?
Btw $.nette.ajax by měl jít nahradit za volání klasického submit ajaxu. Nevím z hlavy jak to přetížit. Vždycky se dívám do zdrojáku té js komponenty, když to potřebuju.
A pak bych normálně použil handleformSucceeded přímo z komponenty, aby to nebylo závyslé na HomepagePresentru.

R@da
Člen | 25
+
0
-

Pokud změním handleSignIn na renderSignIn, rozběhne se to. Nevím proč? Je to vůbec správně? Pro ajax by se měl používat handle nebo ne? Jak případně můžu zapsat url, když mám handleformSucceeded zvlášť? taky mi to přijde zavádějící mí to v homepagePresenteru.

Šaman
Člen | 2634
+
+1
-

Když potřebuji něco vracet, tak pro AJAX používám action.
Ty děláš odkaz na akci/pohled (action/render), protože v tom odkazu ({link Homepage:signIn}) neuvádíš vykřičník. A s handlery býval problém, pokud je chceš volat na jiné komponentě, takže pokud to není interní signál jen pro potřeby komponenty, klidně použiju action + terminate(). (U tebe není terminate potřeba, protože to ukončí už metoda sendPayload(), nebo kterákoliv jiná sendResponse).