this is my controller code for pdf view
define( 'DOMPDF_ENABLE_AUTOLOAD', FALSE );
require_once( Yii::app()->basePath . "/../vendor/dompdf/dompdf/dompdf_config.inc.php" );
$dompdf = new DOMPDF();
$dompdf->set_paper( "A2", 'landscape' );
$html = $this->render( 'register', [
'dataProvider' => $dataProvider,
'batch' => $batch,
'course' => $course,
'pdf' => $pdf
], TRUE );
// echo $html;die();
$dompdf->load_html( $html );
$dompdf->render();
$dompdf->stream( "{$course->course_name}-{$batch->batch_name}-admission_register.pdf",
[ 'Attachment' => 0 ] );
How can i set the no of rows shown in a page?
I tried something like in this view
$sl = 1;
foreach( $dataProvider->getData() as $students )
{
if($sl>10)
{
echo "<div style='page-break-before: always;'></div>";
}
echo "
<tbody>
<tr>
<td>{$sl}</td>
<td>{$students->admission_no}</td>
<td>{$students->Fullname}</td>
<td>";
....
}
Related
I want to upload an image via Kartik widget. After submitting the form, the $_FILE['Product'] has the data about the image but getInstance($model, 'images') returns null. Tried with images[], also null.
This is what I'm trying to var_dump in the controller:
public function actionCreate()
{
$model = new Product();
if ($model->load(Yii::$app->request->post())) {
var_dump(UploadedFile::getInstance($model, 'images[]'));die;
And this is my model Product:
<?php
namespace app\models;
use backend\models\CActiveRecord;
use Yii;
use omgdef\multilingual\MultilingualQuery;
use omgdef\multilingual\MultilingualBehavior;
use yii\web\UploadedFile;
/**
* This is the model class for table "product".
*
* #property int $id
* #property int $category_id
* #property int $quantity
* #property double $price
* #property int $sort
*
* #property Productlang[] $productlangs
*/
class Product extends CActiveRecord
{
public $images;
public static function find()
{
return new MultilingualQuery(get_called_class());
}
public function behaviors()
{
$allLanguages = [];
foreach (Yii::$app->params['languages'] as $title => $language) {
$allLanguages[$title] = $language;
}
return [
'ml' => [
'class' => MultilingualBehavior::className(),
'languages' => $allLanguages,
//'languageField' => 'language',
//'localizedPrefix' => '',
//'requireTranslations' => false',
//'dynamicLangClass' => true',
//'langClassName' => PostLang::className(), // or namespace/for/a/class/PostLang
'defaultLanguage' => Yii::$app->params['languageDefault'],
'langForeignKey' => 'product_id',
'tableName' => "{{%productLang}}",
'attributes' => [
'title',
'description',
'meta_title',
'meta_desc',
'url'
]
],
];
}
/**
* #inheritdoc
*/
public static function tableName()
{
return 'product';
}
/**
* #inheritdoc
*/
public function rules()
{
$string = $this->multilingualFields(['description', 'url']);
$string_59 = $this->multilingualFields(['meta_title']);
$string_255 = $this->multilingualFields(['meta_desc', 'title']);
$string[] = 'description';
$string[] = 'url';
$string_59[] = 'meta_title';
$string_255[] = 'meta_desc';
$string_255[] = 'title';
return [
[['quantity', 'price', 'title', 'meta_title', 'meta_desc'], 'required'],
[['category_id', 'quantity', 'sort'], 'integer'],
[$string, 'string'],
[$string_59, 'string', 'max' => 59],
[$string_255, 'string', 'max' => 255],
[['price'], 'number'],
['images', 'file']
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'category_id' => 'Category ID',
'quantity' => 'Quantity',
'price' => 'Price',
'sort' => 'Sort',
];
}
public function upload()
{
if ($this->validate()) {
foreach ($this->image as $file) {
$file->saveAs(\Yii::getAlias("#images") . "/products/" . $this->id . "_" . $this->image->baseName . '.' . $this->image->extension);
}
return true;
} else {
return false;
}
}
}
Tried with rules ['images', 'safe'] also ['images', 'file'] ( think the second one is not right because the attribute is an array, right ? ). The form is <?php $form = ActiveForm::begin(['options' => ['multipart/form-data']]); ?>.
Finally my input:
<?= $form->field($model, 'images[]')->widget(FileInput::class, [
'showMessage' => true,
]) ?>
Full controller action:
public function actionCreate()
{
$model = new Product();
if ($model->load(Yii::$app->request->post())) {
foreach (Yii::$app->params['languages'] as $language){
if(Yii::$app->params['languageDefault'] != $language){
$title_lang = "title_$language";
$model->$title_lang = Yii::$app->request->post('Product')["title_$language"];
$description_lang = "description_$language";
$model->$description_lang = Yii::$app->request->post('Product')["description_$language"];
$meta_title_lang = "meta_title_$language";
$model->$meta_title_lang = Yii::$app->request->post('Product')["meta_title_$language"];
$meta_desc_lang = "meta_desc_$language";
$model->$meta_desc_lang = Yii::$app->request->post('Product')["meta_desc_$language"];
}
}
if($model->save()){
$model = $this->findModel($model->id, true);
//Make urls
foreach (Yii::$app->params['languages'] as $language) {
if (Yii::$app->params['languageDefault'] != $language) {
$url_lang = "url_$language";
$title_lang = "title_$language";
$model->$url_lang = $model->constructURL(
$model->$title_lang,
$model->id
);
}else{
$model->url = $model->constructURL(
$model->title,
$model->id
);
}
}
//Upload Images
$model->images = UploadedFile::getInstance($model, 'images');
if (!($model->upload())) {
Yii::$app->session->setFlash('error', Yii::t('app', 'Some problem with the image uploading occure!'));
return $this->redirect(['create']);
}
if($model->update() !== false){
return $this->redirect(['view', 'id' => $model->id]);
}else{
Yii::$app->session->setFlash('error', Yii::t('app', 'Something went wrong. Please, try again later!'));
return $this->redirect(['create']);
}
}
}
return $this->render('create', [
'model' => $model,
]);
}
What looks like you are trying to upload a single image you should remove the [] from the input field name from the ActiveForm field declaration, and from models rules.
Single File
<?= $form->field($model, 'images')->widget(FileInput::class, [
'showMessage' => true,
'pluginOptions' => [
'showCaption' => false ,
'showRemove' => false ,
'showUpload' => false ,
'showPreview' => false ,
'browseClass' => 'btn btn-success btn-block' ,
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
'browseLabel' => 'Select Profile Image'
] ,
'options' => ['accept' => 'image/*' ] ,
]) ?>
and from the following line
UploadedFile::getInstance($model, 'images');
Multiple Files
For multiple files you need to add 'options' => ['multiple' => true] for the field and change the attribute name to images[]
<?= $form->field($model, 'images[]')->widget(FileInput::class, [
'showMessage' => true,
'pluginOptions' => [
'showCaption' => false ,
'showRemove' => false ,
'showUpload' => false ,
'showPreview' => false ,
'browseClass' => 'btn btn-success btn-block' ,
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
'browseLabel' => 'Select Profile Image'
] ,
'options' => ['accept' => 'image/*' ,'multiple'=>true] ,
]) ?>
and for receiving the uploaded files you should not specify the attribute as an array just change getInstance to getInstances and then try printing, it will show you all the images use foreach() to save all of them.
UploadedFile::getInstances($model, 'images');
I personally prefer to use a separate model for file uploading rather than using the ActiveRecord model.
Note: When using multiple files upload, you can also specify the 'maxFiles'=>1000 inside you model rules to limit the number of files to be uploaded
EDIT
For troubleshooting your code you should comment out the actionCreate from the controller and replace with the one i added below
public function actionCreate() {
$model = new Product();
if ( $model->load ( Yii::$app->request->post () ) ) {
foreach ( Yii::$app->params['languages'] as $language ) {
if ( Yii::$app->params['languageDefault'] != $language ) {
$title_lang = "title_$language";
$model->$title_lang = Yii::$app->request->post ( 'Product' )["title_$language"];
$description_lang = "description_$language";
$model->$description_lang = Yii::$app->request->post ( 'Product' )["description_$language"];
$meta_title_lang = "meta_title_$language";
$model->$meta_title_lang = Yii::$app->request->post ( 'Product' )["meta_title_$language"];
$meta_desc_lang = "meta_desc_$language";
$model->$meta_desc_lang = Yii::$app->request->post ( 'Product' )["meta_desc_$language"];
}
}
$transaction = Yii::$app->db->beginTransaction ();
try {
if ( !$model->save () ) {
throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
}
//Make urls
foreach ( Yii::$app->params['languages'] as $language ) {
if ( Yii::$app->params['languageDefault'] != $language ) {
$url_lang = "url_$language";
$title_lang = "title_$language";
$model->$url_lang = $model->constructURL (
$model->$title_lang , $model->id
);
} else {
$model->url = $model->constructURL (
$model->title , $model->id
);
}
}
//save the new urls
if ( !$model->save () ) {
throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
}
//Upload Images
$model->images = UploadedFile::getInstances ( $model , 'images' );
$model->upload ();
//commit the transatction to save the record in the table
$transaction->commit ();
Yii::$app->session->setFlash ( 'success' , 'The model saved successfully.' );
return $this->redirect ( [ 'view' , 'id' => $model->id ] );
} catch ( \Exception $ex ) {
$transaction->rollBack ();
Yii::$app->session->setFlash ( 'error' , Yii::t ( 'app' , $ex->getMessage () ) );
}
}
return $this->render ( 'create' , [
'model' => $model ,
] );
}
And comment out the upload() function of your model and add below function
public function upload() {
$skipped = [];
foreach ( $this->images as $file ) {
if ( !$file->saveAs ( \Yii::getAlias ( "#images" ) . "/products/" . $this->id . "_" . $this->image->baseName . '.' . $this->image->extension ) ) {
$skipped[] = "File " . $file->baseName . " was not saved.";
}
}
if ( !empty ( $skipped ) ) {
Yii::$app->session->setFlash ( 'error' , implode ( "<br>" , $skipped ) );
}
}
And for the ActiveForm make sure your input matches the following
$form->field($model, 'images[]')->widget(FileInput::class, [
'showMessage' => true,
'pluginOptions' => [
'showCaption' => false ,
'showRemove' => false ,
'showUpload' => false ,
'showPreview' => false ,
'browseClass' => 'btn btn-success btn-block' ,
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
'browseLabel' => 'Select Profile Image'
] ,
'options' => ['accept' => 'image/*','multiple'=>true ] ,
]) ;
Tell me where I was wrong, everything is tried
my view file:
echo FileInput::widget([
'model' => $model,
'attribute' => 'files[]',
'options' => ['multiple' => true]
]);
Also i added
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
enctype option to form element
Model:
i add two variables as property:
public $files; // files instance
public $serialize; // set string which store the files
in rules
serialize as string, and files:
[['files'], 'file', 'skipOnEmpty' => true, 'extensions' => 'gif, jpg, png, pdf, doc, docx', 'maxFiles' => 10],
and controller action:
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$oldFiles = $model->serialize;
$files = UploadedFile::getInstance($model, 'files');
if($files === false){
$model->serialize = $oldFiles;
} else {
$serialize = [];
if($model->validate()){
foreach($files as $file){
$ext = end((explode(".", $file)));
$filename = Yii::$app->security->generateRandomString().".{$ext}";
$serialize[] = $filename;
$file->saveAs(Yii::$app->basePath . '/web/image/' . $filename);
}
} else {
}
//print_r($model->getErrors()); die();
$model->serialize = serialize($serialize);
}
$model->save();
return $this->redirect(['view', 'id' => $model->news_id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
So, $files is empty, why?
also i get a "4" code error in $_FILES array
It should be getInstances for multiple files.
$files = UploadedFile::getInstances($model, 'files');
I have followed this solution in working with multiple models to upload using files using kartik fileinput during actionCreate.
My problem is achieving the same during actionUpdate, I keep on receiving the error below:
Either 'name', or 'model' and 'attribute' properties must be specified.
My form view is as follows:
echo $form->field($document,'document[]')->widget(FileInput::classname(), [
'options' => ['multiple' => true],
'pluginOptions' => [
// 'previewFileType' => 'any',
'showPreview' => false,
'showUpload' => false
], ]);
Whereas my controller actionUpdate is as follows
public function actionUpdate($id)
{
//$document = new EmployeeDocuments();
$model = $this->findModel($id);
$document = EmployeeDocuments::find()->indexBy('employee_id')->all();
$empavatar=$model->avatar;
$oldavatar=Yii::$app->session['oldavatar'] = $empavatar;
if ($model->load(Yii::$app->request->post()) ) {
// print_r($model); exit;
// $attachments = UploadedFile::getInstances($document, 'document');
// print_r($attachments); exit;
if($model->avatar==""){
$model->avatar=$oldavatar;
}
if ($model->save()){
if(!empty($attachments)){
foreach($attachments as $attachment):
$ext = end((explode(".", $attachment)));
$filename=end((explode(">", $attachment)));
$filename = ucwords(substr($filename, 0, strpos($filename, '.')));
// generate a unique file name
$file2save = Yii::$app->security->generateRandomString().".{$ext}";
$path=Yii::getAlias('#loc').'/uploads/employees/docs/'; //set directory path to save image
$attachment->saveAs($path.$model->id."_".$file2save); //saving img in folder
$attachment = $model->id."_".$file2save; //appending id to image name
\Yii::$app->db->createCommand()
->insert('lcm_hrm_employee_documents', ['document' => $attachment, 'name'=>$filename,'employee_id'=>$model->id])
->execute(); //manually update image name to db /* */
endforeach;
}
return $this->redirect(['view', 'id' => $model->id]);
}
else {
return $this->render('update', [
'model' => $model, 'document'=>$document
]);
}
} else {
return $this->render('update', [
'model' => $model, 'document'=>$document
]);
}
}
Change your form view to
echo $form->field($document,'document[]')->widget(FileInput::classname(), [
'options' => ['multiple' => true],
'attribute' =>'document[]',
'pluginOptions' => [
// 'previewFileType' => 'any',
'showPreview' => false,
'showUpload' => false
], ]);
If the response does not contain data about the city, I want to see the output message. Also i want to change css of text in textfield when I get an empty response.
I have:
View:
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'name'=>'city_id',
'value'=>'',
'source'=>CController::createUrl('/PromouterCity/autoComplete'),
'options'=>array(
'showAnim'=>'fold',
'minLength'=>'0',
'select'=>'js:function( event, ui ) {
$("#city_id").val( ui.item.name );
$("#selectedvalue").val( ui.item.id);
return false;
}',
),
'placeholder' => "Search...",
),
));
Controller:
public function actionAutoComplete(){
$match=$_GET['term'];
if(!empty($match)){
$match = addcslashes($match, '%_');
$q = new CDbCriteria( array(
'condition' => "name LIKE :match",
'params' => array(':match' => "$match%")
));
$query = City::model()->findAll($q);
}else{
$query=array(
'0'=>array(
'id'=>'1',
'name'=>'London',
)
);
}
$list = array();
foreach($query as $q){
$data['label']=$q['name'];
$data['id']= $q['id'];
$data['name']= $q['name'];
$list[]= $data;
unset($data);
}
echo CJSON::encode($list);
Yii::app()->end();
}
Decision:
'response'=> 'js:function( event, ui ) {
if (ui.content.length === 0) {
$("#empty-message").text("your message");
} else {
$("#empty-message").empty();
}
}',
I have created the following nested forms array;
return array(
'elements' => array(
'contact' => array(
'type' => 'form',
'elements' => array(
'first_name' => array(
'type' => 'text',
),
'last_name' => array(
'type' => 'text',
)
),
),
'lead' => array(
'type' => 'form',
'elements' => array(
'primary_skills' => array(
'type' => 'textarea',
),
),
),
),
'buttons' => array(
'save-lead' => array(
'type' => 'submit',
'label' => 'Create',
'class' => 'btn'
),
)
);
i have view page like this
echo $form->renderBegin();
echo $form['lead'];
echo $form['contact'];
echo $form->buttons['save-lead'];
echo $form->renderEnd();
my actionCreate is like this
$form = new CForm('application.views.leads.register');
$form['lead']->model = new Lead;
$form['contact']->model = new Contact;
// how can i perform ajax validation only for $form['contact']
$this->performAjaxValidation($model);
//if contact form save btn is clicked
if ($form->submitted('save-lead') && $form['contact']->validate() &&
$form['lead']->validate()
) {
$contact = $form['contact']->model;
$lead = $form['lead']->model;
if ($contact->save()) {
$lead->contact_id = $contact->id;
if ($lead->save()) {
$this->redirect(array('leads/view', 'id' => $lead->id));
}
}
}
ajax validation method is
protected function performAjaxValidation($model)
{
if (isset($_POST['ajax']) && $_POST['ajax'] === 'contact') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
so my question is how can i perform ajax validation on $form['contact'] and $form['lead'] elements individually?
You can have several forms in a page but they should not be nested.
Nested forms are invalid.
You should make your own validation
in actionCreate and actionUpdate of your controller you must add (i have main model "Invoice" and secondary "InvoiceDetails", and there could be more than 1 form for InvoiceDetails). But of course forms cannot be nested!
public function actionCreate()
{
...
$PostVar = 'Invoices';
if (Yii::app()->request->isAjaxRequest)
{ // if ajax
$this->performAjaxValidation($model, strtolower($PostVar) . '-form');
$PostVar = ucfirst($PostVar);
if (isset($_POST[$PostVar]))
{
$model->attributes = $_POST[$PostVar];
$dynamicModel = new InvoiceDetails(); //your model
$valid = self::validate($model, $dynamicModel);
if (!isset($_POST['ajax']))
{
if (isset($_POST['InvoiceDetails']))
{
$allDetails = array();
$allDynamicModels = $_POST['InvoiceDetails'];
//your own customization
foreach ($allDynamicModels as $key => $value)
{
$InvDet = InvoiceDetails::model()->findByPk($_POST['InvoiceDetails'][$key]['id']);
if (!isset($InvDet))
{
$InvDet = new InvoiceDetails();
}
$InvDet->attributes = $_POST['InvoiceDetails'][$key];
$InvDet->save();
$allDetails[] = $InvDet;
}
}
$model->invoicedetails = $allDetails;
if ($model->save())
{
echo CJSON::encode(array('status' => 'success'));
Yii::app()->end();
}
else
{
echo CJSON::encode(array('status' => 'error saving'));
Yii::app()->end();
}
}
// Here we say if valid
if (!isset($valid))
{
echo CJSON::encode(array('status' => 'success'));
}
else
{
echo $valid;
}
Yii::app()->end();
}
else
{
$this->renderPartial('_form', ...);
}
}
else
{
// not AJAX request
$this->render('_form', ...));
}
Nested Forms are invalid. You can use scenarios to validate the form at different instances.
Example:
`if ($form->submitted('save-lead'){
$form->scenario = 'save-lead';
if($form->validate()) {
$form->save();
}
} else {
$form->scenario = 'contact';
if($form->validate()){
$form->save();
}
}
$this->render('_form', array('form'=>$form);`