I'm using YiiConditionalValidator.php extension to Yii 1.1.20.
I want to have required field (master_id) when i switch button (is_master) from 1 to 0 ...
is_master - 1 or 0
master_id - if "is_master" = 0 make "master_id required...
So... my model rule looks like this:
public function rules()
{
return [
['is_master', 'required'],
['is_master', 'validators.YiiConditionalValidator',
'if' => [
['is_master', 'compare', 'compareValue'=> "0"],
],
'then' => [
['master_id', 'required'],
],
],
['is_master, master_id', 'safe', 'on' => 'search'],
];
}
And in my form i have this options set:
'enableAjaxValidation' => false,
'enableClientValidation' => true,
'clientOptions' => array(
'validateOnChange' => true,
'validateOnSubmit' => true,
),
It seems like my $form cant see this conditional rule...
Thanks for any Help!
While no one knows ^____^ ... I made little research and the answer is that in YiiConditionalValidator.php one function is missing...
When you look at yii 1.1.x framework/validators most of them have 2 functions:
protected function validateAttribute($object,$attribute)
and
public function clientValidateAttribute($object,$attribute)
And that's why YiiConditionalValidator.php isn't working on client side because it lacks public function clientValidateAttribute($object,$attribute) which "Returns the JavaScript needed for performing client-side validation"...
If you want to know how does it look like check your project folder/framework/validators
Best Regards!
Tom
Related
I have 2 models: Order and Product, each has belongsToMany with pivot set properly.
In OrderCrudController, I also use FetchOperation and make a fethProducts() function as below:
use \Backpack\CRUD\app\Http\Controllers\Operations\FetchOperation;
public function fetchProducts()
{
return $this->fetch([
'model' => \App\Models\Product::class,
'searchable_attributes' => ['name','sku']
]);
// return $this->fetch(\App\Models\Product::class); <-- I also tried this one
}
protected function setupCreateOperation()
{
CRUD::setValidation(OrderRequest::class);
// other fields
$this->crud->addField([
'name' => 'products',
'type' => 'relationship',
'pivotSelect' => [
'attribute' => 'name',
'ajax' => true,
],
'subfields' => [
[
'name' => 'quantity',
'type' => 'number',
],
],
]);
}
But it comes to unexpected behavior when I search the product, the select2 field remains "searching" though the request successfully retrieved the data.
screenshot - select2 field
screenshot - ajax results
PS: this field works perfectly without subfields, no vendor overrides etc., so I think I've set everything correctly.
Anyone can help?
This was asked two months ago but somehow I missed it, just noticed it today after someone opened an issue on the GitHub repository.
I am happy you guys found a solution for it but unfortunatelly I cannot recommend it as using the select2_from_ajax will miss the functionality to don't allow the selection of the same pivots twice, otherwise you will have undesired consequences when saving the entry.
I've just submitted a PR to fix this issue, I will ping you guys here when it's merged, probably by next Monday.
Cheers
I just came accross this exact problem and after quite some research and trials, i finally found a solution !
The problem seems to be related to the relationship field type inside the pivotSelect. Try to use select2_from_ajax instead and don't forget to set method to POST explicitly, that worked for me like a charm.
Here is what you might try in your case :
$this->crud->addField([
'name' => 'products',
'type' => 'relationship',
'pivotSelect' => [
'attribute' => 'name',
'type' => 'select2_from_ajax',
'method' => 'POST',
'data_source' => backpack_url('order/fetch/products') // Assuming this is the URL of the fetch operation
],
'subfields' => [
[
'name' => 'quantity',
'type' => 'number',
],
],
]);
I have this working in GridView:
[
'attribute' => 'attribute',
'value' => function ($model) {
return \Yii::$app->formatter->{$model->format}($model->attribute);
},
],
I want to implement basically the same but into DetailView:
[
'attribute' => 'attribute',
'value' => \Yii::$app->formatter->{$model->format}($model->attribute),
],
$model->format is coming from DB and is e.g. asDecimal.
In DetailView I'm getting the following error:
PHP Fatal Error – yii\base\ErrorException
Method name must be a string
How can I avoid this problem? Can you please point me to the right direction? Thank you!
UPDATE: it's also not working in index pages. It's working only in views, generated with giiant, in gridviews of related data. I see these are somehow strange echoed gridviews, but what is the key difference between a normal gridview, and the one like that:
<?=
'<div class="table-responsive">'
. \yii\grid\GridView::widget([
'layout' => '{summary}{pager}<br/>{items}{pager}',
'dataProvider' => new \yii\data\ActiveDataProvider([
Since Yii 2.0.11 you can use closures in DetailView in the same way as in GridView:
[
'attribute' => 'attribute',
'value' => function ($model) {
return \Yii::$app->formatter->{$model->format}($model->attribute);
},
],
https://www.yiiframework.com/doc/guide/2.0/en/output-data-widgets#detail-view
I have an issue with a Gridview using kartik\grid\EditableColumn, after changing the value I am returned the wrong value for the column when it updates. I am returned the dropdown key/main table integer rather than the string contained in a linked table.
I have two tables
Leads - columns id and status_id
Related fields - model, field, related_value, related_value
The relation is based on in this case
model:"Leads",
field:"status_id",
related_id:status_id
I have the following relation in my model
public function getStatus()
{
return $this->hasOne(RelatedFields::className(), ["related_id" => "status_id"])->andOnCondition(["status.field" => "status_id", "status.model"=>"Leads"])->from(["status" => RelatedFields::tableName()]);
}
I also created the following as a test based on this link
public function getStatusValue()
{
return $this->status->related_value;
}
Here is the column code
[
'class' => 'kartik\grid\EditableColumn',
'attribute' => 'status_id',
'value'=>'status.related_value',
//'value' => function($model){ return $model->status->related_value; },
//'value' => function($model){ return $model->StatusValue; },
//'refreshGrid' => true,//Works but not nice
'vAlign'=>'middle',
'hAlign'=>'center',
'pageSummary' => true,
'readonly' => false,
'width'=>'10%',
'filter'=>Html::activeDropDownList($searchModel, 'status', ArrayHelper::map(RelatedFields::Find()->where(['model' =>"Leads","field"=>"status_id"])->all(), 'related_id', 'related_value'),['class' => 'form-control','prompt' => Yii::t('app', '')]),
'editableOptions'=> [
//'attribute'=>'status_id',
//'value'=>'status.related_value',
//'header' => 'profile',
//'format' => Editable::FORMAT_BUTTON,
'inputType' => Editable::INPUT_DROPDOWN_LIST,
'data'=> ArrayHelper::map(RelatedFields::Find()->where(['model' =>"Leads","field"=>"status_id"])->all(), 'related_id', 'related_value'),
]
],
Commented out are a number of lines in my attempts to fix the issue as well as combinations of them, however all result in the wrong value.
If for example I select the related value "New" which has a related_id 1, after the column has been updated I get the value 1 instead of "New".
When the table is first loaded/reloaded the value does show correctly.
I could reload the grid, but this seems wrong just to fix 1% of the data shown on the page.
I your model take a public variable $status_value
create an assigning value method
public function getStatusValue()(){
return $this->status_value= $this->status->related_value;
}
Now in Gridview use getStatusValueenter code heremethod with assigning value as below
use yii\helpers\Url;
$gridColumns = [
[
'class' => 'kartik\grid\EditableColumn',
'attribute' => 'status_value',
'pageSummary' => true,
'readonly' => false,
'value' => function($model){ return $model->statusValue; }, // assign value from getStatusValue method
'editableOptions' => [
'header' => 'status_value',
'inputType' => kartik\editable\Editable::INPUT_TEXT,
'options' => [
'pluginOptions' => [
]
]
],
],
];
If you follow Kartik guide, he suggest to add EditableColumnAction to better handle the editable column:
The EditableColumnAction offers a quick easy way to setup your
controller action for updating, saving and managing the EditableColumn
output from GridView. This action class extends from yii\rest\Action
and hence all properties available with yii\rest\Action are applicable
here. The basic setup of the column involves setting up the controller
action and the EditableColumn.
So you need to add an EditableColumnAction in your controller to handle the update of the model:
public function actions()
{
return ArrayHelper::merge(parent::actions(), [
'edit-lead' => [
'class' => EditableColumnAction::class,
'modelClass' => Leads::class
]
]);
}
In your GridView editable column configuration, include the above
controller action for processing the Editable within editableOptions.
For example
And in your column code you need to add the action to editableOptions property:
'editableOptions' => [
...
'formOptions' => ['action' => ['/leads/edit-lead']]
]
Now, according to the guide, you can add to your action the outputValue property:
'outputValue' => function (Leads $model) {
return $model->status->related_value;
}
I want to display the name instead of ID in the DetailView.
I have done similar on what I did in the GridView which is:
[
'attribute' => 'employee_id',
'value' => 'employee.employee_name'
],
But if I try it on DetailView it displays "employee.employee_name" not the Employee Name
Here's my model:
public function getEmployee()
{
return $this->hasOne(Employee::className(), ['id' => 'employee_id']);
}
I've already found the answer I have just read the Yii2 documentation.
The solution is
[
'attribute' => 'employee_id',
'value' => $model->employee->employee_name,
],
I hope this also help the others.
There is even more simpler one line solution
[
'attribute' => 'employee.employee_name'
],
In GridView, you can show the name using the "employee.employee_name" approach.
But "DetailView" Approach is different. You must use the $model approach, which is shown below.
$model->your_relation_name(without prefixing "action")->field_name
//e.g.
[
'attribute'=> 'Employee Name',
'value'=>$model->employee->employee_name;
]
I use yii-jui to add some UI elements in the views such as datePicker. In the frontend\config\main-local.php I set the following to change the theme used by the JqueryUI:
$config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'gjhgjhghjg87hjh8878878',
],
'assetManager' => [
'bundles' => [
'yii\jui\JuiAsset' => [
'css' =>
['themes/flick/jquery-ui.css'],
],
],
],
],
];
I tried the following to override this configuration item in the controller actions method:
public function actions() {
Yii::$app->components['assetManager'] = [
'bundles' => [
'yii\jui\JuiAsset' => [
'css' =>
['themes/dot-luv/jquery-ui.css'],
],
],
];
return parent::actions();
}
Also I tried to set the value of Yii::$app->components['assetManager'] shown above to the view itself (it is partial view of form _form.php) and to the action that calls this view (updateAction). However, all this trying doesn't be succeeded to change the theme. Is there in Yii2 a method like that found in CakePHP such as Configure::write($key, $value);?
You should modify Yii::$app->assetManager->bundles (Yii::$app->assetManager is an object, not an array), e.g.
Yii::$app->assetManager->bundles = [
'yii\jui\JuiAsset' => [
'css' => ['themes/dot-luv/jquery-ui.css'],
],
];
Or if you want to keep other bundles config :
Yii::$app->assetManager->bundles['yii\jui\JuiAsset'] = [
'css' => ['themes/dot-luv/jquery-ui.css'],
];
You are going about this all wrong, you want to change the JUI theme for 1 controller alone because of a few controls. You are applying 2 css files to different parts of the website that have the potential to change styles in the layouts too. The solution you found works but it is incredibly bad practice.
If you want to change just some controls do it the proper way by using JUI scopes.
Here are some links that will help you:
http://www.filamentgroup.com/lab/using-multiple-jquery-ui-themes-on-a-single-page.html
http://jqueryui.com/download/
In this way you are making the website easier to maintain and you do not create a bigger problem for the future than you what solve.