yii2 ajax submit custom form do nothing - yii2

**hello
i want to submit my form value with ajax
i have a modal in my view file
in modal i built a custom form to submit my data to a action**
<?php
use yii\bootstrap\Modal;
use yii\helpers\Html;
use yii\helpers\Url;
Modal::begin([
'header' => 'روز تخمینی برای اتمام پروژه انتخاب کنید',
'id' => 'modal-accept',
'size' => 'modal-sm',
'clientOptions' => [
'backdrop' => 'static',
'keyboard' => false,
],
]);
?>
<div id="modal-content">
<form method="post" action="<?= Url::to(['admin/site-developer/accept-task'])?>" id="modal_form">
<?php
echo jDate\DatePicker::widget([
'name' => 'datepicker',
'id' => 'estimate',
]);
?>
<?= Html::submitButton('submit',['class' => 'btn btn-sm btn-success']) ?>
</form>
</div>
<?php
Modal::end();
?>
for submit my value and get the result i used this function ,,, but when i click submit no ajax call will perform nothing will happening why i cant see any network activity in my browser inspect ...
$('#modal_form').on('beforeSubmit', function(e) {
var form = $(this);
var formData = form.serialize();
$.ajax({
url: form.attr("action"),
type: form.attr("method"),
data: formData,
success: function (data) {
console.log("successfull");
},
error: function () {
alert("Something went wrong");
}
});
}).on('submit', function(e){
e.preventDefault();
});
any suggestion?

You don't need to use before submsision, this is the problem
$('#modal_form').on('submit', function(e){
e.preventDefault();
var form = $(this);
var formData = form.serialize();
$.ajax({
url: form.attr("action"),
type: form.attr("method"),
data: formData,
success: function (data) {
console.log("successfull");
},
error: function () {
alert("Something went wrong");
}
});
return false;
});

Related

yii2 boostrap 5 and modal

Edit:
I discovered that if i do a clean install, the modal works, and it's after adding hail812/yii2-adminlte3 that the modal system won't work anymore... but i don't find what create this,
original:
little question, does any of you use yii/boostrap5/modal and succeed to render ajax form in a modal ? Because my code used with the older bootstrap won't work.. and i don't find how the new yii/bootstrap5/modal works...
here is my code
<?php
yii\bootstrap5\Modal::begin([
'id' => 'modal',
'size' => 'modal-lg',
//keeps from closing modal with esc key or by clicking out of the modal.
// user must click cancel or X to close
'clientOptions' => ['backdrop' => 'static', 'keyboard' => TRUE]
]);
echo '<div id="modalContent"></div>';
yii\bootstrap5\Modal::end();
?>
<?php
$this->registerJs( <<< EOT_JS_CODE
$(function(){
// changed id to class
$('.modalButton').click(function (e){
e.preventDefault();
$.get($(this).attr('href'), function(data) {
$('#modal').modal('show').find('#modalContent').html(data)
});
document.getElementById('modalHeader').innerHTML = '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h4>' + $(this).attr('title') + '</h4>';
return false;
});
});
EOT_JS_CODE
);
?>
the link i use to open the modal:
<?= Html::a(Yii::t('app', 'Ajouter'), ['create-categorie'], ['class' => 'btn btn-success modalButton','title'=>'Nouvelle catégorie']) ?>
And my code in my controller
public function actionCreateCategorie()
{
$model = new Categorie();
if ($model->load(Yii::$app->request->post())) {
$model->created_at = strtotime('now');
$model->updated_at = strtotime('now');
if( $model->save()){
return 'success';
}else{
return 'error';
}
}
return $this->renderAjax('create-categorie', [
'model' => $model,
],false, true);
}
my console with a strange error i don't get

new FormData works on one site but not on other

In my previous project I have:
let send = (form) => {
form = $(form)
...........
$.ajax({
method: 'post',
url: form.attr('action'),
data: new FormData(form[0]),
contentType: false,
processData: false
})
..........
return false
}
And my form looks like:
<?php $form = \yii\widgets\ActiveForm::begin([
'id' => 'w0',
'action' => 'site/send-contact',
'fieldConfig' => [
'options' => [
'tags' => false
]
]
]) ?>
................ some fields ............
\yii\widgets\ActiveForm::end(); ?>
Here, using the new FormData(..) works totally fine. You can check it here in the console networks tab. I have added var_dump($_POST) in the action. Now on my new project, new FormData(..) doesn't work. Absolutely no idea why. The dumped array is empty.
$.ajax({
method: 'get',
url: 'site/index',
data: {
data: new FormData($("#w0")[0])
},
})
And the form:
$form = \yii\bootstrap\ActiveForm::begin();
........... some fields here ............
\yii\bootstrap\ActiveForm::end()
Tried with post,get,contentType,processData just for any case but still empty array. Any suggestions? Thank you!
You can use Form submit event to submit form using ajax:
jQuery(document).ready(function($) {
$(".formclass").submit(function(event) {
event.preventDefault(); // stopping submitting
var data = $(this).serializeArray();
var url = $(this).attr('action');
$.ajax({
url: url,
type: 'post',
dataType: 'json',
data: data
})
.done(function(response) {
if (response.data.success == true) {
alert("Wow you commented");
}
})
.fail(function() {
console.log("error");
});
});
});
For more info

How can I save data in the database with a form that is loaded via Ajax in Symfony 4?

homepage.html.twig
<a class="load-form" href="{{ path('article_load_form', {slug:page.slug}) }}">Load my beautiful form</a>
<div class="show-form">form will appear here</div>
<script>
$( ".load-form" ).on( "click", function(e) {
e.preventDefault();
var $link = $(e.currentTarget);
$.ajax({method:'POST', url: $link.attr('href')}).done(function(data){
$('.show-form').html(data.output);
});
});
</script>
myController.php
/**
* #Route("/pages/{slug}/heart", name="article_load_form", methods={"POST"})
*/
public function loadForm($slug, Request $request){
$id = 9;
$item = new User();
$item= $this->getDoctrine()->getRepository(User::class)->find($id);
$form = $this->createFormBuilder($item)
->add('username', TextType::class, array('attr' => array('class' => 'form-control')))
->add('email', EmailType::class, array('attr' => array('class' => 'form-control')))
->add('is_active', HiddenType::class)
->add('plainPassword', RepeatedType::class, array('type' => PasswordType::class,'invalid_message' => 'The password fields must match.','options' => array('attr' => array('class' => 'password-field')),'required' => false,'first_options' => array('label' => 'Passwort', 'attr' => array('class' => 'form-control')),'second_options' => array('label' => 'Passwort wiederholen', 'attr' => array('class' => 'form-control')),))
->add('cancel', ButtonType::class, array('label' => 'Abbrechen','attr' => array('class' => 'cancel form-btn btn btn-default pull-right close_sidebar close_h')))
->add('save', SubmitType::class, array('label' => 'Speichern','attr' => array('class' => 'form-btn btn btn-info pull-right','style' => 'margin-right:5px')))
->getForm();
$form->handleRequest($request);
$response = new JsonResponse(
array(
'message' => 'Success',
'output' => $this->renderView('form.html.twig',
array(
'entity' => $item,
'form' => $form->createView(),
))), 200);
return $response;
if($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->flush();
}
}
My form is loaded when I click on "Load my beautiful form" with all the data from the database for each field. So this is working fine. BUT when I then change the data inside the form (for example the username from "leo" to "alan") and click the save button, then no data is stored in the database (the username is still "leo").
In the profiler the POST parameters are correct. But no forms were submitted for this request.
The action will return a response before the following block will be reached
if($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->flush();
}
So nothing will be stored in the DB.
then let's see what you are trying to do,
you try to get your beautiful from with ajax and put it to your load-form, so you need at first to use a get method, method:'GET',
after that you need an other ajax method to load your data to the server with post
$('#submit-my-beautiful-form').click(function(e){
e.preventDefault();
var form = $(this).closest('form');
var formData = form.serialize();
alert(formData);
$.ajax({
method:'POST',
url: $link.attr('href'),
data: formData,
success: function(data){
alert(data);
}
});
})
ps: your form data will be serialized and affected to formData variable and then loaded to the server
ps: you need to add an id to your save button :
->add('save', SubmitType::class, array('label' => 'Speichern','attr' => array('id' => 'submit-my-beautiful-form', 'class' => 'form-btn btn btn-info pull-right','style' => 'margin-right:5px')))
ps: dont forget to persist your $item object
$entityManager->persist($item);

activeform client validation with pjax

When enableClientValidation is set to true, then yii2-pjax widget does not fire ajax. Only when enableClientValidation is set to false, pjax works here. Is there any way to have active form client side and ajax validations on each field ( by yii ) as well as pjax on submit button ( by pjax )
<?php Pjax::begin(['id'=> 'new-comment','enablePushState' => false]); ?>
<?php $form = ActiveForm::begin([
'id' => $model->formName(),
'options' => ['data-pjax' => "1"] ,
'action' => ['site/signup'],
'enableClientValidation' => true,
]);
?>
<?= Html::submitButton('REGISTER', ['class' => 'btn btn-primary', 'name' => 'signup-button', 'id'=>'register-btn']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php Pjax::end(); ?
I had to remove Pjax calls in PHP around Active form since clientValidation would fail otherwise.
<?php $form = ActiveForm::begin([
"id"=>"CreateForm",
'enableClientValidation' => true,
//'enableAjaxValidation' => true,
'validationUrl'=>['site/form-validate'],
"options" => ["enctype" =>"multipart/form-data"]
]
); ?>
enableAjaxValidation can be made true as well above
Currently I have clientValidation as true without Pjax which is validating based on validationUrl. Submit button of form is handled externally in javascript that will firstly call same validationUrl and update error fields using updateMessages method of yii activeform. If no errors, then business logic is done in different action than validationUrl action
$.ajax({
url : encodeURI(baseUri + "site/form-validate"),
data : $("#CreateForm").serialize(),
dataType : 'json',
type : 'POST',
beforeSend : function(xhr, settings) {
$this.attr("disabled","disabled");
Pace.stop();
Pace.bar.render();
},
success : function(data) {
$('#CreateForm').yiiActiveForm("updateMessages", data);
if($("form#CreateForm").find('.has-error').length == 0) {
$.ajax({
url : encodeURI(baseUri + "site/form"),
data : $("#CreateForm").serialize(),
dataType : 'json',
type : 'POST',
beforeSend : function(xhr, settings) {
},
success : function(data) {
console.log(data);
},
error : function(data) {
},
complete : function() {
$this.removeAttr("disabled");
Pace.stop();
},
});
} else {
$this.removeAttr("disabled");
Pace.stop();
}
},
error : function(data) {
},
complete : function() {
},
});
Controller -
public function actionFormValidate() {
$model = new CreateForm();
if(Yii::$app->request->isAjax && $model->load($_POST))
{
Yii::$app->response->format = 'json';
return \yii\widgets\ActiveForm::validate($model);
}
}

yii2 autofill related field based on another field

I've a field called employee_name and depending on this field value I want to autofill another field employee_id. I've searched and I found this answer and tried implementing this on my form but I'm getting Error in ajax request. The jquery code in my form is
$('#emp').focusout(function() {
empName = this.value;
if ( empName != '' || empName != null ) {
$('#depcustomer-employee_name').val(empName);
}
$.ajax({
url: '".yii\helpers\Url::toRoute("deposit/employeeid")."',
dataType: 'json',
method: 'GET',
data: {name: $(this).val()},
success: function (data, textStatus, jqXHR) {
$('#depcustomer-employee_id').val(data.id);
},
beforeSend: function (xhr) {
alert('loading!');
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('An error occured!');
alert('Error in ajax request');
}
});
});
My Controller name is Deposit and my controller code is
public function actionEmployeeid($name){
$model= app\modules\settings\models\DepEmployee::findOne(['employee_name'=>$name]);
return \yii\helpers\Json::encode([
'id'=>$model->employee_id
]);
What could be the possible reason that my ajax code is not working?
My form is quite big. Here's the part of the employee field entry
<div class="row">
<div class="col-md-6">
<?= $form->field($model, 'employee_id')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-md-6">
<label for='emp'>Employee Name</label>
<?= Html::activeHiddenInput($model, 'employee_name')?>
<?php
echo AutoComplete::widget([
'name' => 'employee_name',
'id' => 'emp',
'clientOptions' => [
'source' => $dataEmp,
'autoFill'=>true,
'minLength'=>'2',
'select' => new JsExpression("function( event, ui ) {
$('#depcustomer-name').val(ui.item.id);
}")
],
]);
?>
</div>
</div>
According to your autocomplete data you already have employee_id. So no need to make ajax request to get employee id.
DepEmployee Model
public static function getEmpData()
{
$dataEmp = DepEmployee::find()
->select(['employee_name as value', 'employee_name as label','employee_id as id'])
->asArray()
->all();
return $dataEmp;
}
_form
<?= AutoComplete::widget([
'name' => 'employee_name',
'id' => 'emp',
'clientOptions' => [
'source' => DepEmployee::getEmpData(),
'autoFill'=>true,
'minLength'=>'2',
'select' => new JsExpression("function( event, ui ) {
$('#depcustomer-name').val(ui.item.id);
$('#depcustomer-employee_id').val(ui.item.id);
}")
],
]);?>
What i should do if i was at your place:
Here the view:
<?= $form->field($model, 'employeeName')->textInput([
// I use onfocusout instead of focusout
'onfocusout' => '
$.post("generateemployeeid?name="+$(this).val(), function(data) {
$("#employee_id_container").html(data);
});
',
]) ?>
<div id="employee_id_container"></div> // <- I will autofill here
Now here is the function who will fill the ID input: (should be in your controller)
public function actionGenerateemployeeid($name) {
$employeeModel = DepEmployee::find()
->where(['employee_name' => $name])
->one();
if($employeeModel !== NULL) {
echo 'Employee ID: <input type="text" name="EmployeeID" value="'.$employeeModel->employee_id.'" readonly><br>';
}
else {
// error 404
}
}
Resume: the jquery function take the employee name and send to the controller who will look for the employee ID in the database. Then send an input text with default value (employee ID) as response and load this input in the form.