how can I display the images in yii2 - yii2

I have mulltiple images for every product in the db. I have them stored like ["1.jpg,2.jpg,...n.jpg"]. can somebody help me with it? thx in advice. I tried another method by creating a table and storing there every image with the coresponding product id but I don't want to use it like that.
and the _viewGallery is like
<div class='viewGallery'>
<div class='gallery'>
<?php
$imagesArray = explode(',', $model->imagini);
foreach ($imagesArray as $image) {
echo "<img src='kep/{$image}' alt=''>";
}
?>
</div>
</div>
in my view file I have ,
<?= DetailView::widget([
'model' => $model,
'attributes' => [
[
//'imagini:ntext',
'label'=>'Imagini',
'value'=>'<div class="col-md-12">'.$this->render('_viewGallery',['model'=>$model], true)."</div>",
'format' => 'html',
],
],
]) ?>

It sounds like you would need to use the php explode function to split the string into an array and then display the images with a foreach loop.
$imagesArray = explode(',', $model->images);
foreach ($imagesArray as $image) {
echo "<img src='path/{$image}' alt=''>";
}

Related

Strategi must be a string

please help me..
when data input arises such problems "Strategi must be a string."
this is my controller :
$isistrategi = $_POST['FormNarasi'];
$fn = FormNarasi::find()->where([
'kriteria_id' => $model->id,
'form_spmi_id' => $formSpmi->id,
])->one();
if(empty($fn))
$fn = new FormNarasi;
$fn->kriteria_id = $model->id;
$fn->form_spmi_id = $formSpmi->id;
$fn->strategi = $isistrategi;
this is my _form :
<?php
$fn = FormNarasi::find()->where([
'kriteria_id' => $model->id,
'form_spmi_id' => $formSpmi->id
])->one();
echo $form->field($fn, 'strategi')->widget(CKEditor::className(), [
'options' => ['rows' => 6],
'preset' => 'advance'
])
?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success','value'=>'1','name'=>'btn-submit']) ?>
</div>
<?php ActiveForm::end(); ?>
please help, master
Here you are assigning an array to the model
$isistrategi = $_POST['FormNarasi'];
...
$fn->strategi = $isistrategi; // HERE
and in the following code you are accessing it. There is an array assigned. So you should assign there a string (the content of the CKEditor)
echo $form->field($fn, 'strategi')->widget(CKEditor::className(), [ // HERE
...
])
As #Sfili_81 mentioned, do not access the $_POST directly and rather use $model->load(Yii::$app->request->post())

Add block after 3rd list item in a yii2 listview widget

I have not worked with the listview widget before so I cant find a solution for this, as I output a list with items I wanted to do 2 things, 1. auto increment and unique ID/number to each list item, 2. add a block(custom piece of code) after each 3rd list item.
I could not find any documentation about this so not sure if this is possible.
echo ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider
]);
<div id="listofitems">
<div class="list_item_wrapper">
// my items which are in a seperate file
<div class="list_item_wrapper">
// when using the $index to check for a certain number the code will be build here.
</div>
</div>
// the needed solution
if($index == 12 || $index == 12){
echo 'some div here';
}
</div>
You can use the itemView option for the ListView widget where you can either provide
Specify as a callback function ($model , $key , $index , $widget) { and add your custom HTML inside and do your custom operations like check every third item,or use the actual id by calling $model->id and appending it with the html tag attribute, it provides you
$model: mixed, the data model
$key: mixed, the key value associated with the data item
$index: integer, the zero-based index of the data item in the items array returned by $dataProvider.
$widget: ListView, this widget instance
For example
echo ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider,
'itemView'=>function ($model , $key , $index , $widget) {
//Do your Thing with Html you want to draw
//return '<div></div>';
}
]);
Or provide the view file path to the option, you can still use the above given params in the view file
For Example
echo ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider,
'itemView'=>'_view-name'
]);
Your view can look like
<?php
use yii\helpers\Html;
?>
<div class="card">
<div class="header">
<h3 class="title"><?= Html::encode ( $model->title ) ?></h3>
</div>
<div class="body"><img src="<?= Html::encode ( $model->name ) ?>"><?= Html::encode ( $model->id ) ?></div>
<div class="footer"></div>
</div>
UPDATE
If your requirements are to draw or add an element after every item or any number of items you can use the afterItem option which takes an anonymous function that is called once AFTER rendering each data model, it passes same set of parameters as beforeItem
$model: the current data model being rendered
$key: the key value associated with the current data model
$index: the zero-based index of the data model in the model array returned by $dataProvider
$widget: the ListView object
UPDATE2
The below should work in your case with the given HTML
<div id="listofitems">
<?php
echo ListView::widget ( [
'id' => 'listofitems' ,
'dataProvider' => $dataProvider ,
'afterItem=' > function($model , $key , $index , $widget) {
// the needed solution
if ( $index == 12 || $index == 12 ) {
return 'some div here';
}
} ,
'itemView' => function ($model , $key , $index , $widget) {
//Do your Thing with Html you want to draw
return '<div class="list_item_wrapper">
// my items which are in a seperate file
<div class="list_item_wrapper">
// when using the $index to check for a certain number the code will be build here.
</div>
</div>
';
}
] );
?>
</div>
There is such an index by default in the widget. Configure the 'itemView' attribute of the ListView widget, that means you can use a custom view which will be rendered for each item. Like this:
<?= ListView::widget([
'id' => 'listofitems',
'dataProvider' => $dataProvider,
'itemView' => '/site/item',
?>
in your view file /site/item.php, you can access the index of the current item:
<?php
var_dump($index);
?>
More info about the itemView property here.

Select2 and DepDrop in dynamic form in yii2

I'm trying to use Select2 and depdrop within a dynamic form. For the first row it's working only. But on the next row I'm getting following error.
When I'm using select2 without depfrop it works fine.
Code of form (of select2 and depdrop field)
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($modelsProductsales, "[{$i}]productname")->label(false)->widget(Select2::classname(), [
'data' => ArrayHelper::map(Productbatch::find()->orderBy('productname')->all(),'productname','productname'),
'language' => 'en',
'options' => ['placeholder' => 'Select Product','id' => 'prodname'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, 'batchno')->label(false)->widget(DepDrop::classname(), [
//'options'=>['id'=>'subcat-id'],
'pluginOptions'=>[
'depends'=>['prodname'],
'placeholder'=>'Batch No',
'url'=>Url::to(['/invoice/bills/subcat'])
]
]); ?>
Code of subcat action
public function actionSubcat() {
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
$out = Productbatch::getBatchNo($cat_id);
echo Json::encode($out);
// the getSubCatList function will query the database based on the
// cat_id and return an array like below:
// [
// ['id'=>'<sub-cat-id-1>', 'name'=>'<sub-cat-name1>'],
// ['id'=>'<sub-cat_id_2>', 'name'=>'<sub-cat-name2>']
// ]
//echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
Please let me know if anymore input from my end is required.
check your codes to find JavaScript codes for the first element that works correctly.you should be add JavaScript codes for all same elements that produces by insert button.
I suggest you to extended another dynamic form from \wbraganca\dynamicform\DynamicFormWidget for your own.Then override registerAssets function and add JavaScripts for other insert handler.
It has problem is yii2-dynamic-form.js file of dynamic form. Same solution work for Select2 and DepDrop both.
solution on following link works for me.
https://github.com/wbraganca/yii2-dynamicform/issues/76#top[Updated Code][1]

Yii2: How to validate a form with multiple instances of the same model

In my form I update more start and end dates from the same model at once. See the simplified form:
<?php $form = ActiveForm::begin(); ?>
<?php foreach($dates as $i=>$date): ?>
<?= $form->field($date,"[$i]start"); ?>
<?= $form->field($date,"[$i]end"); ?>
<?php endforeach; ?>
</table>
<?= Html::submitButton('Save'); ?>
<?php ActiveForm::end(); ?>
In the model I need to control, if the end date is after the start date:
public function rules() {
return [
[['end'], 'compare', 'compareAttribute' => 'start', 'operator' => '>', 'message' => '{attribute} have to be after {compareValue}.‌'],
];
}
I tried to change selectors similarly as described in: Yii2: Validation in form with two instances of same model, but I was not successful. I suppose I need to change the 'compareAttribute' from 'mymodel-start' to 'mymodel-0-start' in the validation JS:
{yii.validation.compare(value, messages, {"operator":">","type":"string","compareAttribute":"mymodel-start","skipOnEmpty":1,"message":"End have to be after start.‌"});}
So, I look for something like:
$form->field($date,"[$i]end", [
'selectors' => [
'compareAttribute' => 'mymodel-'.$i.'-start'
]
])
Solution
The solution is based on the answer of lucas.
In the model I override the formName() method, so for every date I have a unique form name (based on ID for the existing dates and based on random number for new dates):
use ReflectionClass;
...
public $randomNumber;
public function formName()
{
$this->randomNumber = $this->randomNumber ? $this->randomNumber : rand();
$number = $this->id ? $this->id : '0' . $this->randomNumber;
$reflector = new ReflectionClass($this);
return $reflector->getShortName() . '-' . $number;
}
The form then looks like this:
<?php $form = ActiveForm::begin(); ?>
<?php foreach($dates as $date): ?>
<?= $form->field($date,"start"); ?>
<?= $form->field($date,"end"); ?>
<?php endforeach; ?>
</table>
<?= Html::submitButton('Save'); ?>
<?php ActiveForm::end(); ?>
Override the formName() method in your model class to make it unique. If you don't want to change your model class, create a subclass of it for the purpose of working for this controller action. After doing this, the html ID and name fields will automatically be unique.

How to create a dropdown dependent on another dropdown in yii2?

I have two api's:
1: returns all the industries,
2: returns all the industry category(based on industry id).
I need two dropdowns, one dependent on other. On selecting industry 2nd dropdown should show only relevant categories.
Thanks in advance.
I got it. I have simply used ajax which posts the value from one dropdown and sends the data to an action which returns the data and i am simply putting those values to my other drop down. :)
<?= $form->field($model, 'industryId')->dropDownList($industry,
['prompt'=>'Select Industry',
'onchange'=>'
$.get( "'.Url::toRoute('/site/category').'", { id: $(this).val() } )
.done(function( data ) {
$( "#'.Html::getInputId($model, 'industryName').'" ).html( data );
}
);
','class' => 'form-control'
]
); ?>
<?= $form->field($model, 'industryName')
->dropDownList(
['prompt'=>'Select category','class' => 'form-control']);
?>
_form.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\Category;
?>
<?php $form = ActiveForm::begin(); ?>
$model = Category::find()->select('id,name')->orderBy('name asc')->all();
$listData = ArrayHelper::map($model, 'id', 'name');
<?= $form->field($model, 'industryId')->dropDownList($listData,
['prompt'=>'Select Category',
'onchange'=>'
$.get( "'.Url::toRoute('/category/subcats').'", { id: $(this).val() } )
.done(function( data ) {
$( "#'.Html::getInputId($model, 'sub_category').'" ).html( data );
}
);
','class' => 'form-control'
]
); ?>
<?= $form->field($model, 'sub_category')
->dropDownList(
['prompt'=>'Select sub cat','class' => 'form-control']);
?>
----
You can use this extension. You can find explanation of plugin on its guide page.