I have the following code in my main index.php:
<div class="form">
<?php $oForm = $this->beginWidget('CActiveForm', array(
'id' => 'test-form',
'enableAjaxValidation' => false,
'enableClientValidation' => true,
'clientOptions' => array(
'validateOnSubmit' => true,
),
'focus' => array($oTest, 'title'),
)); ?>
<fieldset>
<legend>Questions</legend>
<div id="questions">
<?php echo $oForm->hiddenField($oTest, '_id'); ?>
<?php $this->renderPartial('_showQuestions', array('oTest' => $oTest)); ?>
</div>
</fieldset>
<fieldset>
<legend>Reviewers</legend>
<div class="row">
<?php echo $oForm->labelEx($oTest, 'reviewers'); ?>
<?php echo $oForm->textField($oTest, 'reviewers', array('size' => 140)); ?>
</div>
</fieldset>
<?php $this->endWidget(); ?>
and the following code in the partial view _showSuestions
<div class="form">
<?php $oForm = $this->beginWidget('CActiveForm', array(
'id' => 'question-form2',
'enableAjaxValidation' => false,
'enableClientValidation' => true,
'clientOptions' => array(
'validateOnSubmit' => true,
),
)); ?>
<?php echo $oForm->hiddenField($oTest, '_id'); ?>
<?php
foreach ($oTest->questions as $oQuestion)
{
var_dump($oQuestion);
}
?>
<?php $this->endWidget(); ?>
Now the problem is that this doesn't work. When I fisit my page, the form tag is suddenly closed after I called my partialView. i'm guessing this is because of the nested CActiveForm? When I remove the inner CActiveForm it works
try changing the name of the second form variable (in _showQuestions file), say, oForm to tForm. there is a variable name clash. Because at the end of the day, renderPartial is nothing but a include.
Related
I am currently in the process of updating a (rather big) application from CakePHP 3 to 4.
I have this template:
<?= $this->Form->create(
$dmpLayer,
[
'url' => [
'controller' => 'DmpLayers',
'action' => 'edit',
],
]
); ?>
<div class="row">
<div class="col-4">
<?= $this->element('DataLayers/layer-table'); ?>
</div>
<div id="form-div" class="col-6">
<div class="layer-form">
<?= $this->element('DataLayers/form') ?>
</div>
</div>
<div class="col-2">
<div class="layer-form">
<h2>Form Actions</h2>
<?= $this->Form->submit('Create/Update Layer', ['class' => 'btn btn-success']); ?>
</div>
</div>
</div>
<?= $this->Form->end(); ?>
<?= $this->Html->script('data-layers'); ?>
which includes the DataLayers/form element:
<div class="row">
<div class="col-12">
<h4>Artist Layer</h4>
<?php
echo $this->Html->tag('fieldset', $this->element(
'actions/add',
[
'url' => [
'prefix' => 'Admin',
'plugin' => false,
'controller' => 'SegmentCores',
'action' => 'add',
],
]
)
. $this->Form->control('artist_layer.segment_cores[]', [
'multiple',
'options' => $segmentCores,
'label' => 'Segment Core',
'value' => $selectedValues['segment_cores'],
])
. $this->Form->control('artist_layer.segment_potentials[]', [
'multiple',
'options' => $segmentPotentials,
'label' => 'Segment Potential',
'value' => $selectedValues['segment_potentials'],
])
. $this->Form->control('artist_layer.layer_tags[]', [
'multiple',
'options' => $layerTags,
'label' => 'Artist Tag',
'value' => $selectedValues['artist_tags'],
])
. $this->Form->control('artist_layer.genres[]', [
'empty' => 'No genre set',
'options' => $genres,
'label' => 'Genre',
'value' => $selectedValues['genres'],
]);
?>
</div>
</div>
<?php
$this->Form->unlockField('artist_layer.genres');
$this->Form->unlockField('artist_layer.segment_cores');
$this->Form->unlockField('artist_layer.segment_potentials');
$this->Form->unlockField('artist_layer.layer_tags');
?>
In the initialize function of the AppController I have this:
$this->loadComponent('Security');
When I visit the page, it doesn't render and I immediately get this error:
FormProtector instance has not been created. Ensure you have loaded the FormProtectionComponent in your controller and called FormHelper::create() before calling FormHelper::unlockField()
This is the only form in my application for which this error happens. Every other form is working fine, and I am calling the Form->unlockField() function in many of them.
I am obviously calling Form->create() in my code, so is this because I am including an element to add fields to the form that is defined in the "main" template? Or is there some other explanation?
I have already attempted adding
$this->loadComponent('FormProtection');
to my AppController, but this causes a whole lot more problems in many other places in the app, and it doesn't solve the problem anyway (the page renders, but I get an error when submitting the form to save the data).
I can't create a Pjax form inside an active form. What I've found is that when I put the Pjax inside an active form it doesn't work (it submits the entire page) but when I put it outside the active form its works fine:
<?php
$form = ActiveForm::begin([
'id' => 'CouplePartnerForm',
'action' => ['couple-partner/savecouplepartner'],
'enableAjaxValidation' => true,
'enableClientValidation' => true,
'validateOnSubmit' => true,
]);
?>
<div class="row">
<?php Pjax::begin([]); ?>
<?= Html::beginForm(['couple-partner/form-submission'], 'post', ['data-pjax' => '0', 'class' => 'form-inline']); ?>
<?= Html::input('text', 'string', Yii::$app->request->post('string'), ['class' => 'form-control']) ?>
<?= Html::submitButton('Hash String', ['class' => 'btn btn-lg btn-primary', 'name' => 'hash-button']) ?>
<?= Html::endForm() ?>
<h3><?= isset($stringHash) ?$stringHash :"" ?></h3>
<?php Pjax::end(); ?>
</div>
<?php ActiveForm::end(); ?>
So what is the problem here?
I have this code in layouts/main.php file:
<div class="wrap">
<? \yii\widgets\Pjax::begin(['id' => 'nav_pjax'])?>
<?php
NavBar::begin([
'brandLabel' => 'Название компании',
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'id' => 'ww',
'class' => 'navbar-inverse navbar-relative',
],
]);
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right', 'id' => 'ww'],
'items' => User::getMenuItemsByRoleUser(!Yii::$app->user->isGuest ? Yii::$app->user : false,Yii::$app->user->isGuest)
]);
NavBar::end();
?>
<? \yii\widgets\Pjax::end()?>
<div class="container" id="content_inner">
<? \yii\widgets\Pjax::begin(['timeout' => '3000'])?>
<?= Breadcrumbs::widget([
'homeLink'=>[
'label' => 'Главная', // required
'url' => \yii\helpers\Url::home(), // optional, will be processed by Url::to()
],
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
<?= $content ?>
<? \yii\widgets\Pjax::end()?>
</div>
When I click into navbar link, the server returns a content, which I want to put into div class="container" id="content_inner". How I can do that? Or I should refresh the page completely?
You don't need two pjax widget, you could simply try :
1) Update just content
<div class="wrap">
<?php /* navbar */ ?>
<div class="container" id="content_inner">
<?php \yii\widgets\Pjax::begin([
'id' => 'nav_pjax',
'timeout' => '3000',
'linkSelector' => '.navbar-nav a', // use pjax on navbar links
]); ?>
<?php /* breadcrumb and content */ ?>
<?php \yii\widgets\Pjax::end(); ?>
</div>
</div>
Read more about linkSelector.
2) Update navbar and content
<div class="wrap">
<?php \yii\widgets\Pjax::begin([
'id' => 'nav_pjax',
'timeout' => '3000',
]); ?>
<?php /* navbar */ ?>
<div class="container" id="content_inner">
<?php /* breadcrumb and content */ ?>
</div>
<?php \yii\widgets\Pjax::end(); ?>
</div>
I created a simple form in typical ZF2 application. The form class code is just a modified code provided by Zend's Album example.
<?php
namespace Admin\Form;
use Zend\Form\Form;
class CityForm extends Form
{
public function __construct($name = null)
{
parent::__construct('city');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden',
),
));
$this->add(array(
'name' => 'name',
'attributes' => array(
'type' => 'text'
),
'options' => array(
'label' => 'Name',
),
));
$this->add(array(
'name' => 'province',
'attributes' => array(
'type' => 'text'
),
'options' => array(
'label' => 'Province',
),
));
$this->add(array(
'name' => 'country',
'attributes' => array(
'type' => 'text'
),
'options' => array(
'label' => 'Country',
),
));
$this->add(array(
'name' => 'coordinate',
'attributes' => array(
'type' => 'text'
),
'options' => array(
'label' => 'Coordinate',
),
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Save',
'id' => 'submitButton',
),
));
}
}
And call it like this in CityController, a typical controller extends AbstractActionController:
public function addAction()
{
$form = new CityForm();
$viewData = array(
'form' => $form
);
return new ViewModel($viewData);
}
Finally in view I echo it like this:
<?php $title = 'Add New City'; ?>
<?php $this->headtitle($title); ?>
<h1><?php echo $this->escapehtml($title); ?></h1>
<?php $form = $this->form; ?>
<?php $form->setAttribute('action', $this->url('city', array('action' => 'add'))); ?>
<?php $form->prepare(); ?>
<?php
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('name'));
echo $this->formRow($form->get('province'));
echo $this->formRow($form->get('country'));
echo $this->formRow($form->get('coordinate'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
?>
What I expected to see is a vertical form like this:
But what i got is an ugly form like this:
What's wrong with my code? Please help.
EDIT:
When I inspect element, the form generated is strange. The <input> element is inside the <label> element.
<form id="city" name="city" method="post" action="/karciscus/public/admin/city/add">
<input type="hidden" value="" name="id">
<label>
<span>Name</span><input type="text" value="" name="name">
</label>
<label>
<span>Province</span><input type="text" value="" name="province">
</label>
<label>
<span>Country</span><input type="text" value="" name="country">
</label>
<label>
<span>
Coordinate</span><input type="text" value="" name="coordinate">
</label>
<input type="submit" value="Save" id="submitButton" name="submit">
</form>
I'm pretty sure it is the cause of my ugly rendered form. I think it is not supposedly like that. How to fix it?
That's something you have to do in your css.
Give your label a fixed width/length will align them correctly.
If you want to achieve your example above, add display:block for labels then they will each take a full line, like a block element.
Fixed. For other who has the same experience with me, just add element id in form class:
$this->add(array(
'name' => 'name',
'attributes' => array(
'type' => 'text',
'id' => 'name', // Must have id, will render strange otherwise!
),
'options' => array(
'label' => 'Name',
),
));
This fixes the issue for me.
Use the built in twitter bootstrap css which comes with Zf2. Use divs to render your form elements. I understand that everyone thinks about the form data that you set on your .html is pure php data and you cant align it.
<div class="row">
<?php $title = 'Add New City'; ?>
<div>
<div class="row">
<?php $this->headtitle($title); ?>
<h1><?php echo $this->escapehtml($title); ?></h1>
<?php $form = $this->form; ?>
<?php $form->setAttribute('action', $this->url('city', array('action' => 'add'))); ?>
<?php $form->prepare(); ?>
<?php
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('name'));
echo $this->formRow($form->get('province'));
echo $this->formRow($form->get('country'));
echo $this->formRow($form->get('coordinate'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
?>
</div>
Thats the sample....try doing what you like just like what i have shown above and you are good to go.
I have a foreach that show many forms with the same action ending with diferente id's.
But, the tag <form> just appears in the first form. All others, the fields appears, but don't the <form>
I tried to put the id for the form different in the loop. But doesn't work.
The code:
<?php echo $this->Form->create(null, array(
'url' => array('controller' => 'menus', 'action' => 'aprovar', $procuracao['Attorney']['id']), 'id' => $procuracao['Attorney']['id']
)); ?>
<div class="control-group">
<label class="control-label">Alçada:</label>
<div class="controls">
<?php echo $this->Form->input ('alcada', array('type' => 'select', 'label' => FALSE, 'options' => array(
'Até 10.000' => 'Até 10.000',
'Até 50.000' => 'Até 50.000',
'Acima de 100.000' => 'Acima de 100.000',
'Acima de 500.000' => 'Até 500.000',),
'empty' => 'Selecione')); ?>
</div>
</div>
<div class="control-group">
<label class="control-label">Validade:</label>
<div class="controls">
<?php echo $this->Form->input('validade', array('label' => FALSE, 'type' => 'text')); ?>
</div>
</div>
<?php echo $this->Form->submit('Ok', array('class' =>'btn btn-success pull-left', 'div' => false)); ?>
</div>
The field "Alçada" and "Validade" appears correctly. But the tag <form> just appears in the first element.
You are not ending the form.
echo $this->Form->create(null, array(
'id' => 'your-form-'.$i, //that $i is the index of the foreach, for example
'url' => array('controller' => 'menus', 'action' => 'aprovar', $procuracao['Attorney']['id']), 'id' => $procuracao['Attorney']['id']
));
//all inputs and other stuff
echo $this->Form->end(array('label'=>'Ok', 'class' =>'btn btn-success pull-left', 'div' => false));
all that inside the foreach you're using.
Here is the reference of that function in the docs. But basically, it does this
Closes an HTML form, cleans up values set by FormHelper::create(), and
writes hidden input fields where appropriate