1

I created a form with ActiveForm which include one multiple file input. I enabled AJAX validation on submit but when I select "n" items and click the submit button, yii send data in background but the file validator return the next error message: "Please upload a files". Ok I understand that why do it but I don't know that what the best practise if I want to check max file numbers and sizes and required at least one file and I want to use ajax validation too. Perhaps the best practise if I don't use ajax validation and I change the skipOnEmpty from false to true...?

Example (not the real full code):

Model:

class Document extends Model {
    public $name;
    public $files;

    public function rules()
    {
        return [
            ['name', 'required'],
            ['files', 'file',
                'maxSize'     => 1024 * 1024,
                'maxFiles'    => 5,
                'skipOnEmpty' => false
            ]
        ];
    }

    public function create() { // other code }
}

Controller:

class DocumentController extends Model
{
    public function create()
    {
        $model = new Document();

        $model->load(Yii::$app->request->post());
        $model->files = UploadedFile::getInstances($model, 'files');

        if (Yii::$app->request->isAjax) {
            Yii::$app->response->format = Response::FORMAT_JSON;

            return ActiveForm::validate($model);
        }

        if ($model->validate() && $model->create()) {
           // other code...
        }
    }
}

Thx guys!

5
  • Why does you Controller extends Model? Commented Aug 15, 2018 at 9:08
  • it was just an erratum in the example. Commented Aug 27, 2018 at 7:34
  • It's confusing, you should make valid examples so that people can help you better :) Commented Aug 27, 2018 at 8:54
  • Have you never maked a mistake? I think you should write a helpful answer :) Commented Aug 27, 2018 at 12:49
  • Haha, if I could, I would.. :D Commented Aug 29, 2018 at 6:06

3 Answers 3

1

That's known issue: https://github.com/yiisoft/yii2/issues/6873

You can make widget which validate your upload on client side and if all right send files to server where they will be validated again with your model and return error if something wrong.

Widget example https://github.com/2amigos/yii2-file-upload-widget

Sign up to request clarification or add additional context in comments.

1 Comment

Thx the links, I maked a widget what validating the file input with JavaScript too and worked perfectly.
0

#controller ajax validation same as expect

if ($model->load(Yii::$app->request->post())) {
    if (Yii::$app->request->isAjax) {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        return ActiveForm::validate($model);
    }
}

#model validation with fileRequired scenario

['filePath', 'required', 'on' => ['fileRequired']],

$tempScenario = $documentModel->scenario;

$documentModel->scenario = 'fileRequired';

echo $form->field($documentModel, "filePath", [
    'enableClientValidation' => true,
    'enableAjaxValidation' => false,
])->fileInput();
$documentModel->scenario = $tempScenario;

A enableAjaxValidation remove for ajax validation and enableClientValidation is for client validation which work perfectly for file validation

Comments

-1

//model

public function rules()
{
    return [

        [['identity_copy','home_copy', 'certificate_copy'], 'file', 
            'skipOnEmpty' => false,'on' => 'imageFalse',
            'extensions' => 'jpg, png, gif',
            'wrongExtension' => '{attribute} ควรเป็น {extensions} เท่านั้น.',
            'maxSize' => 512000,
        ],
        [['identity_copy','home_copy', 'certificate_copy'], 'file', 
            'skipOnEmpty' => TRUE,'on' => 'imageTrue',
            'extensions' => 'jpg, png, gif',
        ],
    ];
}

//controller

public function actionCreate() {

    $model = new StdRecord();

    $model->scenario = 'imageFalse';

   if ($model->load(Yii::$app->request->post())) {

        $model->scenario = 'imageTrue';


        $model->save();
        Yii::$app->session->setFlash('success', 'บันทึกข้อมูลเรียบร้อย');
        return $this->redirect(['view', 'id' => $model->std_id]);
    } else {
        if(Yii::$app->request->isAjax){
           return $this->renderAjax('create', [
               'model' => $model,
        ]);  
        } else {
            return $this->render('create', [
              'model' => $model,
        ]);  
        }
    }
}

1 Comment

You should add some comments around your code like suggested when you submitted your answer. This way people can make more sence of your code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.