Validating using unobtrusive before ajax post - asp.net-mvc-3

So I have been playing around with the Anti Forgery Token, making progress thanks to you guys.
I have figured out a solution to merge form values anf get my ActionMethods to not puke on the AntiForgery token... I have unfortunately broken validation in the process. The AJAX post fires before client side validation / client side validation is ignored. Server side works however I would dig some validation before the post.. Here is the code I am using.
$(document).ready(function () {
$('input[type=submit]').live("click", function (event) {
event.preventDefault();
// Form with the AntiForgeryToken in it
var _tokenForm = $(this).parents().find("#__AjaxAntiForgeryForm");
// Current Form we are using
var _currentForm = $(this).closest('form');
// Element to update passed in from AjaxOptions
var _updateElement = $(_currentForm).attr("data-ajax-update");
// Serialize the array
var arr = $(_currentForm).serializeArray();
//Merge TokenForm with the CurrentForm
$.merge(arr, $(_tokenForm).serializeArray());
// The AJAX Form Post stuff
$.ajax({
type: "POST",
url: $(_currentForm).attr('action'),
data: arr,
success: function (data) {
$(_updateElement).html(data);
}
});
return false;
});
});
So I am thinking that I need to handle the client side validation some way before the $.ajax goo... Any suggestions would possibly save me some time.

Call this:
var formValid = $("#FormId").validate().form();
if (!formValid) return false;
Added into your code:
$(document).ready(function () {
$('input[type=submit]').live("click", function (event) {
event.preventDefault();
// Form with the AntiForgeryToken in it
var _tokenForm = $(this).parents().find("#__AjaxAntiForgeryForm");
// Current Form we are using
var _currentForm = $(this).closest('form');
var isValid = $(_currentForm).validate().form();
if (!isValid) return false;
// Element to update passed in from AjaxOptions
var _updateElement = $(_currentForm).attr("data-ajax-update");
// Serialize the array
var arr = $(_currentForm).serializeArray();
//Merge TokenForm with the CurrentForm
$.merge(arr, $(_tokenForm).serializeArray());
// The AJAX Form Post stuff
$.ajax({
type: "POST",
url: $(_currentForm).attr('action'),
data: arr,
success: function (data) {
$(_updateElement).html(data);
}
});
return false;
});
});

Related

Is there a way to show "Loading data.." option in Rally Grid(ext JS) while making the Ajax request to load the data?

I am trying to set the message to "Data Loading.." whenever the data is loading in the grid. It is working fine if I don't make an Ajax call. But, when I try to make Ajax Request, It is not showing up the message "Loading data..", when it is taking time to load the data. Can someone please try to help me with this.. Thanks in Advance.
_loadData: function(x){
var that = this;
if(this.project!=undefined) {
this.setLoading("Loading data..");
this.projectObjectID = this.project.value.split("/project/");
var that = this;
this._ajaxCall().then( function(content) {
console.log("assigned then:",content,this.pendingProjects, content.data);
that._createGrid(content);
})
}
},
_ajaxCall: function(){
var deferred = Ext.create('Deft.Deferred');
console.log("the project object ID is:",this.projectObjectID[1]);
var that = this;
console.log("User Reference:",that.userref,this.curLen);
var userObjID = that.userref.split("/user/");
Ext.Ajax.request({
url: 'https://rally1.rallydev.com/slm/webservice/v2.0/project/'+this.projectObjectID[1]+'/projectusers?fetch=true&start=1&pagesize=2000',
method: 'GET',
async: false,
headers:
{
'Content-Type': 'application/json'
},
success: function (response) {
console.log("entered the response:",response);
var jsonData = Ext.decode(response.responseText);
console.log("jsonData:",jsonData);
var blankdata = '';
var resultMessage = jsonData.QueryResult.Results;
console.log("entered the response:",resultMessage.length);
this.CurrentLength = resultMessage.length;
this.testCaseStore = Ext.create('Rally.data.custom.Store', {
data:resultMessage
});
this.pendingProjects = resultMessage.length
console.log("this testcase store:",resultMessage);
_.each(resultMessage, function (data) {
var objID = data.ObjectID;
var column1 = data.Permission;
console.log("this result message:",column1);
if(userObjID[1]==objID) {
console.log("obj id 1 is:",objID);
console.log("User Reference 2:",userObjID[1]);
if (data.Permission != 'Editor') {
deferred.resolve(this.testCaseStore);
}else{
this.testCaseStore = Ext.create('Rally.data.custom.Store', {
data:blankdata
});
deferred.resolve(this.testCaseStore);
}
}
},this)
},
failure: function (response) {
deferred.reject(response.status);
Ext.Msg.alert('Status', 'Request Failed.');
}
});
return deferred;
},
The main issue comes from your Ajax request which is using
async:false
This is blocking the javascript (unique) thread.
Consider removing it if possible. Note that there is no guarantee XMLHttpRequest synchronous requests will be supported in the future.
You'll also have to add in your success and failure callbacks:
that.setLoading(false);

How submit captcha to the controller using ajax and form data

I have a form with some fields and file upload, rendering as a partial view using ajax in asp.net MVC. when submitting the form, I want to pass all the data to the controller. But if I use $("form").serialize(), it is not passing the selected file to the controller. So I am using formData() to pass the data to the controller. Till this point, everything works fine.
But after adding captcha using CaptchaMvc, it not reaching the controller. Even if I enter valid captcha, it is invalid in the controller.
This is how I send data to the controller using the ajax and formData
var data = new FormData();
var vidFile = null;
if ($("#FileUpload")[0].files.length > 0)
vidFile = $("#FileUpload")[0].files[0];
data.append("detail", $("#detail").val());
data.append("name", $("#name").val());
data.append("FileUpload", vidFile);
$.ajax({
url: "/home/submitData",
type: "POST",
contentType: false,
processData:false,
data: data,
success: function (response) {
if (response.success == true) {
} else {
}
}
});
Is there any way to pass the captcha as well to the controller?
Why can't you validate using different controller function, as follows:
At the time of submission, validate the captcha first, and depending on the result, call another controller function to submit data or show the error.
var submitData = function(){
var data = new FormData();
var vidFile = null;
if ($("#FileUpload")[0].files.length > 0)
vidFile = $("#FileUpload")[0].files[0];
data.append("detail", $("#detail").val());
data.append("name", $("#name").val());
data.append("FileUpload", vidFile);
$.ajax({
url: "/home/submitData",
type: "POST",
contentType: false,
processData:false,
data: data,
success: function (response) {
if (response.success == true) {
//Success
} else {
//Submission failed
}
}
});
}
var validateCaptcha = function(){
$.ajax({
url: "/home/validateCaptcha",
type: "POST",
data: $("form").serialize(),
success: function (response) {
if (response.success == true) {
submitData();
} else {
alert("Invalid Captcha entry");
}
}
});
}
$("form").submit(function(e){
validateCaptcha();
});

admin-ajax.php do not recognizes 'action'. $_REQUEST is empty

After two days of fruitless research, I decided to join the community. I hope to get a solution. I develop a plug-in that, among other things, must implement the upload of documents. this should be done using ajax technology. the problem is that the request is approved, but admin_ajax.php reacts like no action was taken. Outside of wp this piece of code works fine, as it was thought out. The problems come with installing this code in wp. Below is my code
PHP. This code in the main class that will call from main modul of plugin
class main{
//other activation methods
private function register_scripts(){
add_action('wp_enqueue_scripts', array($this,'re_add_script'));
}
public function re_add_script() {
wp_enqueue_script('re_upload',plugins_url('re'.'/js/re_upload.js'),array('jquery'));
wp_localize_script('re_upload',"re_ajax",array(
'ajaxurl'=>admin_url("admin-ajax.php")));
add_action( 'wp_ajax_upload', 'processingUpload');
}
}//end of class
//callback function
function processingUpload(){
$clsUpload = new UploadsDocs();
$clsUpload->setRequestedData($_FILES,$_POST['doc_id']);
$clsUpload->checkUploadsFiles();
$clsUpload->outputFilesList();
wp_die();
}
jQuery 're_upload.js'
jQuery(document).ready(function (e) {
jQuery('#bt_upload').on('click', function () {
var toUpload=getFileListToUpload();
var form_data = new FormData();
var ins = input.files.length;
for (var x = 0; x < ins; x++) {
if (isFileToUpload(input.files[x],toUpload)){
form_data.append("files[]", input.files[x]);
}
}
form_data.append("doc_id", jQuery('#doc_id')[0].value);
var data_to_sent={
action: 'upload',
datas: form_data
};
jQuery.ajax({
url: re_ajax.ajaxurl, // point to server-side PHP script
dataType: 'text', // what to expect back from the PHP script
cache: false,
contentType: false,
processData: false,
data: data_to_sent,
type: 'post',
success: function (response) {
// do something
},
error: function (response) {
// do something
},
xhr: function(){
//upload Progress
var xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//update progressbar
jQuery('#bt_upload').css("display","none");
jQuery('#progress-wrp').css("display","block");
jQuery('#progress-wrp' +" .progress-bar").css("width", + percent +"%");
(percent<50)? jQuery('#progress-status').addClass('status-less-then-50'): jQuery('.status-less-then-50').removeClass('status-less-then-50').addClass('status-more-then-50');
jQuery('#progress-status').text("Uploading..."+percent +"%");
}, true);
}
return xhr;
},
mimeType:"multipart/form-data"
});
});
});
function getFileListToUpload(){
var list=[];
var elem = document.getElementsByClassName('preview');
var tag_li=elem[0].querySelectorAll('p');
for (var i=0;i<tag_li.length;i++){
list[i]=tag_li[i].textContent.split('(')[0];
}
return list;
}
function isFileToUpload(input_file,files_toUpload){
var res=false;
for(var i=0; i<files_toUpload.length;i++){
if (input_file.name==files_toUpload[i]){
res=true;
break;
}
}
return res;
}
The problem is
add_action( 'wp_ajax_upload', 'processingUpload');
is not called.
The upload is done in two separate invocations of the server. The first invocation displays the upload page to the user. The second invocation processes the AJAX request. Your call to
add_action( 'wp_ajax_upload', 'processingUpload');
is done in the first invocation where it is not needed but not in the second invocation where it is needed.
Please read https://codex.wordpress.org/AJAX_in_Plugins. (Observe carefully how the call to 'add_action( 'wp_ajax_...', ...) is done.) Further, you need to read about nonces.
Try to append action to your ajax url like:
url: re_ajax.ajaxurl?action=upload
and
data: form_data
or pass it to form_data like:
form_data.append('action', 'upload')

Kendo UI FileUpload via AJAX with JSON

I am using Kendo with MVC 5. I have several form inputs including a fileupload control. Onclick of a button I am building a json object with the values of the inputs and sending it through via an AJAX call.
I want to know how I can include the selected file from the file upload control in the json object that is sent. Here is the code for the upload control:
$(document).ready(function () {
$("#files").kendoUpload({
multiple: false
});
});
And then the ajax call sending the form data:
var ro = new Object();
// ...... //populate some properties
var jsonString = JSON.stringify(ro);
$.ajax({
url: '#Url.Action("Save", "Service")',
data: jsonString ,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
});
The receiving controller action look like this:
public ActionResult Save(MyViewModel model)
{
var obj = //call something here then return resulting obj
return this.Json(obj, JsonRequestBehavior.AllowGet);
}
Any help is appreciated.
Try
$("#files").kendoUpload({
multiple: false,
async: {
saveUrl: '#Url.Action("Save", "Service")',
autoUpload: true
},
upload: function (e) {
var ro = new Object();
//......//populate some properties
var jsonString = JSON.stringify(ro);
e.data = jsonString;
}
});
In your controller:
public ActionResult Save(IEnumerable<HttpPostedFileBase> files, string model)
// string because you used JSON.stringify and it is a string, do not stringify, if you need an object
{
var js = new JavaScriptSerializer();
var objetModel = js.Deserialize<MyViewModel>(model);
var obj = //call something here then return resulting obj
return Json(obj, JsonRequestBehavior.AllowGet);
}
I did not test it - it is just to get you an idea how to pass an additional information along with the uploaded binary file

Reploting a JQplot chart using ajax

I have been trying to solve this in different ways, but haven't make it work as expected, I feel it isn't so big deal (I really hope so) but my experience and skills with Ajax and jQuery are kind of limited that's why I am appealing to your expertise!
I am working on a chart similar to the one here http://www.jqplot.com/tests/data-renderers.php. but in my case the json file is generated depending on a value that the user choses from a select box. I am using 2 files and ajax calls to accomplish this:
-AnnualB.html is the file where the select box is located and the chart should be displayed.
-Index.php is the file where the query to the database is made (using the value obtained from the selectbox in AnnualB.html) and the json array is generated.
In AnnualB.html I use the GET method to retrieve the value from the selectbox and send it to Index.php, which generates the json data. Based on that json data the chart has to be created in AnnualB... Here is where my problem comes. The function to generate the chart is working fine and the call to send the select value and return the json is also working (have checked with Firebug), but I know am missing something (but don't know what yet) because I don't manage to pass the json data to the function that generates the chart.
My codes in AnnualB.html goes like this (abbreviating some irrelevant information with ...):
Function to generate the chart (Is working ok if the json data is passed)
function CreateGraph() {
$(document).ready(function(){
var ajaxDataRenderer = function(url, plot) {
var ret = null;
$.ajax({
async: false,
url: url,
dataType:'json',
success: function(data) {
ret = data; }
});
return ret; };
$.jqplot.config.enablePlugins = true;
var jsonurl = "./index.php";
var plotData = ajaxDataRenderer(jsonurl);
var series = ...
plot1 = $.jqplot('Chart1', series,{...}}
Ajax Call (PROBABLY WHERE MY MISTAKE/OMISSION IS)
function LoadGraph(int)
{
if (window.XMLHttpRequest)
{xmlhttp=new XMLHttpRequest();}
else
{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.open("GET","index.php?tasel="+int,true);
xmlhttp.send();
xmlhttp.onreadystatechange=function()
{
CreateGraph(int)
}
}
Select box
<select name="tasel" size="1" onchange="LoadGraph(this.value)">
<option value="">Select accounts type:</option>
<option value="3">Tuloslaskelma</option>
<option value="2">Tasevastattava</option>
<option value="1">Tasevastaava</option>
</select>
The related code in Index.php goes like this (Is working ok when the value of the select box (tasel) is passed)):
$tasel = $_REQUEST['tasel'];
if ($tasel == ...2)
{...}
.
.
.
echo "[",$selite, ",";// These 2 variables create the json array
echo $finaljson, "]";
Thanks in advance for your patience and help!
I realized the answer to this question was simpler than what I was expecting.
Instead of making the whole function LoadGraph(int) ajax call, I just needed to call the tasel value ?tasel="+int in the function to generate the chart like this (which is already doing an ajax call):
function CreateGraph() {
$(document).ready(function(){
var ajaxDataRenderer = function(url, plot) {
var ret = null;
$.ajax({
async: false,
url: url,
dataType:'json',
success: function(data) {
ret = data;
}
});
return ret;
};
$.jqplot.config.enablePlugins = true;
var jsonurl = "./index.php?tasel="+int;
var plotData = ajaxDataRenderer(jsonurl);
var series = ...
plot1 = $.jqplot('Chart1', series,{...}
}
var plot1 = undefined;
var plotOptions = undefined;
function CreateGraph() {
$.ajax({
async: false,
url: "./index.php",
dataType:'json',
success: function(data) {
var series = fn... // Convert your json Data to array
if(plot1 != undefined)
{
plot1.destroy();
}
plot1 = $.jqplot('Chart1', series, plotOptions);
}
});
}
$(function(){
$.jqplot.config.enablePlugins = true;
plotOptions = {...}; // jqPlot options
CreateGraph();
});
Hope this might help you..

Resources