Yii2. Generate ul list directly from SearchModel - sql

I need following output:
<ul>
<li class="active">Value 1</li>
<li>Value 2</li>
<li>Value 3</li>
<li>Value 4</li>
<li>Value 5</li>
...
</ul>
where Value is a data from a data base (DB) (value of some field for example). Is it possible to get recodrs from DB already inserted to some predefined string?

I think you are needing this.
Use ArrayHelper to create an array to store all the data from certain model.
<?php
use yii\helpers\ArrayHelper;
$dataFromDBTable = ArrayHelper::map(ModelName::find()->all(), 'id', 'name');
?>
<ul>
<?php foreach ($dataFromDBTable as $id => $name) { ?>
<li><?=$name?></li>
<?php } ?>
</ul>

Better use Html to create list. Example:
<?=yii\helpers\Html::u($items, $options); ?>

I used ListView with 'tag' => false:
<?=
ListView::widget([
'dataProvider' => $dataProvider,
'options' => ['tag' => false],
'itemOptions' => ['tag' => false],
'layout' => "\n{items}",
'itemView' => function ($model, $key, $index, $widget) {
return $this->render('_specialization_li',['model' => $model, 'index' => $index]);
},
]);
?>
Inside _specialization_li I wrote:
<li><?= $model->name_ ?></li>
Also there is a bugfix for 'tag'=>false on github:
https://github.com/pkirill99/yii2/commit/528b97183591376da80ee168a2a1132ea36f33cf

Related

Yii2 How can I display Activeform radioList data on screen?

I have not experience with Yii2.
I would like to be able to show the result of a form on the screen.
With the fields name and email I have no problem but I can not show the selection
that I make of my radioList.
I have tried many methods but none works.
Can you help me please?
These are my files.
SiteController.php
public function actionEntry()
{
$this->layout = 'print';
$model = new EntryForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
return $this->render('entry-confirm', ['model' => $model]);
} else {
return $this->render('entry', ['model' => $model]);
}
}
EntryForm.php
namespace app\models;
use Yii;
class EntryForm extends \yii\db\ActiveRecord
{
public $name;
public $email;
public $category;
public function rules()
{
return [
[['name', 'email'], 'required'],
['email', 'email'],
];
}
entry.php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'category')->radioList([
1 => 'radio 1',
2 => 'radio 2'
]);
?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
entry-confirm.php
<p>You have entered the following information:</p>
<ul>
<li><label>Name</label>: <?= Html::encode($model->name) ?></li>
<li><label>Email</label>: <?= Html::encode($model->email) ?></li>
<li><label>Category</label>: <?= Html::encode($model->category) ?></li>
</ul>
This is the image with the problem:
In model extending ActiveRecord you must never explicitly define properties that are the same as names of columns in DB.
You must define at least one validation rule for each attribute that is set by the end user, otherwise system will not allow to set it.

How to get last insert record - Yii 2

I am making application to create barcode
in my application, i want to create Barang but in issue slip i want issue slip filled automatically from the last issue slip
what can i do to fix it?
this is my view
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $model backend\models\Barang */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="barang-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'rm_code')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'nama_barang')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'berat')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'issue_slip')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<div class="row">
<?= $form->field($model, 'berat')->textInput(['maxlength' => true]) ?>
<?php echo \Yii::$app->db->getLastInsertId('{{barang}}');?>
</div>
In controller before render
public function actionCreate()
{
$model = new Barang();
$modelForSlip = Barang::find()->orderBy(['id'=> SORT_DESC])->one();
$model->issue_slip = $modelForSlip->issue_slip;
if ($model->load(Yii::$app->request->post())){
$model->waktu = date('Y-m-d h:m:s');
$model->user = \Yii::$app->user->identity->username;
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
//$model->issue_slip= \Yii::$app->db->getLastInsertId();
}
}
Let say this is your create function:
public function actionCreate()
{
$model = new Modal();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['update', 'id' => $model->Id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
then redirect to new page with last inserted ID
Now make you update function like this
public function actionUpdate($id)
{
$model2 = Model::findOne($id);
$model = new Modal();
$model->issue_slip = $model2['issue_slip'];
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->Id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
In YII2 you can get last inserted record after save() function easily
like
$model->save();
echo $model->Id
or whatever column you want to get
instead of issue_slip you can use whatever column you want

Onsubmit call function in yii

I want to call function when submit form in yii. In my form I enabled validateOnSubmit.
when in call function form Onsubmit mean it will call function in twice.
My Coding,
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'question-form',
// Please note: When you enable ajax validation, make sure the corresponding
// controller action is handling ajax validation correctly.
// There is a call to performAjaxValidation() commented in generated controller code.
// See class documentation of CActiveForm for details on this.
'enableAjaxValidation' => true,
'enableClientValidation' => false,
'clientOptions' => array(
'validateOnSubmit' => true,
'validateOnChange' => false,
),
'htmlOptions' => array('onsubmit' => 'return checkmultiple()',),
));
?>
<div class="form-group">
<?php echo $form->labelEx($model, 'question_title'); ?>
<?php echo $form->textField($model, 'question_title', array('size' => 50, 'maxlength' => 250, 'class' => 'form-control')); ?>
<?php echo $form->error($model, 'question_title'); ?>
</div>
<?php if ($tileAssigned == Yii::app()->const->FLAG_ZERO) { ?>
<div class="form-group">
<?php echo $form->labelEx($model, 'type', array('label' => 'Is Multiple Choice')); ?>
<?php echo $form->radioButtonList($model, 'type', $yesnoList, array('separator' => '', 'onchange' => 'questionTypeChange(this.value);', 'class' => '')); ?>
<?php echo $form->error($model, 'type'); ?>
</div>
I am calling function checkmultiple mean it will call twice.
function checkmultiple()
{
}

Bootstrap3 Modal not working with GridView's pjax

I have a following GridView, but unfortunately Bootstrap modal isn't working properly if I have used Pjax pagination or search. Well, the modal does show up, but it won't submit the form. And when I leave the modal out of Pjax(), then it isn't loaded at all.
Pjax::begin(['id' => 'pjax_id', 'timeout' => false, 'enablePushState' => false]);
echo GridView::widget([
'dataProvider' => $details,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
['format' => 'raw',
'label' => 'Category',
'value' => function ($data) {
$string = '';
foreach ($data['Category'] as $category) {
$string .= $category->category_name . '<br/>';
}
return $string;
}],
'book_name',
['format' => 'raw',
'contentOptions' => ['class' => 'form-cell'],
'label' => '',
'value' => function ($data) {
$buttons = Html::button('Edit', ['class' => 'btn btn-default mleft modallink', 'data-toggle' => 'modal', 'data-target' => '#'.$data->cat_id]);
return $buttons;
}
],
[
'format' => 'raw',
'label' => '',
'value' => function ($data) {
if (Yii::$app->user->identity->user_type == 'admin') {
$string = '</span>';
$string .= '<a class=\'mleft\' href=\''.Url::to(['category/update', 'id' => $data->cat_id]).'\'><span class="glyphicon glyphicon-pencil"></span></a>';
return $string;
}
}
],
],
]);
$details = $details->getModels();
foreach ($details as $detail) {
?>
<div class="modal fade" id="<?= $detail->cat_id ?>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel"><?= $detail->category_name ?></h4>
</div>
<div class="modal-body">
<?php
echo Html::beginForm(Url::to(['category/details', 'id' => $detail->cat_id]), 'post', ['id' => 'popup']);
echo Html::beginTag('div', ['class' => 'form-group']);
echo Html::activeLabel($detail, 'cat_description');
echo Html::activeTextarea($detail, 'cat_description', ['class' => 'form-control']);
echo Html::endTag('div');
echo Html::beginTag('div', ['class' => 'form-group']);
echo Html::activeLabel($detail, 'link');
echo Html::activeInput('text', $detail, 'link', ['class' => 'form-control']);
echo Html::endTag('div');
echo Html::beginTag('div', ['class' => 'form-group']);
echo Html::activeLabel($detail, 'resource');
echo Html::activeInput('text', $detail, 'resource', ['class' => 'form-control']);
echo Html::endTag('div');
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<?= Html::submitButton('Submit', ['class' => 'btn btn-success']) ?>
<?= Html::endForm(); ?>
</div>
</div>
</div>
</div>
<?php
}
Pjax::end();
So how do I keep GridView's Pjax functionality so that the modal still works?
Pjax widget has a formSelector attribute that, by default, will find all forms with data-pjax attribute set to something not falsy.
The easiest way to fix your form is to add that attribute to your form definition:
echo Html::beginForm(
Url::to(['category/details', 'id' => $detail->cat_id]),
'post',
[
'id' => 'popup',
'data-pjax' => 1,
]
);

How create file input at form, which upload file and write link in database

I'm trying to learn Yii2 by writing my own cms.
I want realize attachment photo for shop items. I don't know right way to do this, but i think it's should be so -
On save, files which was selected in multiple file input are uploads to server.
Get the url by each photo
Write links in database cell by template
<div class="itemImgs">
<img class="0" src="{link}"> <!-- first -->
<img class="1" src="{link}"> <!-- second -->
<img class="..." src="{link}"> <!-- ... -->
</div>
Please, help me understand, what i must write in model and\or controller, if its right way. Else, please tell me how should to do it.
Thanks.
UPD
Action in controller:
public function actionCreate() {
$model = new ShopItems();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'category' => ShopCategories::find()->all()
]);
}
}
Model contain this functions:
public function behaviors() {
return [
TimestampBehavior::className(),
];
}
/** #inheritdoc */
public static function tableName() {return 'shop_items';}
/** #inheritdoc */
public function rules() {
return [
[['category_id', 'title', 'desc', 'price', ], 'required'],
[['category_id', 'price', 'in_stock', 'discount',], 'integer'],
[['desc', 'options',], 'string'],
[['photos',], 'file', 'maxFiles' => 10],
[['title'], 'string', 'max' => 100]
];
}
/** #inheritdoc */
public function attributeLabels() {
return [
'id' => 'ID',
'category_id' => 'Категория',
'title' => 'Название',
'desc' => 'Описание',
'price' => 'Цена',
'discount' => 'Скидка %',
'in_stock' => 'На складе',
'photos' => 'Фото',
'options' => 'Опции',
'created_at' => 'Дата добавления',
'updated_at' => 'Последнее редактирование',
];
}
And the view _form.php:
<?php $form = ActiveForm::begin(); ?>
<div class="col-lg-6">
<?= $form->field($model, 'title')->textInput(['maxlength' => 100]) ?>
<?= $form->field($model, 'desc')->textarea(['class' => 'ckeditor',]); ?>
</div>
<div class="col-lg-6">
<?= $form->field($model, 'category_id')->dropDownList(
ArrayHelper::map($category, 'category_id', 'category_name')
) ?>
<?= $form->field($model, 'price')->textInput() ?>
<?= $form->field($model, 'discount')->textInput() ?>
<?= $form->field($model, 'in_stock')->textInput() ?>
<?= $form->field($model, 'photos[]')->fileInput(['multiple' => true]) ?>
<?= $form->field($model, 'options')->textInput() ?>
</div>
<div class="clearfix"></div>
<div class="col-xs-12">
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Добавить' : 'Принять изменения', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
See documentation - http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html#uploading-multiple-files
In controller:
if ($model->file && $model->validate()) {
foreach ($model->file as $file) {
$file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
}
}
Input model Photo:
if ($model->file && $model->validate()) {
foreach ($model->file as $file) {
$path = 'uploads/' . $file->baseName . '.' . $file->extension;
$file->saveAs($path);
$photo = new Photo();
$photo->path = $path;
$photo->save();
}
}
Photo table like that:
CREATE TABLE `photo` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`path` VARCHAR(255) NOT NULL ,
`status` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
ENGINE=InnoDB;
Get photos use:
$photos = Photo::find()->all();
In view:
<div class="itemImgs">
<?php foreach ($photos as $k=>$photo) ?>
<img class="<?= $k ?>" src="<?= $photo->path ?>"/><br/>
<?php } ?>
</div>
EDIT
Set in controller
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$files = UploadedFile::getInstances($model, 'file');
$photosArr = [];
foreach ($files as $file) {
$path = 'uploads/' . $file->baseName . '.' . $file->extension;
$file->saveAs($path);
$photosArr[] = $path;
}
$model->photos = Json::encode($photosArr);// better put json in afterSave
$model->save(false);// because validate() run before
return $this->redirect(['view', 'id' => $model->id]);
}
In field photos you get JSON with path for uploaded photos. In view:
$arr = Json::decode($model->photos); // better put in afterFind()
foreach ($arr as $path) {
echo '<img src="'.$path.'">';
}