I need some help with a postLink created with FormHelper in CakePHP 3. The normal postLink works just fine like this:
<?= $this->Form->postLink(__('Delete'),
['action' => 'delete', $member->id],
['confirm' => __('Are you sure, you want to delete {0}?', $member->name)]) ?>
But when I try to use a font-awesome icon / i-tag instead of the text link, the confirmation message is not showing up anymore. The icon itself is showing correctly and the action still works fine, just the message is not working.
I used the following posts for help, but the examples in the answers there are not working for me:
CakePHP equivalent of html code
CakePHP delete confirmation
I tried these two approaches:
<?= $this->Form->postLink('<i class="fa fa-trash"></i> ',
['action' => 'delete', $member->id],
['escape' => false],
['confirm' => __('Are you sure, you want to delete {0}?', $member->name)]) ?>
<?= $this->Form->postLink(
$this->Html->tag('i', '', ['class' => 'fa fa-trash']),
['action' => 'edit', $member->id],
['escape' => false],
['confirm' => __('Are you sure you want to delete {0}?', $member->name)]); ?>
I'm still very new to CakePHP and tried to look this up in the book, but that did not help me. I also tried the exact syntax as shown in the SO links above, which seemingly worked for some others...but the confirmation message is still not working for me.
What am I doing wrong here?
escape and confirm options should be in the same array. Function postLink() looks like this:
postLink(string $title, mixed $url = null, array $options =[])
So working code for you will be:
<?= $this->Form->postLink('<i class="fa fa-trash"></i> ',
['action' => 'delete', $member->id],
[
'escape' => false,
'confirm' => __('Are you sure, you want to delete {0}?', $member->name)
]
) ?>
Related
I want form data updated after ajax save. Cause if item was new (id - empty), it tries to create new one each time. Also there are back-end generated fields which are appears after save.
<?php $form = ActiveForm::begin([
'method' => 'post',
'action' => ['category/save', 'id' => $category ? $category->id : ''],
'enableClientValidation' => true,
// 'enableAjaxValidation' => false,
'validateOnChange' => false,
'validateOnBlur' => false,
'validateOnSubmit' => true,
'options' => [
'id' => 'customer-update',
'class' => 'ajax-submit',
],
'fieldConfig' => [
'template' => '<div class="row-content-col1">{label}</div><div class="row-content-col2">{input}{error}</div>'
]
]); ?>
.......
<?php echo $form->field($category, 'url')->textInput(['class' => 'ip', 'readonly' => true]); ?>
......
<?php $form->end(); ?>
Form field produce such html:
<div class="row-content-col1"><label class="control-label" for="category-url">Url</label></div><div class="row-content-col2"><input type="text" id="category-url" class="ip" name="Category[url]" readonly><div class="help-block"></div></div>
</div>
And than on controller i return this (tried different variations):
{"error":false,"message":"Category 'asdfzsdf sdf' saved","data":{"name":"asdfzsdf sdf","url":"asdfzsdf-sdf","project_id":1,"id":21}}
What is valid response for ajax form? Or is there other way to handle this all ?
Pjax is really useful for your challenge, Just add your form inside of Pjax widget. add form action to new path(such: site/control-data).
In your action method do what you want, but send response like that :
return $this->renderAjax('form path',$model);
It's the general of what you must do.
But maybe you have problem with jquery or pjax or need some more data, but all questions have an answer,
See Pjax for ActiveForm
I am trying to display a link in error message in login for, but it is not working.
The error message in LoginForm valdiation:
$this->addError($attribute, 'Your account has been disabled. Enable It');
In login.php (view):
<?= $form->errorSummary($model); ?>
I tried like below, but not working:
<?= $form->errorSummary($model,['errorOptions' => ['encode' => false,'class' => 'help-block']]); ?>
I am getting the following output instead of rendered a tag:
You need to disable encoding at ActiveForm level using encodeErrorSummary property, if you want to use $form->errorSummary($model):
<?= $form = ActiveForm::begin([
'id' => 'login-form',
'encodeErrorSummary' => false,
'errorSummaryCssClass' => 'help-block',
]) ?>
<?= $form->errorSummary($model) ?>
Alternatively you may use Html::errorSummary() directly:
<?= Html::errorSummary($model, ['encode' => false]) ?>
The view that is rendered from the controller has a Pjax begin and end tags:
Pjax::begin([
'id' => 'pjax-questions-list',
'enablePushState' => false,
'clientOptions' => [
'method' => 'get'
],
]);
Inside the Pjax it renders two nested views:
<div class="body">
<?php
echo $this->render('_questions_search', ['model' => $searchModel, ' questionary' => $questionary]);
echo $this->render('_questions_list', ['dataProvider' => $dataProvider, 'model' => $searchModel]);
?>
</div>
Inside the nested view there is a delete question link:
<li>
<a class="waves-effect waves-block" data-pjax="0"
href="<?= Url::to(['question/delete', 'id' => $model->id]) ?>">Delete</a>
</li>
When that link is clicked, the delete action method is called twice. Moreover, this issue is hard to notice when the Pjax is outside of the view that contains the link (i.e. nested views). Because of this issue the redirect after successfull delete doesn't work and instead a 404 not found error is found (tries to delete the same id twice).
How can i fix the double redirect?
You can fix the double redirect by adding the following attribute to your link which is located inside Pjax:
data-pjax="0"
In my case i reused the nested view by deleting the grid view and replacing it with ul with links, and of course forgot to remove the unneeded Pjax in the outer view. After that the issue appeared. It was hard to notice that it was calling the action method twice.
I need to have Body: (with colon at the end), not Body rendered as label for each field in my form. How can I achieve this the best way?
I tried modifying fieldConfig => template in ActiveForm::begin by adding div class=\"\">{label}:</div> into it:
<?php $form = ActiveForm::begin([
'id' => 'edit-form',
'options' => ['class' => 'form-horizontal'],
'fieldConfig' => [
'template' => "<div class=\"\">{label}:</div>\n<div class=\"\">{input}</div>\n<div class=\"\">{error}</div>",
'labelOptions' => ['class' => 'edit-label'],
]]); ?>
but it is wrong. Colon is rendered as separate DOM element, with incorrect styling and looks ugly.
I tried doing this awfully in CSS:
.edit-label::after {
content: ":";
}
but this is even worse.
I remember, that I made a lot of stupid things in Yii1 to get this. I don't want to repeat these stupid things, when implementing this in Yii2. What is the best way of achieving this?
When using Bootstrap 3 (yii\bootstrap\ActiveField) you can use additional placeholders in the $template and you need to replace {label} with {beginLabel}{labelTitle}:{endLabel}:
<?php $form = ActiveForm::begin([
'id' => 'edit-form',
'options' => [
'class' => 'form-horizontal',
'enctype'=>'multipart/form-data'
],
'fieldConfig' => [
'template' => "<div class=\"\">{beginLabel}{labelTitle}:{endLabel}</div>\n<div class=\"\">{input}</div>\n<div class=\"\">{error}</div>",
'labelOptions' => ['class' => 'edit-label'],
],
]); ?>
I don't know, how to solve this problem, if you're using basic yii\widgets\ActiveField instead.
I would rather not deal with decorators as my form design is not exactly straight forward, but i would like to keep the functionality of validating the forms.
So i have it set up where sub forms are working correctly, but when i try to style it manually in my viewscript i get the name without the parent. I've seen other posts that are similar, but i haven't found a solution.
Example:
This is in my view script
<?php echo $this->form->username->renderViewHelper();?>
I then get
<input type="text" value="" id="username" name="username">
When rendered. It should be
<input type="text" value="" id="form1-username" name="form1[username]">
How do i get that form1 portion?
Thanks!
Edit
Ok, so i found one way.
By using belongTo, it works:
$form1->addElements(array(
new Zend_Form_Element_Text('username', array(
'belongsTo' => 'form1',
'required' => true,
'label' => 'Username:',
'filters' => array('StringTrim', 'StringToLower'),
'validators' => array(
'Alnum',
array('Regex',
false,
array('/^[a-z][a-z0-9]{2,}$/'))
)
))
));
Is there a better way to do this or is this the only way?
Edit2
public function prepareSubForm($spec){
if (is_string($spec)) {
$subForm = $this->{$spec};
} elseif ($spec instanceof Zend_Form_SubForm) {
$subForm = $spec;
} else {
throw new Exception('Invalid argument passed to ' .
__FUNCTION__ . '()');
}
$this->setSubFormDecorators($subForm)
->addSubmitButton($subForm)
->addSubFormActions($subForm);
return $subForm;
}
public function setSubFormDecorators(Zend_Form_SubForm $subForm){
$subForm->setDecorators(array(
'FormElements', \\<--- I tried to change this to PrepareElements before.
array('HtmlTag', array('tag' => 'dl',
'class' => 'zend_form')),
'Form',
));
return $this;
}
I believe you can get your desired output just by using:
<?php echo $this->form->username; ?>
I get the expected output when calling this without renderViewHelper. This is also without any special code for decorators or preparing sub forms. All I had to do was add belongsTo to the form element.
UPDATED:
If you set this to be your default decorator, you can eliminate the dd/dt tags from rendering, instead it will use a div. Then you may be closer to getting the custom output you want. You can change the tag in HtmlTag from div to whatever tag you would like to wrap your elements in. This is what I use mostly:
array(
'ViewHelper',
'Errors',
array('Description', array('tag' => 'p', 'class' => 'description')),
array('HtmlTag', array('tag' => 'div', 'class' => 'form-div')),
array('Label', array('class' => 'form-label', 'requiredSuffix' => '*'))
);
This is the default for Zend Framework:
array(
'ViewHelper',
'Errors',
array('Description', array('tag' => 'p', 'class' => 'description')),
array('HtmlTag', array('tag' => 'dd', 'id' => array('callback' => $getId)))
array('Label', array('tag' => 'dt'))
);
Note that file, and submit/button elements use different decorators.
Also see this answer