Instrukcje do ćwiczeń

Proste formularze

W poprzednich częściach kursu poznaliśmy strukturę frameworka Yii, oraz sposoby przekazywania danych między modelem, kontrolerem i widokiem. Teraz pora na modyfikację danych.

Tworzymy kontroler:

class TestUsersController extends Controller {
public function actionIndex(){
$this->render('index');
}
}

Możemy przystąpić do budowy prostego formularza.

Tworzymy katalog views/TestUser.php a w nim plik index.php

<form action="/kurs/www/TestUsers" method="post">

Identyfikator: <input name="username" type="text" /> <br />

Hasło: <input name="password" type="password" /> <br />

<button type="submit" name="OK">Login</button>

</form>

Jest to najbardziej typowy formularz html z możliwych. Możemy go przetestować – po kliknięciu Login powinien wyświetlić się ponownie: http://localhost/yiikurs/www/TestUsers

Oczywiście w kontrolerze należy to jakoś obsłużyć. Dodajemy przed wywołaniem funkcji render:

if (isset($_POST['password'])) $message='dane użytkownika';

else $message='';

Aby po kliknięciu „Login” pojawi się odpowiedni komunikat, musimy komunikat przekazać do formularza:

$this→render('index',array('message'=>$message));

a w formularzu dodajemy:

<?php echo $message; ?> <br />

Pewnym ułatwieniem jest możliwość przekazywania danych z formularza w tablicy. W widoku zamiast 'username' wpisujemy "User[username]" i odpowiednio dla password:

<form action="/yiikurs/www/TestUsers" method="post">

Identyfikator: <input name="User[username]" type="text" /> <br />

Hasło: <input name="User[password]" type="password" /> <br />

<button type="submit" name="OK">Login</button>

</form>

W tablicy $_POST będzie zapisana tablica danych formularza. Modyfikujemy odpowiedni fragment kontolera:

if (isset($_POST['User'])) {
$User=$_POST['User'];
$message='dane użytkownika '.$User['username'].'<br />';
}

Powiązanie z modelem

Do testów utwórzmy tabelę test_users:

CREATE TABLE IF NOT EXISTS `test_users` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`username` varchar(20) NOT NULL,

`password` varchar(128) NOT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY `username` (`username`)

) DEFAULT CHARSET=utf8;

INSERT INTO `test_users` (`username`, `password`)

values ('admin', 'haslo');

Zbudujmy odpowiedni model (http://www.yiiframework.com/doc/guide/1.1/pl/form.model):

<?php

class TestUsers extends CFormModel
{
public $username;
public $password;

public function tableName()
{
return 'test_users';
}

public function FetchID($id) {
$db = Yii::app()->db->createCommand('SELECT * FROM test_users WHERE
id = :id');
$db->bindValue(':id', $id, PDO::PARAM_INT);
$result=$db->queryRow();
if (isset($result)) {
foreach($result as $name=>$value) {
if(property_exists($this,$name))
$this->$name=$value;
$this->attributes[$name]=$value;
}
}
return $result;
}

public function FetchUsername($username) {
$db = Yii::app()->db->createCommand('SELECT * FROM test_users WHERE
username = :username');
$db->bindValue(':username', $username, PDO::PARAM_STR);
return $db->queryRow();
}

}

Można oczywiście uprościć sobie korzystając w miejsce CFormModel z CActiveRecord (wymaga nieco innych operacji):

class TestUsers extends CActiveModel
{
public function tableName() {
return 'test_users';
}
}

Przekazanie modelu do formularza jest proste:

public function actionIndex(){
$model=new TestUsers();
$this->render('index',array('model'=>$model,));
}
Możemy dzięki temu na przykład wyświetlać / zmieniać dane wybranego rekordu. Załóżmy, że chodzi nam o rekord o numerze 1 (jeśli używasz CActiveRecord – TestUsers::model()→findByPk(1); zob. http://www.yiiframework.com/doc/guide/1.1/pl/database.ar ):

public function actionIndex(){
$model=new TestUsers();$model->
FetchID(1);
$this->render('index',array('model'=>$model,));
}

Aby sprawdzić dane po wpisaniu w formularzu, możemy je odczytać zdefiniowaną wcześniej funkcją FetchUsername:
public function actionIndex(){
$model=new TestUsers();
if (!isset($_POST['User'])) $model->FetchID(1);
else {
$user=$model->FetchUsername($_POST['User']['username']);
if ($user['password']==$_POST['User']['password']) $message='OK';
else $message='nie zgadza się';
}
$this->render('index',array('model'=>$model,'message'=>$message));
}

Helpers

Yii dostarcza klasy „pomocników” (Helpers), w których zdefiniowano generowanie kodu html. Zamiast pisać „ręcznie” kod formularza, możemy użyć pomocnika Chtml (dla Yii 1.x). Więcej: http://www.yiiframework.com/doc/guide/1.1/en/form.view

Ten sam formularz możemy wygenerować używając klasy CHtml. Należy jednak zwrócić uwagę na to, że w czasie generacji jako identyfikator tablicy z danymi jest używana nazwa modelu (a więc TestUsers a nie Users). Musimy więc zmienić kontroler:

public function actionIndex(){
$message='';
$model=new TestUsers();
if (!isset($_POST['TestUsers'])) {
$model->FetchID(1);
} else {
$user=$model->FetchUsername($_POST['TestUsers']['username']);
if ($user['password']==$_POST['TestUsers']['password']) $message='OK';
else $message='nie zgadza się';
}
$this->render('index',array('model'=>$model,'message'=>$message));
}

Formularz (w widoku index):

<?php echo $message; ?> <br />

Formularz z użyciem pomocnika (helper):

<?php

echo CHtml::beginForm("/yiikurs/www/TestUsers");

echo CHtml::errorSummary($model);

echo CHtml::activeLabel($model,'username');

echo CHtml::activeTextField($model,'username'); ?><br />

<?php

echo CHtml::activeLabel($model,'password');

echo CHtml::activePasswordField($model,'password');

echo CHtml::submitButton('Login');

echo CHtml::endForm(); ?>

Kontrolki (Widgety)

Najbardziej zaawansowanym sposobem generowania formularzy jest użycie kontrolek (widgetów). Standardowo używa się do formularzy stosuje się kontrolkę CActiveForm. Istnieje jednak wiele alternatyw. Na razie zobaczmy jak to wygląda z użyciem CActiveForm. Stwórzmy jednak nową akcję w kontrolerze i nowy widok (Login):

public function actionLogin(){
$message='';
$model=new TestUsers();
if (!isset($_POST['TestUsers'])) {
$model->FetchID(1);
} else {
$user=$model->FetchUsername($_POST['TestUsers']['username']);
if ($user['password']==$_POST['TestUsers']['password']) $message='OK';
else $message='nie zgadza się';
}
$this->render('login',array('model'=>$model,'message'=>$message));
}

Widok:

<?php echo $message; ?> <br />
<div class="form">

<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'form-ident',
'enableAjaxValidation'=>false,
));
echo $form->errorSummary($model);

echo $form->labelEx($model,'username');
echo $form->textField($model,'username');
echo $form->error($model,'username');
?>
<br />
<?php
$form->labelEx($model,'password');
echo $form->passwordField($model,'password');
echo $form->error($model,'password');
?>
<br />
<?php
echo CHtml::submitButton('Submit');
$this->endWidget(); ?>

Formularze z użyciem kontrolek można wygenerować przy użyciu gii (http://www.yiiframework.com/doc/guide/1.1/pl/topics.gii). Standardowo generuje on CActiveRecord (a nie jak w powyższych przykładach CFormModel).

Ostatnia modyfikacja: sobota, 31 październik 2015, 08:31