Формы
Создание формы со стандартной отрисовкой и обработчиком.
Создание полей с необходимой разработчику отрисовкой (генерация HTML-кода)
Создайте файл в /internals/includes/MyField.php и разместите там класс вашего поля. Отрисовка (генерация HTML-кода) вашего поля происходит через метод get_html() класса MyField.
<?
class MyField extends Field {
public $type = 'myfield';
public function get_html(){
$html = '<input type="text" name="' . $this->name . '" value="' . htmlspecialchars( $this->value, ENT_QUOTES | ENT_SUBSTITUTE ) . '" />';
return $html;
}
}
?>
Создайте файл формы в /internals/includes/MyForm.php, разместите там класс вашей формы и сделайте подключение вашего поля.
<?
require_once('MyField.php');
class MyForm extends Form {
public function __construct() {
$this->action = '/my-page/?action=save';
$this->method = 'post';
$field = new MyField();
$field->name = 'field1';
$this->add_field( $field );
}
}
?>
Отправка формы через ajax.
$form->ajax = true;
// Указываем свой обработчик отправки, который будет вызван при нажатии на кнопку submit.
$form->onsubmit = 'return my_form_ajax_submit(this)';
Обработка (проверка) формы
if( $form->handle() == true ){
}
else {
}
Создание формы с индивидуальной отрисовкой и обработчиком.
Для этого необходимо создать класс наследованный от базового класса Form.
class MyForm extends Form {
public function __construct( $properties = [] ) {
parent::__construct( $properties );
$this->action = '/my-page/?action=save';
$this->method = 'post';
$field = new FieldHidden();
$field->name = 'id';
$field->dt = 'int';
$this->add_field( $field );
$field = new FieldEditbox();
$field->title = 'ФИО';
$field->name = 'fio';
$field->required = true;
$field->dt = 'str';
$this->add_field( $field );
$field = new FieldEditbox();
$field->title = 'Телефон';
$field->name = 'phone';
$field->required = true;
$field->dt = 'str';
$this->add_field( $field );
}
public function get_html(){
$vars = [];
$vars['form'] = $this->prepare();
$module = app::get_module('frontend','kernel');
$html = app::$tpl->fetch( $module->dir . '/form/form.tpl', $vars );
return $html;
}
public function handle(){
// Стандартная проверка.
parent::handle();
if( $this->error == true ){
return false;
}
//
// BEGIN Проверка существования записи.
//
$this->data['record'] = null;
if( $this->field('id')->value > 0 ){
$this->data['record'] = check_record( $this->field('id')->value, false );
if( $this->data['record'] == null ){
$this->error = true;
}
}
//
// END Проверка существования записи.
//
return !$this->error;
}
}
Пример работы.
/internals/includes/my_functions.php
<?
function check_record( $id, $redirect = true ){
$sql = 'SELECT * FROM table WHERE id = ?d AND remove_ts = 0';
$row = app::$db->select_row( $sql, $id );
if( $row == null && $redirect == true ){
$tdata = [];
$tdata['messages'][] = [ 'Запись с указанным кодом не найдена.', app::MES_WARN ];
$key = app::set_transit_data( $tdata );
$url = app::$controller_url . '?_page=my_page&_key=' . $key;
redirect( $url );
}
return $row;
}
?>
/internals/pages/my_page.php
<?
require_once( app::$config['dirs']['includes'] . '/MyForm.php' );
require_once( app::$config['dirs']['includes'] . '/my_functions.php' );
$ext_action = get_str('action');
switch( $ext_action ){
case 'save':
$ext_id = get_int('id');
$form = new MyForm();
if( $form->check() == true ){
$tdata = [];
$record_id = 0;
if( $form->field('id')->value > 0 ){
$upd_data = [];
$upd_data['name'] = $form->field('fio')->value;
$upd_data['phone'] = $form->field('phone')->value;
$sql = 'UPDATE table SET ?l WHERE id = ?d';
// TODO Try Catch
app::$db->q( $sql, $upd_data, $form->data['record']['id'] );
$tdata['messages'][] = [ 'Данные сохранены.', app::MES_OK ];
$record_id = $form->data['record']['id'];
}
else {
$sql = 'INSERT INTO table SET ?l';
$ins_data = [];
$ins_data['name'] = $form->field('fio')->value;
$ins_data['phone'] = $form->field('phone')->value;
// TODO Try Catch
$record_id = app::$db->ins( $sql, $ins_data );
$tdata['messages'][] = [ 'Новая запись создана.', app::MES_OK ];
}
$key = app::set_transit_data( $tdata );
$url = url_add_params( $this->get_url(), [ 'action' => 'edit', 'id' => $record_id, '_key' => $key ] );
}
else {
$tdata = [];
if( $form->field('id')->value > 0 ){
$tdata['messages'][] = [ 'Не удалось сохранить изменения.', app::MES_ERROR ];
}
else {
$tdata['messages'][] = [ 'Не удалось создать новую запись.', app::MES_ERROR ];
}
$tdata['form'] = serialize( $form );
$key = app::set_transit_data( $tdata );
if( $form->field('id')->value > 0 ){
$url = url_add_params( $this->get_url(), [ 'action' => 'edit', 'id' => $form->field('id')->value, '_key' => $key ] );
}
else {
$url = url_add_params( $this->get_url(), [ 'action' => 'create', '_key' => $key ] );
}
}
redirect( $url );
break;
case 'create':
case 'edit':
$ext_id = get_int('id');
//
// BEGIN Проверить существование записи.
//
if( $ext_id > 0 ){
$record = check_record( $ext_id );
}
//
// END Проверить существование записи.
//
$default = true;
if( app::exists_transit_data( $tdata ) == true ) {
if( array_key_exists( 'form', $tdata ) == true ){
$tdata['form'] = unserialize( $tdata['form'] );
if( is_object( $tdata['form'] ) == true ) {
$form = $tdata['form'];
$default = false;
}
}
}
if( $default == true ){
$form = new MyForm();
if( $ext_action == 'edit' ){
$form->field('fio')->value = $record['name'];
$form->field('phone')->value = $record['phone'];
}
}
//
// BEGIN Вывод.
//
if( $ext_action == 'edit' ){
$this->seo_h1 = 'Редактирование записи';
$this->title = 'Редактирование записи';
$this->bread_crumbs[] = [
'text' => 'Редактирование записи (код: ' . $record['id'] . ')',
'href' => url_add_params( $this->get_url(), [ 'action' => 'edit', 'id' => $record['id'] ] )
];
}
else {
$this->seo_h1 = 'Новая запись';
$this->title = 'Новая запись';
$this->bread_crumbs[] = [
'text' => 'Новая запись',
'href' => url_add_params( $this->get_url(), [ 'action' => 'create' ] )
];
}
//
// END Вывод.
//
$html = $form->get_html();
break;
default:
// ...
break;
}
echo $html;
?>
Варианты формы
Варианты формы — динамический механизм (без использования ajax), который позволяет форме иметь разный состав полей в зависимости от ситуации. Например при выборе некоторого радиобокса, часть полей показывать, а часть скрывать.