I have a problem with my form because it cant serialize the image file. So how can I submit a form that contains an image file input in Yii2 using ajax?
(Below you can see the active form and the js code.)
<div class="cars-form">
<?php $form = ActiveForm::begin(['options'=>['id'=>$model->formName(),'enableAjaxValidation'=>true,'enctype'=>'multipart/form-data']]); ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?=$form->field($model, 'colour')->widget(ColorInput::classname(), ['options' => ['placeholder' => 'Select Color...'],]); ?>
<?=$form->field($model, 'imageFile')->widget(FileInput::classname(), [
'options' => ['accept' => 'image/*'],'pluginOptions' => [
'previewFileType' => 'image',
'showUpload' => false],]);?>
<?= $form->field($model, 'price')->textInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$script = <<< JS
$('form#{$model->formName()}').on('beforeSubmit',function(e)
{var \$form =$(this);
$.post(
\$form.attr("action"),
\$form.serializefiles()
)
.done(function(result)
{
if (result == 1)
{
$(\$form).trigger("reset");
$.pjax.reload({container:'#cars'});
}
else
{
$("#message").html(result);
}
}).fail(function(data)
{console.log("server error: " + data);});
return false;
});
JS;
$this->registerJs($script);?>
(Controller)
public function actionCreate()
{
$model = new Cars();
if ($model->load(Yii::$app->request->post())) {
$imageName= $model->name;
$model->imageFile= UploadedFile::getInstance($model,'imageFile');
$model->imageFile->saveAs('carsimages/'.$imageName.'.'.$model->imageFile->extension);
$model->image='carsImages/'.$imageName.'.'.$model->imageFile->extension;
if($model->save())
//{
//return $this->redirect(['view', 'id' => $model->id]);
//}
{
echo 1;
}
else
{
echo 0;
}
}
else {
return $this->renderAjax('create', [
'model' => $model,
]);
}}
Related
I have a form where i am assigning some equipments to an user. I want to assign only one equipment to one user because i have a start date and end date. I want if i select some display from dropdown, the phone and laptop to freeze and to be selected default none. I also want if i select phone for ex, display and laptop to freeze.I found somewhere that it can be made with javascript, but i don't know how. If you can guide me or give me a proper example i would appreciate.I am new to js.
Here is my form :
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\User;
use kartik\date\DatePicker;
/* #var $this yii\web\View */
/* #var $model app\models\UserEquipmentMapping */
/* #var $form yii\widgets\ActiveForm */
#print_r($userquery);die;
?>
<div class="user-equipment-mapping-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'user_id')
->dropDownList(ArrayHelper::map($usermodel, 'id', 'username'))?>
<?= $form->field($model, 'laptop_id')
->dropDownList(ArrayHelper::map($laptopmodel, 'id', 'laptop_series'))?>
<?= $form->field($model, 'phone_id')
->dropDownList(ArrayHelper::map($phonemodel, 'id', 'phone_series'))?>
<?= $form->field($model, 'display_id')
->dropDownList(ArrayHelper::map($displaymodel, 'id', 'display_series'))?>
<?=$form->field($model, 'start_date')->widget(DatePicker::classname(), [
'language' => 'en',
'value' => date('yyyy/mm/dd', strtotime('+7 days')),
'readonly' => true,
#'disabled' => true,
#'size' => 'lg',
#'type' => DatePicker::TYPE_COMPONENT_APPEND,
'options' => ['placeholder' => 'Selectati data'],
'pluginOptions' => [
#'orientation' => 'top right',
'format' => 'yyyy/mm/dd',
'todayHighlight' => true,
'todayBtn' => true,
'autoclose'=>true,
]
]);?>
<?=$form->field($model, 'stop_date')->widget(DatePicker::classname(), [
'language' => 'en',
'value' => date('yyyy/mm/dd', strtotime('+7 days')),
'readonly' => true,
#'disabled' => true,
#'size' => 'lg',
#'type' => DatePicker::TYPE_COMPONENT_APPEND,
'options' => ['placeholder' => 'Selectati data'],
'pluginOptions' => [
#'orientation' => 'top right',
'format' => 'yyyy/mm/dd',
'todayHighlight' => true,
'todayBtn' => true,
'autoclose'=>true,
]
]);?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Thank you for any suggestions
UPDATE : But still not working, i have tried for the first 2 dropdowns at least to test.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\User;
use kartik\date\DatePicker;
/* #var $this yii\web\View */
/* #var $model app\models\UserEquipmentMapping */
/* #var $form yii\widgets\ActiveForm */
#print_r($userquery);die;
?>
<div class="user-equipment-mapping-form">
<script>
$(document).ready(function(){
if($("#dropDown1").val())
$("#dropDown2").attr("disabled", "disabled");
else
$("#dropDown2").removeAttr("disabled");
if($("#dropDown2").val())
$("#dropDown1").attr("disabled", "disabled");
else
$("#dropDown1").removeAttr("disabled");
$($("#dropDown1").on("change", function(){
if($(this).val())
$("#dropDown2").attr("disabled", "disabled");
else
$("#dropDown2").removeAttr("disabled");
});
$($("#dropDown2").on("change", function(){
if($(this).val())
$("#dropDown1").attr("disabled", "disabled");
else
$("#dropDown1").removeAttr("disabled");
});
});
</script>
<?php $form = ActiveForm::begin(); ?>
<?php
$userData=ArrayHelper::map($usermodel,'id','username');
echo $form->field($model, 'user_id')->dropDownList($userData, ['prompt'=>'Select...'], array("id" => 'dropDown1'));
?>
<?php
$laptopData=ArrayHelper::map($laptopmodel,'id','laptop_series');
echo $form->field($model, 'laptop_id')->dropDownList($laptopData, ['prompt'=>'Select...'], array("id" => 'dropDown2'));
?>
<?php
$phoneData=ArrayHelper::map($phonemodel,'id','phone_series');
echo $form->field($model, 'phone_id')->dropDownList(
$phoneData,
['prompt'=>'Select...']);
?>
<?php
$displayData=ArrayHelper::map($displaymodel,'id','display_series');
echo $form->field($model, 'display_id')->dropDownList(
$displayData,
['prompt'=>'Select...']);
?>
<?=$form->field($model, 'start_date')->widget(DatePicker::classname(), [
'language' => 'en',
'value' => date('yyyy/mm/dd', strtotime('+7 days')),
'readonly' => true,
#'disabled' => true,
#'size' => 'lg',
#'type' => DatePicker::TYPE_COMPONENT_APPEND,
'options' => ['placeholder' => 'Selectati data'],
'pluginOptions' => [
#'orientation' => 'top right',
'format' => 'yyyy/mm/dd',
'todayHighlight' => true,
'todayBtn' => true,
'autoclose'=>true,
]
]);?>
<?=$form->field($model, 'stop_date')->widget(DatePicker::classname(), [
'language' => 'en',
'value' => date('yyyy/mm/dd', strtotime('+7 days')),
'readonly' => true,
#'disabled' => true,
#'size' => 'lg',
#'type' => DatePicker::TYPE_COMPONENT_APPEND,
'options' => ['placeholder' => 'Selectati data'],
'pluginOptions' => [
#'orientation' => 'top right',
'format' => 'yyyy/mm/dd',
'todayHighlight' => true,
'todayBtn' => true,
'autoclose'=>true,
]
]);?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Your dropdowns - add onchange function and class equipment
<?= $form->field($model, 'laptop_id')->dropDownList(ArrayHelper::map($laptopmodel, 'id', 'laptop_series'), ['prompt'=>'Select...', 'onchange' => 'setEquipment(this)', 'class' => 'equipment'])?>
<?= $form->field($model, 'phone_id')->dropDownList(ArrayHelper::map($phonemodel, 'id', 'phone_series'), ['prompt'=>'Select...', 'onchange' => 'setEquipment(this)', 'class' => 'equipment'])?>
<?= $form->field($model, 'display_id')->dropDownList(ArrayHelper::map($displaymodel, 'id', 'display_series'), ['prompt'=>'Select...', 'onchange' => 'setEquipment(this)', 'class' => 'equipment'])?>
js
function setEquipment(el){
var equipment_elements = $('.equipment');
if($(el).val() != "") {
$.each(equipment_elements, function (key, value) { //disable all elements
$(this).attr('disabled', true);
});
$(el).attr('disabled', false); //enable current element
}else{
$.each(equipment_elements, function (key, value) { //enable all elements
$(this).attr('disabled', false);
});
}
}
I want to select courses from the course field, then let it show in my courses field and submit the courses to the database. or if someone can help me so my courses can appear has a checkbox and once i tick a checkbox, it appears in the courses field
<?php $form = ActiveForm::begin(); ?>
<?=$form->field($model, 'student_id') ?>
<?=
$form->field($model, 'faculty_id')->dropDownList(
ArrayHelper::map(Faculties::find()->asArray()->all(), 'faculty_id', 'faculty_name'), [
'prompt' => 'Select Faculty',
'onchange' => '$.post("' . Yii::$app->urlManager->createUrl('/departments/lists?id=') . '"+$(this).val(), function(data) {
$("select#registrations-department_id").html (data);
});'
]
);
?>
<?=
$form->field($model, 'department_id')->dropDownList(
ArrayHelper::map(Departments::find()->asArray()->all(), 'department_id', 'department_name'), [
'id' => 'registrations-department_id',
'prompt' => 'Select Department',
'onchange' => '$.post("' . Yii::$app->urlManager->createUrl('/courses/lists?id=') . '"+$(this).val(), function(data) {
$("select#registrations-course_id").html (data);
});'
]);
?>
<?=
$form->field($model, 'course_id')->dropDownList(
ArrayHelper::map(Courses::find()->asArray()->all(), 'course_id', 'course_name'), [
'id' => 'registrations-course_id',
'prompt' => 'Select Course',
'onchange' => '$.post("(selected:)."+$(this).val(), function(data){
$("#registrations-courses").append(data)
});'
]);
?>
<!-- <?//= $form->field($model, 'courses')->checkBoxList([]) ?> -->
<?=$form->field($model, 'courses') ?>
<?=$form->field($model, 'comment') ?>
<?=$form->field($model, 'status') ?>
<?=$form->field($model, 'created_at') ?>
<?=$form->field($model, 'updated_at') ?>
<div class="form-group">
<?=Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
EDIT
this is my controller how do I save the courses in the database in the same column?
public function actionCreate()
{
$model = new Registrations();
if ($model->load(Yii::$app->request->post())) {
if ($model->validate()) {
// form inputs are valid, do something here
$model->student_id = Yii::$app->user->identity->id;
$model->faculty_id = 1 ;
$model->department_id = null ;
$model->course_id = 1;
$model->save();
return $this->redirect('../site/profile');
}
}
return $this->render('create', [
'model' => $model,
]);
}
You can use the checkBoxList() to create the list of checkboxes based on the courses list.
Change your course_id field to the following
$form->field($model, 'course_id')->checkboxList(yii\helpers\ArrayHelper::map(Courses::find()->asArray()->all(), 'course_id', 'course_name'), [
'inline' => true,
'unselect'=>null,
'item' => function($index, $label, $name, $checked, $value){
$checked = $checked ? 'checked' : '';
return "<input type='checkbox' class='my-courses' name='{$name}' value='{$value}' {$checked} data-label='{$label}'> <label>{$label}</label>";
}]);
add an id attribute to your courses field like below
$form->field($model, 'courses', ['inputOptions' => ['id' => 'courses']]);
and then add this javascript code to the top of your page
$js = <<< JS
$(".my-courses").on('click',function(e){
let course_name=$(this).data('label');
let course_field=$("#courses");
if($(this).is(":checked")){
$("#courses").val()==''?course_field.val(course_name):course_field.val(course_field.val()+', '+ course_name);
}else{
let regex=new RegExp(',{0,1}\\\s{0,1}('+course_name+')','g');
course_field.val(course_field.val().replace(regex,''));
}
})
JS;
$this->registerJs($js, \yii\web\View::POS_READY);
Now if you select the checkbox the name of the course would be copied to the input field and when you submit your form you can get the fields in your $_POST array under your specific model index like below.
[course_id] => Array
(
[0] => 1
[1] => 2
)
[courses] => asdas, shugal, spoon
You can verify by adding a print_r(Yii::$app->request->post()) in your controller action inside the check
if($model->load(Yii::$app->request->post())){
print_r(Yii::$app->request->post());
You can iterate on the course_id to save all of the course_id that were selected as checkboxes.
i have some field that set to hidden and i want to unhidden the field based on the other field validation. how can i do this using jquery??
here is my code:
<?php $form = ActiveForm::begin([
'id' => 'assign-form',
'enableAjaxValidation' => true,
]); ?>
<?= $form->field($volunteeringin, 'acId', [
'template' => '{label} <div class="row"><div class="col-md-5">{input}{error}{hint}</div></div>',
])->dropDownList($model->getActivitySearch(),['prompt'=>'בחר פעילות לשיבוץ המתנדב'])->label('פעילויות לשיבוץ')?>
<?= $form->field($volunteeringin, 'passedTraining')->radioList([0=>'לא',1=>'כן'] ,['separator' => '</br>','class'=>'hidden','id'=>'demo'])->label('האם המתנדב עבר הכשרה?'); ?>
<div class="form-group">
<?= Html::submitButton( 'שבץ מתנדב' ,['class' => 'btn btn-success' ]) ?>
</div>
<?php ActiveForm::end(); ?>
i want to set the field "passedTraining" to unhidden base on the the above field validation.
i try to use this function:
$('#fieldID').on('afterValidateAttribute', function(event, attribute, messages) {
if(messages.length == 0){
$('#demo').removeClass('hidden');
}
});
thanks
eli
I tested your code, and you have just a small error:
<?php $form = ActiveForm::begin([
'id' => 'assign-form',
'enableAjaxValidation' => true,
'enableClientValidation' => true, // enable this!
]); ?>
Hope this helps!
Good afternoon i've been struggling with these for 2 days now and i'm running out of time...
I have this modal...
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<?php if ( $modalToOpen == "1") { ?>
<h4>Aplicar abono a la cuenta #<?php echo $cardInformation->CardNumber ?></h4>
<?php } ?>
<?php if ($modalToOpen == "2") { ?>
<h4>Aplicar cargo a la cuenta #<?php echo $cardInformation->CardNumber ?></h4>
<?php } ?>
</div>
<div class="modal-body">
<p>Saldo Actual: <?php echo $lastBalance ?></p>
<?php echo $modalToOpen ; if($modalToOpen == 1){ ?>
<?php $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array('id' => 'inlineForm', 'type' => 'inline', 'htmlOptions' => array('class' => 'well'))); ?>
<?php echo $form->TextField($auxModel, 'Payment', array('size' => 8, 'maxlength' => 8, 'placeholder' => "$. Abono", 'class' => 'span1')); ?>
<?php echo $form->TextField($auxModel, 'Coment', array('size' => 250, 'maxlength' => 250, 'placeholder' => "Comentario", 'class' => 'span3')); ?>
<?php
$this->widget(
'bootstrap.widgets.TbButton', array(
'buttonType' => 'ajaxButton',
'type' => 'primary',
'label' => 'Guardar',
'url' => Yii::app()->createUrl('BusinessTargetCollectionCard/ApplyPayment'),
'htmlOptions' => array('onclick' => 'showWait();','id' =>'payment-btn'. uniqid()),
'ajaxOptions' => array(
'type' => 'POST',
'dataType' => 'json',
'data' => array(
'cardNumber' => $cardInformation->CardNumber,
'lastBalance' => $lastBalance,
'coment' => 'js:$("#BusinessTargetCollectionCardMovement_Coment").val()',
'payment' => 'js:$("#BusinessTargetCollectionCardMovement_Payment").val()',
'businessTargetCollectionCardId' => $cardInformation->Id,
'collectorId' => $cardInformation->CollectorId),
'success' => 'js:function(data){
alert(data.message);
if(data.status == "OK"){
$("#PaymentModal").modal("hide");
hideWait();
}
}'
),
)
);
$this->endWidget(); ?>
<?php } ?>
<?php if($modalToOpen == 2){ ?>
<?php $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array('id' => 'inlineForm', 'type' => 'inline', 'htmlOptions' => array('class' => 'well'))); ?>
<?php echo $form->TextField($auxModel, 'BalanceAfter', array('size' => 8, 'maxlength' => 8, 'placeholder' => "Cantidad a aplicar", 'class' => 'span1')); ?>
<?php
$this->widget(
'bootstrap.widgets.TbButton', array(
'buttonType' => 'ajaxButton',
'type' => 'primary',
'label' => 'Guardar',
'url' => Yii::app()->createUrl('BusinessTargetCollectionCard/ApplyCharge'),
'htmlOptions' => array('onclick' => 'showWait();', 'id' => 'charge-btn' . uniqid()),
'ajaxOptions' => array(
'type' => 'POST',
'dataType' => 'json',
'data' => array(
'cardNumber' => $cardInformation->CardNumber,
'charge' => 'js:$("#BusinessTargetCollectionCardMovement_BalanceAfter").val()'),
'success' => 'js:function(data){
alert(data.message);
if(data.status == "OK"){
$("#myModal").modal("hide");
hideWait();
}
}'
),
)
);
$this->endWidget();
?>
<?php } ?>
</div>
and I have these buttons:
<td><?php
$this->widget(
'bootstrap.widgets.TbButton', array(
'label' => 'Aplicar cargo',
'type' => 'success',
'htmlOptions' => array(
'onclick' => I dont know what to do // 'js:$("#modalToOpen").val("1");',
'data-toggle' => 'modal',
'data-target' => '#myModal',
),
)
);
?></td>
<td></td>
<td><?php
$this->widget(
'bootstrap.widgets.TbButton', array(
'label' => 'Aplicar pago',
'type' => 'primary',
'htmlOptions' => array(
'onclick' => I dont know what to do //'js:$("#modalToOpen").val("2");',
'data-toggle' => 'modal',
'data-target' => '#myModal',
),
)
);
?></td>
what I want to do is change the value of $modalToOpen depending on which button was clicked... so the content of the modal will be different if button 1 is clicked or button 2...
please any help will be really appreacciated
You can pass it through data-id like this
<?php
$this->widget(
'bootstrap.widgets.TbButton', array(
'label' => 'Aplicar cargo',
'type' => 'success',
'htmlOptions' => array(
'onclick' =>'js:function(data){
var myvalue = $(this).data("id");
$(".modal-body #myvalue").val(myvalue);
}',
'data-toggle' => 'modal',
'data-target' => '#myModal',
'data-id'=>'1',
),
)
);
?>
take that value in one hidden or text in
<div class="modal-body">
<p>some content</p>
<input type="text" name="myvalue" id="myvalue" value=""/>
</div>
I hope this will help.
On main page I've got a button which call bootstrap modal with activeform. On submit this form adds new row in my db. But I dont look a success message neither in this modal nor on the main page. Instead I get to page mysite.ru/category/create with white screen and text of dialog message on it ("Dialog contents here..."). How not to redirect user on other page? Just close modal and/or redirect on main page and show here flashmessage about successful adding row.
my button in views/site/index.php:
<?= Html::button(
'create',
['value' => Url::to(['category/create']),
'id' => 'modalButton'
]) ?>
<?php
Modal::begin([
'id' => 'modal'
]);
echo "<div id='modalContent'></div>";
Modal::end();
?>
my controller SiteController has:
public function actionIndex()
{
return $this->render('index');
}
CategoryController has
public function actionCreate()
{
$model = new Category;
if ($model->load(Yii::$app->request->post()) && Yii::$app->request->isAjax) {
$model->refresh();
Yii::$app->response->format = 'json';
return ActiveForm::validate($model);
} elseif ($model->load(Yii::$app->request->post()) && $model->save()) {
Yii::$app->session->setFlash('contactFormSubmitted');
//$model->refresh();
$this->refresh();
Dialog::begin([
'clientOptions' => [
'modal' => true,
],
]);
echo 'Dialog contents here...';
Dialog::end();
//$this->redirect('category/create');
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
views/category/create.php:
<?php
use yii\helpers\Html;
/* #var $this yii\web\View */
/* #var $model app\models\Category */
$this->title = 'Create Category';
$this->params['breadcrumbs'][] = ['label' => 'Categories', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="category-create">
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_form', [
'model' => $model,
]) ?>
</div>
and views/category/_form.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\jui\Dialog;
/* #var $this yii\web\View */
/* #var $model app\models\Category */
/* #var $form yii\widgets\ActiveForm */
?>
<?php
$this->registerJsFile(Yii::getAlias('/scripts/main.js'));
?>
<?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
<div class="alert alert-success">
Thank you for contacting us. We will respond to you as soon as possible.
</div>
<?php endif; ?>
<div class="category-form">
<?php $form = ActiveForm::begin([
'id' => $model->formName(),
//'enableAjaxValidation'=>true,
'validateOnSubmit'=>true,
//'action' => '/site/index'
]); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'description')->textarea(['rows' => 6]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
scripts/main.js:
// listen click, open modal and .load content
$('#modalButton').click(function (){
$('#modal').modal('show')
.find('#modalContent')
.load($(this).attr('value'));
});
// serialize form, render response and close modal
function submitForm($form) {
$.post(
$form.attr("action"), // serialize Yii2 form
$form.serialize()
)
.done(function(result) {
form.parent().replaceWith(result);
//$form.parent().html(result.message);
//$('#modal').modal('hide');
})
.fail(function() {
console.log("server error");
$form.replaceWith('<button class="newType">Fail</button>').fadeOut()
});
return false;
}
You have to prevent your form from being submited and use ajax.
$(your_form)
.on('beforeSubmit', function(event){
event.preventDefault();
submitForm($(your_form));
return false;
})
.on('submit', function(event){
event.preventDefault();
});