Moin die Herren (und die Damen?),
Kurzbeschreibung: für mein neuestes Projekt wollte ich einen globalen Login im Header der Seite einbauen. Bei Klick auf den Button "Login" wird der Inhalt des Loginformulares in einen Div-Container geschrieben und dieser Container auf "visible" gesetzt. Bei eingabe falscher Logindaten soll die Fehlermeldung im nun sichtbaren Div-Container ausgeben - bei erfolgreichem Login hingegen wird der Loginbutton samt Loginformular ausgeblendet und eine Erfolgsmeldung ausgegeben.
Dies habe ich wie folgt umgesetzt.
Bei Klick auf den Loginbutton wird folgende Funktion ausgeführt:
$("#loginbox").load("/profil/login #login-form", function(data) {
parseScript(data);
});
View-File:
<?php
$this->pageTitle = 'Login - ';
$this->pageTitle.= Yii::app()->name;
?>
<div class="row">
<div class="twelve columns">
<div class="box">
<div class="header">
<h2>Login</h2>
</div>
<div class="content">
<?php
if(!Yii::app()->user->isGuest) {
?>
<span class="rot">Du bist bereits angemeldet.</div>
<?php
} else {
$form=$this->beginWidget('CActiveForm', array(
'id' => 'login-form',
'enableAjaxValidation' => true,
'enableClientValidation' => true,
//'action' => $this->createUrl('profil/login'),
'htmlOptions' => array(
'class' => "noclose",
//'onsubmit' => "return false;", /* Disable normal form submit */
'enctype' => 'multipart/form-data',
),
));
?>
<fieldset>
<?php echo $form->errorSummary($model); ?>
<label>Hier kommt ein kurzer Logintext hin</label>
<div class="errorMessage" id="ajax-status"></div>
<div id="AjaxLoader" style="display: none"><img src="<?php echo Yii::app()->request->baseUrl; ?>/images/spinner.gif"></img></div>
<div class="row collapse">
<div class="two mobile-one columns">
<span class="prefix">
<img src="/images/icons/login_user_icon.png" class="disabled" />
</span>
</div>
<div class="ten mobile-three columns">
<?php echo $form->textField($model,'username',array('placeholder'=>'Username')); ?>
</div>
<div class="two mobile-one columns">
<span class="prefix">
<img src="/images/icons/login_pass_icon.png" class="disabled" />
</span>
</div>
<div class="ten mobile-three columns">
<?php echo $form->passwordField($model,'password',array('placeholder'=>'Passwort')); ?>
</div>
</div>
<div class="row collapse">
<div class="twelve mobile-four columns middle">
<?php echo $form->checkBox($model,'rememberMe',array()); ?> <?php echo $form->label($model,'rememberMe',array('class'=>'default')); ?>
</div>
</div>
<div class="row collapse">
<div class="twelve columns text-right">
<?php
echo CHtml::ajaxSubmitButton(
'Login',
$this->createUrl('profil/login'),
array(
'dataType'=>'json',
'type' => 'POST',
'data' => "js:$('#login-form').serialize()",
'success'=>'function(data){
if(data.status=="success") {
$("#userprofil-box").load("Yii::app()->request->baseUrl; #userprofil-box > *");
reInitHtmlClick();
$("#grayout").toggle(0);
$("#loginbox").hide(200);
hideFormErrors(form="#login-form");
} else {
formErrors(data,form="#login-form");
}
}',
),
array('class'=>'button')
);
?>
</div>
</div>
<br />
<div class="row collapse">
<div class="twelve mobile-four columns text-right">
<a href="<?php echo $this->createUrl('profil/passwort'); ?>">» Passwort vergessen?</a>
</div>
</div>
</fieldset>
<?php
$this->endWidget();
?>
<div id="test"></div>
<a href="" class="close">×</a>
</div>
<?php
}
?>
</div>
Und der ProfilController:
public function actionLogin() {
$this->breadcrumbs = array('Login');
$model=new LoginForm;
if(Yii::app()->request->isAjaxRequest) {
// $this->performAjaxValidation($model);
if(isset($_POST['LoginForm'])) {
$model->attributes=$_POST['LoginForm'];
$valid=$model->validate();
if($model->validate() && $model->login()){
//do anything here
echo CJSON::encode(array(
'status'=>'success'
));
Yii::app()->end();
} else{
$error = CActiveForm::validate($model);
if($error!='[]') {
echo $error;
}
Yii::app()->end();
}
}
}
if(isset($_POST['LoginForm'])) {
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login()) {
$this->redirect(Yii::app()->user->returnUrl);
}
}
// display the login form
if(Yii::app()->request->isAjaxRequest) {
$this->renderPartial('login',array('model'=>$model), false, true);
} else {
$this->render('login',array('model'=>$model));
}
}
Beim "Basteln" habe ich festgestellt, dass CActiveForm buw Chtl::ajaxSubmitButton JQuery-Funktionen beim Rendern an das auszugebene HTML-Konstrukt anhängen, mit denen die Formulare validiert werden.
Diese automatisch generierten Funktionen funktionieren allerdings nicht, wenn man das Formular einfach in den Div-Container hineinlädt. Der zuvor generierte Button feuert kein Event mehr ab und macht einfach nix (im Firebug überprüft)
Nach Stunden des Herumprüfens kam mir die Idee den Javascript-Code aus der Datei herauszuparsen und via eval zum Laufen zu bringen - siehe da: es hat funktioniert.
Dieser Weg erscheint mir aber nicht sonderlich "schön". Hat hier irgendjemand bessere Lösungen für ein solches Problem parat?
Kann ich die automatisch generierten JQuery-Funktionen irgendwie beim Rendern im Controller abfangen?
Wo wird dieser Code überhaupt generiert und kann man diesen überhaupt manipulieren?
Bin gespannt auf Eure Antworten.