Laravel 5.4 - forgot password ajax validation - laravel

I have a generic AJAX form submit JS class:
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('.ajax-form').submit(function() {
var form = $(this);
var url = form.attr('action');
var data = form.serialize();
if (!form.hasClass('valid')) {
$.ajax({
url: url,
type: 'post',
data: data,
dataType: 'json',
success: function(result) {
$('.field').removeClass('has-error');
form.addClass('valid');
form.submit();
},
error: function(result) {
var errors = result.responseJSON;
$('.field').removeClass('has-error');
$.each(errors, function(key, value) {
var field = $('.field.' + key);
field.addClass('has-error').children('.error-message').text(value[0]);
});
}
});
return false;
}
});
});
This works great for AJAX validation on all my forms. I am now trying to implement this on the default "forgot password" form that is generated with the auth scaffold (resources/views/auth/passwords/email.blade.php).
<form class="ajax-form" method="POST" action="{{ route('password.email') }}">
...
</form>
Although the AJAX validation is working here, the problem I am having is that when the validation passes, it is also performing the "forgot password" functionality. So basically it sends the reset password email twice (once during the AJAX submit and once during normal form submit).
I only want the AJAX submit to perform validation. If validation is successful it should (as it currently does) perform a normal form submit which will send the email.

Did you want to keep the Ajax submit but remove the normal form submit? If so then assuming you have a button to submit the form, you can keep the form from submitting in this answer:
Want html form submit to do nothing

If I understand the issue correctly you need to prevent Form Default behavior and validate and if everything is validated, resume the default form behavior to submit the data.
$('.ajax-form').submit(function(evt) {
evt.preventDefault(); // This would prevent default form submission functionality
var form = $(this);
var url = form.attr('action');
var data = form.serialize();
if (!form.hasClass('valid')) {
$.ajax({
url: url,
type: 'post',
data: data,
dataType: 'json',
success: function(result) {
$('.field').removeClass('has-error');
form.addClass('valid');
form.unbind('submit').submit(); // Submit the Form If everything is validated
},
error: function(result) {
var errors = result.responseJSON;
$('.field').removeClass('has-error');
$.each(errors, function(key, value) {
var field = $('.field.' + key);
field.addClass('has-error').children('.error-message').text(value[0]);
});
}
});
return false;
}
});

Here is the correct way to resolve this. In Auth\ForgotPasswordController override the sendResetLinkEmail function as follows:
/**
* Send a reset link to the given user.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function sendResetLinkEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
// Inserted this piece of code which checks for AJAX request
if ($request->ajax()) {
return response()->json();
}
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$response = $this->broker()->sendResetLink(
$request->only('email')
);
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($response)
: $this->sendResetLinkFailedResponse($request, $response);
}
By doing if ($request->ajax()) we allow it to check for ajax request and only return a json response. Then in the subsequent request when it does a regular form post it will perform the forgot password functionality.

Related

submitting form data on a specific bootstrap wizard step

Ive created a bootstrap wizard with several steps. When a user clicks the 'save & continue' button on the second wizard step, I want to commit the form data entered to the underlying data store before moving to the third step. I cant seem to get the form submission to work, the actionmethod on the controller isnt being called. This is the javascript on the page, it is being hit, but the controller action isnt
$("#scheduleReport").on("click", function () {
// Get the record's ID via attribute
//var id = $(this).attr('data-id');
$('#frmAddSchedule').validate();
$('#frmAddSchedule').submit();
});
$('#frmAddSchedule').on('submit', function (e) {
var $form = $(e.target);
if ($form.valid()) {
e.preventDefault();
$.ajax({
url: '#Url.Action("Create", "ReportScheduler")',
data: $form.serialize(),
async: true,
type: 'POST',
success: function (returnval) {
if (returnval.success == true) {
$("#schedulerGrid").igGrid("dataBind");
}
if (returnval.success == false) {
//$form.parents('.bootbox').modal('hide');
bootbox.alert({ title: '<div class="text-center text-danger"><i class="fa fa-exclamation-triangle"></i> ERROR</div>', message: returnval['responseText'] });
}
},
error: function (returnval) {
//$form.parents('.bootbox').modal('hide');
bootbox.alert(returnval['responseText']);
}
});
}
});
and the controller action method
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Prefix = "Schedule")]ReportScheduleViewModel item)
{
are there any 'best practices' for doing this ? what am I doing wrong ?
I found out the isue in the end, the wizard example I used already had a form element inside it (hadnt noticed it) which I had wrapped in my own form which was stopping the form submiting. It works fine now
Well, as a start I can maybe help you with the part of beeing able to call the controller action. As for the question "best practices", you gave to little details.
So:
/**
* On document ready.
*
* #return void
*/
$(document).ready(function () {
activateScheduleReport();
activateAddScheduleFormSubmit();
});
/**
* Activate schedule report click event.
*
* #return void
*/
function activateScheduleReport() {
$("#scheduleReport").on("click", function () {
// Get the record's ID via attribute
//var id = $(this).attr('data-id');
validateAddScheduleForm();
submitAddScheduleForm();
});
}
/**
* Activate add schedule form submit.
*
* #return void
*/
function activateAddScheduleFormSubmit() {
$('#frmAddSchedule').submit(function (e) {
var $form = $(this);
var ajax = $.ajax({
async: true, // Please don't use this! :-)
method: 'post',
dataType: 'json',
url: '#Url.Action("Create", "ReportScheduler")',
data: $form.serialize()
});
ajax.done(function (response, textStatus, jqXHR) {
if (response.success) {
$("#schedulerGrid").igGrid("dataBind");
} else {
//$form.parents('.bootbox').modal('hide');
bootbox.alert({
title: '<div class="text-center text-danger"><i class="fa fa-exclamation-triangle"></i> ERROR</div>',
message: response.responseText
});
}
});
ajax.fail(function (jqXHR, textStatus, errorThrown) {
//$form.parents('.bootbox').modal('hide');
bootbox.alert(textStatus + ' ' + errorThrown);
});
ajax.always(function (response, textStatus, jqXHR) {
// Do whatever you want here...
});
// Use this to prevent page refreshing. No need for preventDefault().
return false;
});
}
/**
* Validate add schedule form.
*
* #return void
*/
function validateAddScheduleForm() {
$('#frmAddSchedule').validate();
}
/**
* Submit add schedule form.
*
* #return void
*/
function submitAddScheduleForm() {
$('#frmAddSchedule').submit();
}
In the action you should use:
echo json_encode('whatever response string');
or
echo json_encode(array(responseText: 'whatever response string'));
Nota bene:
I used dataType: json. You can also use dataType: html. If, then
echo the string or the array without the json_encode.
I renamed your returnval to response.
Watch the parameters of ajax fail(), e.g of the old error().
I structured the js code in functions.
As I come from the PHP world I used echo to print and json_encode to encode in the JSON format.
Good luck!

how to fill field values using ajax in yii2?

I am using ajax in yii2.
How to fill fields without submit form. Without submitting the validation is working, but how to add field value.
In below code $this->name is my field name.
if($this->statusOk){
$this->name = "gana";
}else{
return $this->addError('branch_code', ' code can’t be found');
}
you can set your value in save function(in model) or before saving your model(in controller) ,and use custom validation just for validation.
Try this,custom ajax
$(document).ready(function () {
$("body").on("blur", "#id", function () {
var data = $("#nameField").val();
$.ajax({
url : "validURL",
type : "post",
data : {"sortcode":data},
success: function (response)
{
var json_obj = $.parseJSON(response);
if(json_obj.errorMessage) {
// do something
}else {
// do something
}

updation issue during with ajax method

i am trying to update my record with ajax and i don't know here i am doing wrong the code with my ajax:
$(document).ready(function(){
$('.edit_tag_button').click(function(){
var id = $(this).parent().find('.tag_id').val();
var formData = {
'tag_type' : $('#tag_type').val(),
'quantity' : $('#quantity').val(),
'number' : $('#number').val(),
'active' : $('#active').val(),
'issued' : $('#issued').val(),
};
$.ajax({
url: "{{url('')}}/update/tagslist/"+id,// Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: formData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
success: function(data) {
swal("Success!", "Great Job!! Your data has been updated","success");
location.reload();
},
error: function () {
swal("Error", "Look like We got some problem. Can you please refresh the page and try again" , "error");
}
});
});
});
and my controller code is:
public function updateTags(Request $request,$id)
{
$plan = Tags::where('id',$id);
$plan->update($request->all());
}
it says your values updated successfully but it does update my values any help plz
In Laravel POST method required CSRF protection.
Make sure to add meta with csrf token content
<meta name="_token" content="{{ csrf_token() }}">
And share it to ajax setup.
$.ajaxSetup({headers: {'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')}});

Laravel 5.2 post route returns plain html text

whenever I send a post request to 'tasks/add' i want the user to return to a new page, but all I get is plain html text in a popup.
Route.php code
Route::post('tasks/add', function() {
return view('secrets');
});
this is my ajax request :
$("#frm").submit(function(e){
e.preventDefault();
var customer = $("input[name=customer]").val();
var details = $("input[name=details]").val();
var dataString = 'customer='+customer+'&details='+details;
$.ajax({
url: "tasks/add",
type:"POST",
beforeSend: function (xhr) {
var token = $('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data : dataString,
success:function(data){
console.log(dataString);
alert(data);
},error:function(){
alert("error!!!!");
}
}); //end of ajax
});
});
Anybody has had this issue before?
You are using Ajax to call your Route method. So when Route::post(...) returns the view 'secrets', it returns it to the Ajax method and becomes held by the data variable. Saying return in your Routes file doesn't magically mean redirect to a certain view, it is just like any other function that returns a value.
You currently have alert(data) which just says make an alert with whatever is held by data which in this case is the html text of your view.
Instead, take out the alert() and put
window.location.replace('<path/to/secrets>')
to redirect to the page you want upon success.
Assuming your Routes file has something like :
Route::get('/secrets', function() {
return view('secrets');
});
You could say
window.location.replace('/secrets')

joomla token is not getting recognized by controllers method

I'm trying to set up a token on ajax post but is not getting recognized by the controllers method. The javascrip looks as it follows
jQuery(document).ready(function() {
jQuery('#source').change(function() {
jQuery('#fileupload').addClass('fileupload-processing');
var data = jQuery('#source option:selected').val();
jQuery.post('index.php', {
'option': 'com_tieraerzte',
'task': 'parser.importColumns',
'tmpl': 'component',
'token':'<?php echo JUtility::getToken()?>',
'app': data,
'dataType': 'html',
}, function(result) {
jQuery('td.add_column').html(result);
jQuery('button#parse.btn').show();
//edit the result here
return;
});
});
the token is getting generated and posted
in the controller I check the existance of toke but throws me Invalid Token
controller check toke
JRequest::checkToken('request') or jexit( 'Invalid Token' );
You're almost there, it's just a little mixed up. The Joomla! Form Token is generated and submitted as a input name with a value of 1. So, the token looks like this in your form:
<input type="hidden" name="1LKJFO39UKSDJF1LO8UFANL34R" value="1" />
With that in mind, when submitting via AJAX, you need to set the parameter name to your token name, with a value of 1. I accomplish something similar by just using the jQuery('selector').serialize() method:
Joomla.autoSave = function () {
jQuery.ajax({
url: "index.php?option=com_gazebos&task=product.apply&tmpl=component",
type: "POST",
data: jQuery("#product-form").serialize(),
success: function (data) {
console.log("autosaved");
}
});
};
Doing this pulls in all the form data (including the form token from the hidden input) and formats it as a query string, then sends it with the request. However, it seems to me that you might not want to do that and you are really only wanting to submit a single bit of data, not the whole form. So, let's rework your code a little bit to get the desired effect:
/**
* First, let's alias $ to jQuery inside this block,
* then setup a var to hold our select list dom object.
*/
jQuery(document).ready(function ($) {
var sourceSelect = $('#source');
sourceSelect.change(function () {
$('#fileupload').addClass('fileupload-processing');
/**
* Use the token as a parameter name and 1 as the value,
* and move the dataType param to after the success method.
*/
$.post('index.php',
{
'option': 'com_tieraerzte',
'task': 'parser.importColumns',
'tmpl': 'component',
'app': sourceSelect.val(),
'<?php echo JSession::getFormToken()?>': 1
},
function(result) {
$('td.add_column').html(result);
$('button#parse.btn').show();
//edit the result here
return;
},
'html'
);
});
});
Finally, this code is assuming you have this js code either in your view.html.php or in your views/parser/tmpl/default.php. If you have it in a separate .js file, then your php code won't execute and give you the token.
In your ajax call method use url as :
$.ajax({
url: '/index.php?option=com_itemreview&task=item.userReviewVote&<?php echo JSession::getFormToken(); ?>=1',
type: 'post',
data: {'data': submitvalue},
dataType: 'json',
success: function(response) {
}
});
for more information see here:
http://joomlabuzz.com/blog/27-preventing-cross-site-request-forgery-in-joomla
https://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms

Resources