How add one more button to yii2-widget-fileinput? - file-upload

I want more button in yii2-fileinput-widget.
My current code is like this:
$allPics = \common\models\Picture::getPictures($album->id);
$images = [];
$imagesOptions = [];
if($allPics){
foreach ($allPics as $pic){
$key = $pic->id;
$url = Url::to(['set-pic-status', 'id'=>$key, 'pid'=>$model->id, 'do'=>'remove']);
$images[] = Yii::$app->urlManagerFront->createAbsoluteUrl(['image/index', 'id'=>$pic->id, 'width'=>300, 'height'=>300]);
$imagesOptions[] = ['caption' => $pic->name, 'size' => $pic->size , 'url'=>$url, 'key'=>$key];
}
}
echo FileInput::widget([
'name' => 'pic',
'language'=>'fa',
'options'=>[
'multiple'=>true
],
'pluginOptions' => [
'uploadUrl' => Url::to(['pic-upload', 'id'=>$model->id]),
'initialPreview'=>$images,
'initialPreviewAsData'=>true,
'initialCaption'=>"تصاویر محصول",
'initialPreviewConfig' => $imagesOptions,
'overwriteInitial'=>false,
'maxFileSize'=>2800,
]
]);
And result of top code is:
Now I need add one more button near remove button to send some data to server and set selected picture as cover or change status of picture in db.
How can I do that?

try this:
$initialPreview = [];
$initialPreviewConfig = [];
foreach($model->images as $image){
$initialPreview[] = Html::img($image->imagePath,['width' =>200]);
$initialPreviewConfig[] = [
'url' => \yii\helpers\Url::to(['/admin/portfolio/portfolio/image-delete']),
'key' => $image->ID,
];
}
?>
<br>
<div class="row">
<div class="col-md-12">
<?php
echo FileInput::widget([
'name' => 'ProductImages[]',
'options'=>['accept'=>'image/*','multiple' => true],
'pluginOptions' => [
'otherActionButtons' => '<button class="set-main" type="button" {dataKey} ><i class="glyphicon glyphicon-star"></i></button>',
'overwriteInitial'=>false,
'maxFileSize'=>2800,
'fileActionSettings' => [
'fileActionSettings' => [
'showZoom' => false,
'showDelete' => true,
],
],
'browseClass' => 'btn btn-success',
'uploadClass' => 'btn btn-info',
'removeClass' => 'btn btn-danger',
'showRemove' => false,
'showUpload' => false,
'initialPreview' => $initialPreview,
'initialPreviewConfig' => $initialPreviewConfig,
],
]);
$this->registerJs("
$('.set-main').on('click',function(){
$.get('" . \yii\helpers\Url::to(['/admin/portfolio/portfolio/set-main-image/']) . "', {id:$(this).attr('data-key')});
});
");
?>
</div></div>
<div>
'otherActionButtons' => '...';

Related

Prestashop - Add additional fields on product combination

I'm trying to add additional fields on my product combinations in order to have custom meta titles for the combinations.
So I created this module:
My module definition:
class CombinationCustomFields extends Module
{
public function __construct()
{
$this->name = 'combinationcustomfields';
$this->tab = 'administration';
$this->author = '';
$this->version = '1.0';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Combination Custom Fields');
$this->description = $this->l('Add additional fields on combinations');
$this->ps_versions_compliancy = array('min' => '1.7.1', 'max' => _PS_VERSION_);
}
public function install()
{
if (!parent::install() || !$this->_installSql()
|| !$this->registerHook('displayAdminProductsCombinationBottom')
|| !$this->registerHook('actionAttributeCombinationSave')
) {
return false;
}
return true;
}
public function uninstall()
{
return parent::uninstall() && $this->_unInstallSql();
}
/**
* Add database fields
* #return boolean
*/
protected function _installSql()
{
$sqlInstall = "ALTER TABLE " . _DB_PREFIX_ . "product_attribute "
. "ADD meta_title_fr VARCHAR(255) NULL, "
. "ADD meta_title_en VARCHAR(255) NULL;";
$returnSql = Db::getInstance()->execute($sqlInstall);
return $returnSql;
}
/**
* Remove database fields
* #return boolean
*/
protected function _unInstallSql()
{
$sqlInstall = "ALTER TABLE " . _DB_PREFIX_ . "product_attribute "
. "DROP meta_title_fr, "
. "DROP meta_title_en";
$returnSql = Db::getInstance()->execute($sqlInstall);
return $returnSql;
}
public function hookDisplayAdminProductsCombinationBottom($params)
{
$combination = new Combination($params['id_product_attribute']);
$this->context->smarty->assign(array(
'id_product_attribute' => $params['id_product_attribute'],
'meta_title_fr' => $combination->meta_title_fr,
'meta_title_en' => $combination->meta_title_en,
)
);
return $this->display(__FILE__, 'views/templates/hook/combinationfields.tpl');
}
public function hookActionAttributeCombinationSave($params)
{
$combination = new Combination($params['id_product_attribute']);
$this->context->smarty->assign(array(
'id_product_attribute' => $params['id_product_attribute'],
'meta_title_fr' => $combination->meta_title_fr,
'meta_title_en' => $combination->meta_title_en,
)
);
$combination->meta_title_fr = Tools::getValue('meta_title_fr');
$combination->meta_title_en = Tools::getValue('meta_title_en');
$combination->save();
return $this->display(__FILE__, 'views/templates/hook/combinationfields.tpl');
}
}
My HTML for the admin hook:
<div class="m-b-1 m-t-1">
<h2>{l s='Combination Custom Fields' mod='combinationcustomfields'}</h2>
<fieldset class="form-group">
<div class="col-lg-12 col-xl-4">
<label class="form-control-label" for="combination_{$id_product_attribute}_attribute_meta_title_fr">{l s='Meta title FR' mod='combinationcustomfields'}</label>
<input class="form-control" name="combination_{$id_product_attribute}[attribute_meta_title_fr]" id="combination_{$id_product_attribute}_attribute_meta_title_fr" type="text" value="{if $meta_title_fr != ''}{$meta_title_fr}{/if}">
<br />
</div>
<div class="col-lg-12 col-xl-4">
<label class="form-control-label" for="combination_{$id_product_attribute}_attribute_meta_title_en">{l s='Meta title EN' mod='cmp_combination_customfields'}</label>
<input class="form-control" name="combination_{$id_product_attribute}[attribute_meta_title_en]" id="combination_{$id_product_attribute}_attribute_meta_title_en" type="text" value="{if $meta_title_en != ''}{$meta_title_en}{/if}">
<br />
</div>
</fieldset>
<div class="clearfix"></div>
</div>
My override of the combination class:
class Combination extends CombinationCore
{
public $meta_title_fr;
public $meta_title_en;
/**
* #see ObjectModel::$definition
*/
public static $definition = [
'table' => 'product_attribute',
'primary' => 'id_product_attribute',
'fields' => [
'id_product' => ['type' => self::TYPE_INT, 'shop' => 'both', 'validate' => 'isUnsignedId', 'required' => true],
'location' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 64],
'ean13' => ['type' => self::TYPE_STRING, 'validate' => 'isEan13', 'size' => 13],
'isbn' => ['type' => self::TYPE_STRING, 'validate' => 'isIsbn', 'size' => 32],
'upc' => ['type' => self::TYPE_STRING, 'validate' => 'isUpc', 'size' => 12],
'mpn' => ['type' => self::TYPE_STRING, 'validate' => 'isMpn', 'size' => 40],
'quantity' => ['type' => self::TYPE_INT, 'validate' => 'isInt', 'size' => 10],
'reference' => ['type' => self::TYPE_STRING, 'size' => 64],
'supplier_reference' => ['type' => self::TYPE_STRING, 'size' => 64],
'meta_title_fr' => ['type' => self::TYPE_STRING, 'size' => 64],
'meta_title_en' => ['type' => self::TYPE_STRING, 'size' => 64],
/* Shop fields */
'wholesale_price' => ['type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice', 'size' => 27],
'price' => ['type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isNegativePrice', 'size' => 20],
'ecotax' => ['type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice', 'size' => 20],
'weight' => ['type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isFloat'],
'unit_price_impact' => ['type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isNegativePrice', 'size' => 20],
'minimal_quantity' => ['type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId', 'required' => true],
'low_stock_threshold' => ['type' => self::TYPE_INT, 'shop' => true, 'allow_null' => true, 'validate' => 'isInt'],
'low_stock_alert' => ['type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'],
'default_on' => ['type' => self::TYPE_BOOL, 'allow_null' => true, 'shop' => true, 'validate' => 'isBool'],
'available_date' => ['type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDateFormat'],
],
];
}
But when I save the product, the fields are in the request:
But I have a 400 Error:
Any idea of my mistake here ?
All the best and thanks in advance for you help :)
You can override the combination class using an override controler:
class Combination extends CombinationCore
{
public $newVariableName;
public function __construct($id = null, $id_lang = null, $id_shop = null)
{
Combination::$definition['fields']['newVariableName'] = array('type' => self::TYPE_STRING, 'validate' => 'isAnything', 'required' => false);
parent::__construct($id, $id_lang, $id_shop);
}
}
You will also need to override product.php
public function updateProductAttribute($id_product_attribute, ..., $newVariableName = null){
public function addCombinationEntity($wholesale_price, ..., $newVariableName = null){
and so on...
I would do so:
HTML:
Change all attributes combination_ to custom_
<div class="m-b-1 m-t-1">
<h2>{l s='Combination Custom Fields' mod='combinationcustomfields'}</h2>
<fieldset class="form-group">
<div class="col-lg-12 col-xl-4">
<label class="form-control-label" for="custom_{$id_product_attribute}_attribute_meta_title_fr">{l s='Meta title FR' mod='combinationcustomfields'}</label>
<input class="form-control" name="custom_{$id_product_attribute}[attribute_meta_title_fr]" id="custom_{$id_product_attribute}_attribute_meta_title_fr" type="text" value="{if $meta_title_fr != ''}{$meta_title_fr}{/if}">
<br />
</div>
<div class="col-lg-12 col-xl-4">
<label class="form-control-label" for="custom_{$id_product_attribute}_attribute_meta_title_en">{l s='Meta title EN' mod='cmp_combination_customfields'}</label>
<input class="form-control" name="custom_{$id_product_attribute}[attribute_meta_title_en]" id="custom_{$id_product_attribute}_attribute_meta_title_en" type="text" value="{if $meta_title_en != ''}{$meta_title_en}{/if}">
<br />
</div>
</fieldset>
<div class="clearfix"></div>
Next step:
public function hookActionAttributeCombinationSave($params)
{
$id_product_attribute = $params['id_product_attribute'];
$custom = $_POST['custom_' . $id_product_attribute];
....
}

Yii2 Pjax and GridView - refresh is not working properly

I am using the Pjax and GridView, and trying to make it work properly after the status of the item is changed. Currently, after the action is over, and server sends back the result, the whole GridView will be replaced with the text (response from the controller).
The Pjax code:
<?php
Pjax::begin(['id' => 'product-manage']);
echo GridView::widget([
'dataProvider' => $productsProvider,
'filterModel' => $filterModel,
'filterPosition' => 'header',
'columns' => [
['class' => 'yii\grid\SerialColumn'],
....
['class' => 'yii\grid\ActionColumn',
'header' => 'Actions',
'buttons' => [
....
'toggle-publish' => function ($url, $model) {
$html = $model->published ? '<span class="glyphicon glyphicon-remove"></span>' : '<span class="glyphicon glyphicon-ok"></span>';
return Html::a($html, $url, [
'title' => $model->published ? 'Unpublish' : 'Publish',
'data-pjax' => 'product-manage',
'data' => [
'confirm' => $model->published ? 'Are you sure you want to unpublish ' . $model->inci . ' ?' : 'Are you sure you want to publish ' . $model->inci . ' ?',
'method' => 'post',
],
]);
},
],
'template' => '<span class="block text-center">{view}</span>
<span class="block text-center">{update}</span>
<span class="block text-center">{toggle-default-product}</span>
<span class="block text-center">{toggle-publish}</span>'
],
],
]);
Pjax::end();
?>
Controller:
$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON;
$response->statusCode = 200;
$response->data = Yii::$app->controller->renderPartial('/partials/_alerts', [
'message' => $message,
'type' => 'success'
]);
return $response;
What am I doing wrong here?

yii2 :why $model->image is empty after upload image with FileUploadUI

this is my _form.php :
<?php
use dosamigos\fileupload\FileUploadUI;
// with UI
?>
<?=
FileUploadUI::widget([
'model' => $model,
'attribute' => 'image',
'url' => ['media/upload', 'id' => 'image'],
'gallery' => false,
'fieldOptions' => [
'accept' => 'image/*'
],
'clientOptions' => [
'maxFileSize' => 200000
],
// ...
'clientEvents' => [
'fileuploaddone' => 'function(e, data) {
console.log(e);
console.log(data);
}',
'fileuploadfail' => 'function(e, data) {
console.log(e);
console.log(data);
}',
],
]);
?>
my file uploaded in my host but i need that url
this is my product controller and image is empty :
public function actionCreate()
{
$request = Yii::$app->request;
$model = new Product();
$idCon = Yii::$app->user->id;
$model->user_id = $idCon;
if ($request->isAjax)
{
/*
* Process for ajax request
*/
Yii::$app->response->format = Response::FORMAT_JSON;
if ($request->isGet)
{
return [
'title' => "Create new Product",
'content' => $this->renderAjax('create', [
'model' => $model,
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])
];
}
else if ($model->load($request->post()) && $model->save())
{
return [
'forceReload' => '#crud-datatable-pjax',
'title' => "Create new Product",
'content' => '<span class="text-success">Create Product success</span>',
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::a('Create More', ['create'], ['class' => 'btn btn-primary', 'role' => 'modal-remote'])
];
}
else
{
return [
'title' => "Create new Product",
'content' => $this->renderAjax('create', [
'model' => $model,
]),
'footer' => Html::button('Close', ['class' => 'btn btn-default pull-left', 'data-dismiss' => "modal"]) .
Html::button('Save', ['class' => 'btn btn-primary', 'type' => "submit"])
];
}
}
else
{
/*
* Process for non-ajax request
*/
if ($model->load($request->post()) && $model->save())
{
return $this->redirect(['view', 'id' => $model->id]);
}
else
{
return $this->render('create', [
'model' => $model,
]);
}
}
}
and this is my model :
use Yii;
use yii\web\UploadedFile;
use yii\base\Model;
/**
* This is the model class for table "product".
*
* #property integer $id
* #property string $name
* #property string $price
* #property string $image
* #property string $url
* #property integer $user_id
*
* #property ConProduct[] $conProducts
* #property User $user
* #property Sales[] $sales
*/
class Product extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'product';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['price'], 'number'],
[['user_id'], 'integer'],
[['name', 'image'], 'string', 'max' => 300],
[['url'], 'string', 'max' => 255],
[['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
];
}
how can i get image url with $model->image in controller !?
Have you tried to use yii\web\UploadedFile::getInstance()?
$model->image = UploadedFile::getInstance($model, 'image');
if ($model->upload()) {
// do some stuff with file
}
http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html#wiring-up

Automatically refreshing yii2 grid after server database changes

I have a grid that involves truck verification. I would like the contents of the grid to change without page refresh.
Currently this works when the page is refreshed but i would like it to work even when a page is not refreshed that is when the content changes in the server database.
This is the grid
<?php
$gridColumns = [
['class' => 'kartik\grid\SerialColumn'],
'reg_no',
[
'attribute'=>'truck_category',
'value'=>'truckCategory.category'
],
[
'class' => 'kartik\grid\ActionColumn',
'vAlign'=>'middle',
'urlCreator' => function($action, $model, $key, $index) { return '#'; },
'viewOptions'=>['title'=>"vdgdv", 'data-toggle'=>'tooltip'],
'updateOptions'=>['title'=>"update", 'data-toggle'=>'tooltip'],
'deleteOptions'=>['title'=>"delete", 'data-toggle'=>'tooltip'],
]
];
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => $gridColumns,
'containerOptions' => ['style'=>'overflow: auto'], // only set when $responsive = false
'beforeHeader'=>[
[
'options'=>['class'=>'skip-export'] // remove this row from export
]
],
'toolbar' => [
[],
'{export}',
'{toggleData}'
],
'pjax' => true,
'bordered' => true,
'striped' => false,
'condensed' => false,
'responsive' => true,
'hover' => true,
'floatHeader' => true,
'showPageSummary' => true,
'panel' => [
'type' => GridView::TYPE_PRIMARY
],
]);
?>
This is the controller that renders the grid
public function actionTrackingcenter()
{
$query = Truck::find()->where(['truck_status'=>5]);
$searchModel = new TruckSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams,$query);
return $this->render('trackingcenter/index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Could someone give a direction on how i can achieve the automatic change
You can use below with set-time-interval with jQuery
<?php
$this->registerJs('
setInterval(function(){
$.pjax.reload({container:"YOUR_PJAX_CONTAINER_ID"});
}, 10000);', \yii\web\VIEW::POS_HEAD);
?>
This code will be place after your GridView code
This will be reload your Pjax grid every 10 second

click yii2 gridview linkpager's page no, jump error

the gridview if on right of the page,left is some menus,when click on page no 2,it dose not only refresh the gridview,but all page including left part are lost——a totally new page come out!help~
there is the debugging Screenshot:
my action is
public function actionList()
{
$model = new Loan();
$dataProvider = new ActiveDataProvider([
'query' => $model->find(),
'pagination' => [
'pagesize' => '1',
],
]);
return $this->renderPartial('list', ['model' => $model, 'dataProvider' => $dataProvider]);
}
my view is:
<?php
use yii\grid\GridView;
use yii\grid\SerialColumn;
use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\LinkPager;
?>
<?=GridView::widget([
'dataProvider' => $dataProvider,
'layout'=> '{items}{pager}',
'columns' => [
['attribute' =>'loan_type','label'=>'借款类型','options' => ['width' => '80']],
['attribute' =>'amount','label'=>'金额','options' => ['width' => '80']],
['attribute' =>'rate','label'=>'还款利率','options' => ['width' => '80']],
['attribute' =>'fee','label'=>'手续费','options' => ['width' => '80']],
['attribute' =>'status','label'=>'状态','options' => ['width' => '80'] ],
['attribute' =>'comment','label'=>'审核意见','options' => ['width' => '80']],
['attribute' => 'created_at','value' =>function($model){return date('Y-m-d',strtotime($model->created_at));},'label'=>'申请时间','options' => ['width' => '150']],
[
'class' => 'yii\grid\ActionColumn',
'header' => '操作',
'template' => '{audit}',
'buttons' => [
'audit' => function ($url,$model) {
return Html::a('<span id="xxxx" class="glyphicon glyphicon-user"></span>','#',['title'=>'审核',
'onclick'=>"
$.ajax({
type: 'GET',
dataType: 'text',
url: 'http://182.92.4.87:8000/index.php?r=loan/pj', //目标地址
error: function (XMLHttpRequest, textStatus, errorThrown) {alert(XMLHttpRequest.status + ':' + XMLHttpRequest.statusText); },
success: function (page)
{
$('.ucRight').html(page);
}
});
return false;",
]);},
],
'urlCreator' => function ($action, $model, $key, $index) {
return Yii::$app->getUrlManager()->createUrl(['loan/list','id' => $model->status]);
},
'headerOptions' => ['width' => '80'],
],
],
]);
?>
The reason for your problem is that you haven't prevented the html link from directing to a new page, so your user is clicking on the link, which then loads a new page with the contents returned by the server; in this case a page of information with no layout applied. You need to add event.preventDefault() before the ajax call to stop this behaviour.
However, as #arogachev said, if you simply want to use pagination without a page refresh, then just use pjax. That is what pjax is designed for,