Error with ajax and zf2 controller action - ajax

I was trying to use ajax to redirect to a controller action in zend framework 2 but the ajax is not responding rightly as well as I am not receiving the data alert.
Here is the ajax code:
$(".save_btn").click(function (){ //the class of submit button is save_btn
$.ajax({
type : 'POST',
url : '/template/addtemplate',
data : {'id':'test'},
success : function(data,status)
{
alert(data.message);
}
});
});
this is my controller code:
public function addtemplateAction()
{
$result = array('status' => 'error',
'message' => 'There was some error. Try again.'
);
$request = $this->getRequest();
if($request->isXmlHttpRequest()){
$data = $request->getPost();
if(isset($data['id']) && !empty($data['id'])){
return new JsonModel($result);
$result['status'] = 'success';
$result['message'] = 'We got the posted data successfully.';
}
}
return new JsonModel($result);
}
I have also added these particular things in my module.config.php file :
'strategies' => array (
'ViewJsonStrategy'
),
I think the problem lies in $request->isXmlHttpRequest() which returns blank.
Any help will be accepted..

Use any kind of developer tools. Chrome => f12 => Network tab and check your response

Related

How to flash validation errors to session in Laravel

The built in behavior for flashing back validation errors in Laravel does not seem to be working for my use case.
I have a (React) form that posts it's data via fetch API using this method, which reloads or redirects the page with (hopefully) any session data after the response is returned:
fetch(props.register_route, {
method: 'POST',
headers: {
'X-CSRF-Token': props.csrf,
},
body: data,
})
.then((result) => {
return result.json();
})
.then((result) => {
console.log(result);
window.location.href = result.url;
},
(error) => {
console.log(error);
});
In my controller, I validate this data but if I structure it as follows, the errors are not available as $errors in the resulting page
if ($validator->fails()) {
return redirect()->back()->withErrors($validator);
}
However if I manually flash the errors to the session and return a url instead of a redirect, suddenly the behavior works.
if ($validator->fails()) {
Session::flash('errors', $validator->errors());
return response->json([
'url' => route('register'),
], Response::HTTP_NOT_ACCEPTABLE);
}
I feel as if I must be doing something incorrectly here to have to use this workaround. I could also manually send the errors back in the response, which may be the right way to structure things in the long run.
when you are calling api from javascript or front end applications like Reactjs,Angular,android etc.. .So it expect return result should be in json format so it should be like
if ($validator->fails()) {
return response()->json( $validator->errors(),422);
}
if you not calling Method from direct laravel blade then pass response in JOSN Format.
like
https://laravel.com/docs/8.x/responses#json-responses
Or
make one ResponseManager File
<?PHP
namespace App\Libraries\utils;
class ResponseManager {
public static $response = array('flag' => true, 'data' => '', 'message' => '', 'code' => 01,);
public static function getError($data = '', $code = 10, $message = '', $flag = false) {
self::$response['flag'] = $flag;
self::$response['code'] = $code;
self::$response['data'] = $data;
self::$response['message'] = $message;
return self::$response;
}
public static function getResult($data = '', $code = 10, $message = '', $flag = true) {
self::$response['flag'] = $flag;
self::$response['code'] = $code;
self::$response['data'] = $data;
self::$response['message'] = $message;
return self::$response;
}}
Define in config/app.php
//custom class
'ResponseManager' => App\Libraries\utils\ResponseManager::class,
and then use in whole project
Error Message Like
if ($validation->fails()) {
$message = $validation->messages()->first();
return Response()->json(ResponseManager::getError('', 1, $message));
}
Success Message Like
return Response()->json(ResponseManager::getResult(null, 10, "Success"));

ajax not getting any response from cakephp code

I am using CakePHP 2.9 to send data on the URL using ajax and get the related response.
I tried may method to get the response, I also want to know why this //URL:'/Pages/dropdownbox/'+id is not working.
bellow are ajax code which I wrote in the index.ctp.
$("#certificatedetail").on('change',function() {
var id = 'subcribe';
$("#usertype").find('option').remove();
$("#certificateclass").find('option').remove();
$("#certificatetyp").find('option').remove();
if (id) {
$.ajax({
type: 'POST',
url:'<?= Router::url(array('controller' => 'Pages', 'action' => 'dropdownbox','id')); ?>',
//url:'/Pages/dropdownbox/'+id,
dataType:'json',
cache: false,
async:true,
success: function(html)
{
$('<option>').val('').text('select').appendTo($("#usertype"));
$('<option>').val('').text('select').appendTo($("#certificateclass"));
$('<option>').val('').text('Select').appendTo($("#certificatetyp"));
$.each(html, function(key, value)
{
$('<option>').val(key).text(value).appendTo($("#usertype"));
});
}
});
}
});
I have written this controller code in PagesController,PHP and I declared the dropdownbox in AppController.php
public function dropdownbox($id = null)
{
Configure::write('debug', 0);
$this->layout = null;
$this->autoRender = false;
$category = array();
switch ($id)
{
case $id == "subcribe":
if ($id == 'subcribe') {
$category = array(
'individual' => 'Individual',
'organization'=>'Organization',
'organizationgovt' => 'Organization-Govt',
'organizationbank' => 'Organization-Bank'
);
break;
}
}
}
/ bellow is the code where I specify the dropdownbox function in AppController.php
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(
'login','add','index','contact','dropdownbox',
'cityres','stateres','sectorres','productres',
'project','service','about','apply','tender',
'decregistration','search','searchresult',
'tenderdetails'
);
}
You are generating the URL on your server, and using the string literal 'id' in it. The JavaScript id variable is never referenced. What you probably want is:
url:'<?= Router::url(array('controller' => 'Pages', 'action' => 'dropdownbox')); ?>' + id,
You are not returning any response from the controller. Do few things to debug it
Check in Browser's Network tab whether the called URL is correct or not.
Check the parameters are correct or not.
This is how it looks in Firefox Developer Edition
If URL is correct. Add below code in the dropdownbox() method. (Before the closing of the method)
echo json_encode($category);
Check Response Tab in the Network tab. (Example image above).
Also, console the response in the javascript code. Maybe you will be getting some other response which is not JSON.
success: function(html) {
console.log(html);
...
}
Hope it helps.

Drupal 8 Mailchimp Ajax Signup Block

I try to ajaxify the Drupal 8 Mailchimp SignUp Block but I stuck with the AjaxResponse.
This is my Form alter hook:
function mailchimp_ajax_form_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id) {
if ($form_id != 'mailchimp_signup_subscribe_block_form') {
return;
}
$form['submit']['#ajax'] = [
'callback' => 'mailchimp_ajax_form_callback',
'prevent' => 'click',
'progress' => array(
'type' => 'throbber',
'message' => t('Submitting data...')
)
];
}
This is my callback function:
function mailchimp_ajax_form_callback(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {
$response = new \Drupal\Core\Ajax\AjaxResponse();
$response->setContent('Response');
return $response;
}
But in Chrome console there is only an error:
Uncaught AjaxError:
An AJAX HTTP error occurred.
HTTP Result Code: 200
Debugging information follows.
Path: /node?ajax_form=1
StatusText: OK
ResponseText: Response
The Signup works, but my question is how can I get the mailchimp response and put it in a valid AjaxResponse?
First, the AjaxResponse object has a setData() method not setContent().
To actually subscribe someone to mailchimp through the Drupal module you can use the mailchimp_subscribe() function in the main mailchimp module.
My "working" solution now is:
alter the form block, add an ajax callback function, prevent click and adds some ajax progress visualization.
/**
* Implements hook_form_FORM_ID_alter()
*
* #param \Drupal\mailchimp_signup\Form\MailchimpSignupPageForm $form
* #param \Drupal\Core\Form\FormStateInterface $form_state
* #param $form_id
*/
function mailchimp_ajax_form_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id) {
if ($form_id != 'mailchimp_signup_subscribe_block_form') {
return;
}
$form['submit']['#ajax'] = [
'callback' => 'mailchimp_ajax_form_callback',
'prevent' => 'click',
'progress' => array(
'type' => 'throbber',
'message' => t('Submitting data...')
)
];
}
This is the Ajax Callback:
I create a new AjaxResponse Object and an array of the Drupal messages via drupal_get_messages(). Then some kind of hack to get the right message.
and add an ReplaceCommandObject which replaces the form with the Mailchimp message.
function mailchimp_ajax_form_callback(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {
$response = new \Drupal\Core\Ajax\AjaxResponse();
$messages = drupal_get_messages();
$message = $messages['status'][0];
if(!$message){
$message = $messages['warning'][0];
}
$response->addCommand(new \Drupal\Core\Ajax\ReplaceCommand('#mailchimp-signup-subscribe-block-form', $message));
return $response;
}
I think there are much more elegant ways to get this.
I still don't know why the submitForm Method of The Mailchimp Form is still invoked...
The AJAX option is committed to the module, you can find it here: https://www.drupal.org/project/mailchimp/issues/2721249
After applying the patch or using the version that includes it, you'll find a checkbox in the form configuration to enable the AJAX in it.

Yii2: ajax form validation on an ajax submitted form

I'm wondering if any Yii2 experts can help me understand how best to work with ajax forms combined with Yii ajax validation. I think I can explain the issue without taking you through all of my code.
I am working on a Promo Code entry form where the user enters their promo code into the form, the form is submit via ajax. We then perform a database lookup for the promo code details, validate the code and if the code validates, we want to display the registration form that is hidden on the page.
I have a custom validation function for the form field "code", which is the active field in a model scenario named "register".
class UserCode extends ActiveRecord
{
...
public function scenarios()
{
return [
'register' => ['code'],
];
}
public function rules()
{
return [
[['code'], 'required'],
[['code'], 'validateUserCode', 'on' => ['register']],
];
}
public function validateUserCode($attribute, $params)
{
// perform all my custom logic to determine if the code is valid
if ($code_invalid) {
$this->addError($attribute, 'Sorry, this code is invalid.');
}
}
...
}
Then in the controller, as the Yii2 Guide suggests, I trap this ajax validation with the following code:
public function actionValidate() {
$model = new UserCode(['scenario' => 'register']);
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
// no logic can be run after the above code b/c the form is submit with ajax
// and therefore always trapped in the Yii::$app->request->isAjax conditional
}
The above code all works fine and if I remove focus from the $form->field($model, 'code') field on my form, Yii's ajax validation kicks in and displays my custom error message based off of my custom validation logic.
My challenge arises when I go to submit the form. The form submission is also handled through ajax, and therefore the controller action always returns the result of the ActiveForm::validate($model); because if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) will get apply to both the ajax form validation AND on the form submit.
With the above approach, I am forced to return only the results of the ajax validation and not any json data that I may need for additional client side validation, such as displaying the registration form after a valid use code is submitted through the ajax form.
I realize that I can set 'enableAjaxValidation' => false on the ActiveForm and then return my own json data inside the if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) condition. If I do this, I am able to show the registration form because I have my own json data to work with.
Is there a way to have ajax validation on a form that is submitted with ajax? How could you trap the ajax validation separately from the ajax form submission to handle the two events in different manners?
Any suggestions or alternate approaches are GREATLY appreciated!
You should set up validationUrl with a different URL compared to the URL that you are submitting the form to. In this way you can have the validation function that would validate and return the return ActiveForm::validate($model); and the normal submit form that does something else.
You can read more about validationUrl here:
I have found solution :
Form :
<?php
$form = ActiveForm::begin(['id' => 'form-add-contact', 'enableAjaxValidation' => true, 'validationUrl' => Yii::$app->urlManager->createUrl('contacts/contacts/contact-validate')]);
?>
Submit Via Ajax :
<?php
$script = <<< JS
$(document).ready(function () {
$("#form-add-contact").on('beforeSubmit', function (event) {
event.preventDefault();
var form_data = new FormData($('#form-add-contact')[0]);
$.ajax({
url: $("#form-add-contact").attr('action'),
dataType: 'JSON',
cache: false,
contentType: false,
processData: false,
data: form_data, //$(this).serialize(),
type: 'post',
beforeSend: function() {
},
success: function(response){
toastr.success("",response.message);
},
complete: function() {
},
error: function (data) {
toastr.warning("","There may a error on uploading. Try again later");
}
});
return false;
});
});
JS;
$this->registerJs($script);
?>
Controller :
/*
* CREATE CONTACT FORM AJAX VALIDATION ACTION
*/
public function actionContactValidate() {
$model = new ContactsManagement();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
$model->company_id = Yii::$app->user->identity->company_id;
$model->created_at = time();
\Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
}
/**
* Quick Add Contact Action
* #param type $id
* #return type
*/
public function actionAddContact() {
$model = new ContactsManagement();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($model->validate()) {
$flag = $model->save(false);
if ($flag == true) {
$transaction->commit();
return Json::encode(array( 'status' => 'success', 'type' => 'success', 'message' => 'Contact created successfully.'));
} else {
$transaction->rollBack();
}
} else {
return Json::encode(array('status' => 'warning', 'type' => 'warning', 'message' => 'Contact can not created.'));
}
} catch (Exception $ex) {
$transaction->rollBack();
}
}
return $this->renderAjax('_add_form', [
'model' => $model,
]);
}

Unable to edit recode in cake php when I load the value in select box using j-query

I am unable to load select box value when I want to update the value. The same code perfectly working when I am going to save value.
My controller code is:
public function listwardByCircle($category = "") {
$this->layout = 'ajax';
$this->beforeRender();
$this->autoRender = false;
$ward=$this->Ward->find('list',array(
"fields" => 'id, wardname',
"conditions" => array('Ward.circle_id' => $category)
));
//$this->set('ward',$ward);
print_r($ward);
foreach($ward as $key => $val) {
echo "<option value=$key>$val</option>";
}
}
And this is my js code :
$("#AreaCircleId").change(function() {
alert("testing....");
$.post('../Admins/listwardByCircle/' + $(this).val(), function(data) {
alert( data);
$("#AreaWardId").empty().append(data);
}, 'html');
});
In js file
Url in Controller Like
`\../../Admins\/listwardByCircle`
You may need to update your URL post location in the ajax from:
$.post('../Admins/listwardByCircle/'
to
$.post('/admins/listwardByCircle/'
This is if the controller name is admins.

Resources