I'm trying to make a drop down menu that whenever an option is selected it needs to update a row in a database. I'm creating the drop down menu with this code
Form
using (Ajax.BeginForm("PartialViewName", "admin", null, new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
//LoadingElementId = "LoadingLink",
UpdateTargetId = "PartialViewName"
}, new { id = "connectNewForm" }))
The drop down code
<select name="statusDD" onchange="ChangeStatus(this.value)">
<option value="">Update Status</option>
<option value="1">Open</option>
<option value="2 ">In Progress</option>
<option value="3">Pending</option>
<option value="4">To Be Verified</option>
<option value="5">Approved</option>
<option value="6">Disapproved</option>
<option value="7">Closed</option>
</select>
The ChangeStatus
function ChangeStatus() {
var form = jQuery(".FormID");
var formData = form.serialize();
$.ajax({
url: "/Controller/ActionResult",
data: formData,
cache: false,
error: function (e) {
if (form == null) {
alert("DIDN'T WORK FORM IS NULL");
}
else {
alert("DIDN'T WORK something else");
}
},
success: function (response) {
// A response to say if it's updated or not
alert("worked");
}
});
}
In the controller
public ActionResult UpdateStatus(int id, FormCollection formValues)
{
int ID = util.IntUtilParse(formValues["ID"]);
int newStatus = util.IntUtilParse(formValues["Status"]);
using (var dbContext = new Project.OpenAccess.DataBase())
{
//var swm = dbContext.StoredProcedure(
var swm = dbContext.StoredProcedure(ID, newStatus);
dbContext.SaveChanges();
return PartialView();
}
}
Whenever I select an option it goes through the ajax and then throws an error and never makes it to the controller. I'm very new to Ajax and I'm not sure whats going on.
$.ajax({
url: "/Controller/ActionResult",
data: formData,
cache: false,
Try changing to
$.ajax({
url: 'http://localhost\\:#####/{Controller Name}/UpdateStatus',
data: formData,
type: "POST",
cache: false,
Not 100% on your application logic, but this is why you're not hitting the controller. Note that the placeholder is indicating the name of your controller, since the name of it is not posted. For example if the name is CustomerController then your ajax url will look as such url: 'http://localhost\\:#####/Customer/UpdateStatus'
Related
Hello I want to load country state and city using select2.js how can i achieve this? i make ajax call to load details of country state and city... i am facing problem when trying to make ajax call to load data using webmethod. BindCountryData and BidnStateData are never called please suggest me solution for that what changes should i do to make call.
$(document).ready(function){
country();
}
function country(){
$(".autosuggest").select2({
minimumInputLength: 1,
placeholder: "Select Item",
allowClear: true,
ajax: {
type: "POST",
url: 'country.aspx/BindCountryData',
async : false,
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: function(term) {
return {
country: term
};
},
results: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.completeName,
slug: item.slug,
id: item.id
}})};}}});}}
$('.autosuggest').change(function () {
searchState();
});
function searchState(){
$(".State").select2({
minimumInputLength: 1,
placeholder: "Select State",
allowClear: true,
ajax: {
type: "POST",
url: 'state.aspx/BidnStateData',
async : false,
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: function(term) {
return {
state: term,
countryId : $('.autosuggest').val()
};
},
results: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.completeName,
slug: item.slug,
id: item.id
}
})
};
}
}
});
}}
I've been using the following approach in my projects:
1) Load select elements at initial stage, and bind onChange action:
<select class="selectcombusca" name="zone_id" onChange="carregacidades($('option:selected',this).val());">
<option value="#">Select State</option>
<option value="1">State 1</option>
<option value="2">State 2</option>
</select>
<select class="selectcombusca" name="cidade_id">
<option value="#">Select City</option>
<option value="1">City 1</option>
<option value="2">City 2</option>
</select>
2) Apply select2 to initial elements:
$(".selectcombusca").select2();
3) Function to load cities based on the selected state, triggered on the select change:
function carregacidades(zone_id) {
$.ajax({
url: your-url,
type: 'post',
dataType: 'json',
data: 'zone_id=' + zone_id, //from the selected option
beforeSend: function() {
$('select[name=\'cidade_id\']').hide();
$('select[name=\'cidade_id\'] + .select2').hide();
//I like to hide the inital element so the user can undestand there's a call being made, avoiding multiple changes on the element.
$('select[name=\'cidade_id\']').after('<span class="loading">Loading Indicator<span>'); //I also like to put some kind of loading indicator, like a spinner
},
complete: function() {
$('.loading').remove(); //remove the loading indicator
$('select[name=\'cidade_id\']').show(); //show DOM element
$("select[name=\'cidade_id\']").select2().val('#'); //rerender select2 and set initial option
$('select[name=\'cidade_id\'] + .select2').show(); //show select2 element
},
success: function(json) {
//create the new options based on the call return
html = '<option value="#">Cidade</option>';
if (json['cidade'] && json['cidade'] != '') {
for (i = 0; i < json['cidade'].length; i++) {
html += '<option value="' + json['cidade'][i]['cityId'] + '">' + json['cidade'][i]['cityName'] + '</option>';
}
}
$('select[name=\'cidade_id\']').html(html); //replace select options on DOM
},
error: function(xhr, ajaxOptions, thrownError) {
//handle error
}
});
};
In short: by changing the select element, I hide the element that will receive the new information, make the call, add then add the information to DOM (still hidden). Finally, rerender the select2 element with the new options and then show it.
I hope this helps you.
How do I pass a whole set model object through formdata and convert it to model type in the controller?
Below is what I've tried!
JavaScript part:
model = {
EventFromDate: fromDate,
EventToDate: toDate,
ImageUrl: imgUrl,
HotNewsDesc: $("#txthtDescription").val().trim(),
};
formdata.append("model",model);
then pass it through AJAX, it will be a string, and if I check the value of Request.Form["model"] the result will be same, that is it will be received as string and value will be "[object object]"
Is there any way to pass model through formdata and receive it in the controller?
If your view is based on a model and you have generated the controls inside <form> tags, then you can serialize the model to FormData using
var formdata = new FormData($('form').get(0));
This will also include any files generated with <input type="file" name="myImage" .../>
and post it back using
$.ajax({
url: '#Url.Action("YourActionName", "YourControllerName")',
type: 'POST',
data: formdata,
processData: false,
contentType: false,
});
and in your controller
[HttpPost]
public ActionResult YourActionName(YourModelType model)
{
}
or (if your model does not include a property for HttpPostedFileBase)
[HttpPost]
public ActionResult YourActionName(YourModelType model, HttpPostedFileBase myImage)
{
}
If you want to add additional information that is not in the form, then you can append it using
formdata.append('someProperty', 'SomeValue');
If you want to send Form data using Ajax.This is the way to send
var formData = new FormData();
//File Upload
var totalFiles = document.getElementById("Iupload").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("Iupload").files[i];
formData.append("Document", file);
}
formData.append("NameCode", $('#SelecterID').val());
formData.append("AirLineCode", $('#SelecterID').val());
$.ajax({
url: "/Controller/ActionName",
type: "POST",
dataType: "JSON",
data: formData,
contentType: false,
processData: false,
success: function (result) {
}
})
Using Pure Javascript, considering you have
<form id="FileUploadForm">
<input id="textInput" type="text" />
<input id="fileInput" type="file" name="fileInput" multiple>
<input type="submit" value="Upload file" />
</form>
JS
document.getElementById('FileUploadForm').onsubmit = function () {
var formdata = new FormData(); //FormData object
var fileInput = document.getElementById('fileInput');
//Iterating through each files selected in fileInput
for (i = 0; i < fileInput.files.length; i++) {
//Appending each file to FormData object
formdata.append(fileInput.files[i].name, fileInput.files[i]);
}
//text value
formdata.append("textvalue",document.getElementById("textInput").value);
//Creating an XMLHttpRequest and sending
var xhr = new XMLHttpRequest();
xhr.open('POST', '/Home/UploadFiles');
xhr.send(formdata); // se
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
//on success alert response
alert(xhr.responseText);
}
}
return false;
}
in your C# controller you can get values it as below
[HttpPost]
public ActionResult UploadFiles(YourModelType model, HttpPostedFileBase fileInput)
{
//save data in db
}
Reference : File Uploading using jQuery Ajax or Javascript in MVC
In view side ,if you are using ajax then,
$('#button_Id').on('click', function(){
var Datas=JSON.stringify($('form').serialize());
$.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
url: '#Url.Action("ActionName","ControllerName")',
data:Datas,
cache: false,
dataType: 'JSON',
async: true,
success: function (data) {
},
});
});
In Controller side,
[HttpPost]
public ActionResult ActionName(ModelName modelObj)
{
//Some code here
}
So I want to POST fileUpload along with AntiForgeryToken via AJAX. Here's my code :
View
#using (Html.BeginForm("Upload", "RX", FormMethod.Post, new {id = "frmRXUpload", enctype = "multipart/form-data"}))
{
#Html.AntiForgeryToken()
#Html.TextBoxFor(m => m.RXFile, new {.type = "file"})
...rest of code here
}
<script>
$(document).ready(function(){
$('#btnRXUpload').click(function () {
var form = $('#frmRXUpload')
if (form.valid()) {
var formData = new FormData(form);
formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]);
formData.append('__RequestVerificationToken', fnGetToken());
$.ajax({
type: 'POST',
url: '/RX/Upload',
data: formData,
contentType: false,
processData: false
})
}
})
})
</script>
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload()
{
//rest of code here
}
I get
The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster
error via fiddler. Any idea how to solve this issue?
I FOUND THE ANSWER :
<script>
$(document).ready(function(){
$('#btnRXUpload').click(function () {
var form = $('#frmRXUpload')
if (form.valid()) {
var formData = new FormData(form.get(0)); //add .get(0)
formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]);
$.ajax({
type: 'POST',
url: '/RX/Upload',
data: formData,
contentType: false,
processData: false
})
}
})
})
</script>
FINALLY FOUND THE ANSWER :
I just need to add .get(0) in the form, here's the code :
<script>
$(document).ready(function(){
$('#btnRXUpload').click(function () {
var form = $('#frmRXUpload')
if (form.valid()) {
var formData = new FormData(form.get(0)); //add .get(0)
formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]);
//formData.append('__RequestVerificationToken', fnGetToken()); //remark this line
$.ajax({
type: 'POST',
url: '/RX/Upload',
data: formData,
contentType: false,
processData: false
})
}
})
})
</script>
You need to add the token to the request headers, not the form. Like this:
if (form.valid()) {
var formData = new FormData(form);
formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]);
$.ajax({
type: 'POST',
url: '/RX/Upload',
data: formData,
contentType: 'multipart/form-data',
processData: false,
headers: {
'__RequestVerificationToken': fnGetToken()
}
})
}
Edit
Looking back at how I solved this problem myself, I remember that the standard ValidateAntiForgeryTokenAttribute looks in the Request.Form object which doesn't always get populated for an AJAX request. (In your case, the file upload needs a multipart/form-data content type, whereas a form post for the CSRF token needs application/x-www-form-urlencoded. You set contentType=false, but the two operations need conflicting content types, which may be part of your problem). So, in order to validate the token on the server, you will need to write a custom attribute for your action method that checks for the token in the request header:
public sealed class ValidateJsonAntiForgeryTokenAttribute
: FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookie != null ? cookie.Value : null,
httpContext.Request.Headers["__RequestVerificationToken"]);
}
}
More info (a bit out of date now) here.
I am trying as the title says to return a Json message from the Controller to the View after it validates.
I have made a breakpoint, and I know that the code works from Controller side, and that my JavaScript calls with success the ActionResult now. How do I display that message in the View?
There are two buttons, stamp in and stamp out. If the user stamps in twice, it should get a message, same with stamp out. I have two ActionResults who are indentical except some message and string changes.
Controller:
[HttpPost]
public ActionResult CreateStamp(Stamping stampingmodel)
{
var validateMsg = "";
stampingmodel.Timestamp = DateTime.Now;
stampingmodel.StampingType = "in";
if (stampingmodel.User == null || ModelState.IsValid)
{
var idValidated = db.Users.Find(model.UserId);
if (idValidated != null)
{
var stamp =
db.Stampings.Where(s => s.UserId == stampingmodel.UserId)
.OrderByDescending(s => s.Timestamp)
.FirstOrDefault();
if (stamp.StampingType == stampingmodel.StampingType)
{
if (stampingmodel.StampingType == "in")
{
validateMsg = "Stamped Twice In A Row!";
}
}
else
{
if (stampingmodel.StampingType == "in")
{
validateMsg = "Stamped In, Welcome.";
}
}
}
db.Stampings.Add(stampingmodel);
db.SaveChanges();
}
return Json(new {Message = validateMsg });
JavaScript:
$(document).ready(function () {
$("#stampInBtn").click(function () {
var userId = $("#userId").val();
$.ajax({
url: "ComeAndGo/CreateStamp",
type: "POST",
dataType: "json",
data: {
userId: userId,
}
});
});
View:
<input type="text" id="idUser" class="form-control" />
<br />
<input type="submit" value="IN" id="stampInBtn" />
I have more code inside the View of course; divs, head, body, title and scripts. But it's perhaps a little irrelevant.
What should I do to successfully show those messages?
Regards.
Add a success function to the ajax call
$.ajax({
url: "ComeAndGo/CreateStamp",
type: "POST",
dataType: "json",
data: { userId: userId },
success: function(data) {
// data contains the value returned by the server
console.log(data);
}
});
So if the controller returns
return Json("This is a message");
the value of data will be "This is a message". Note the return value can be a complex type or a partial view
You are getting the value of $("#userId"), but your input has an id of idUser.
Try making your input:
<input type="text" id="userId" class="form-control" />
Also it would be a good idea to provide your Stamping model structure as it seems that you only pass the user id in your post and nothing else.
Change your javascript code as following:
$(document).ready(function () {
$("#stampInBtn").click(function () {
var userId = $("#userId").val();
$.ajax({
url: "ComeAndGo/CreateStamp",
type: "POST",
dataType: "json",
data: {
userId: userId,
},
success: function(data) {
var objData= jQuery.parseJSON(data);
alert(objData.Message );
},
error: function (request, status, error) {
alert(request.responseText);
}
});
});
});
I am new to MVC and Javascript. I am trying to make a "change user info" page for admin. I have a dropdown which lists registered users and some textbox for enter various info about users (eg, name, surname). My objective is auto fill textboxes with users current info when selected an user with dropdownlist. But because of MVC is not event driven and doesn't have postback I don't exactly know how to accomplish this. I think I have to trigger a controller method by dropdownlist's onchange and I think the only way is using JS, AJAX or something like these.
Note: I can do all database stuff in Controller.
I have this code so far in my view:
.... #Html.DropDownList("Users", ViewBag.Users as SelectList, "Select a User", new { id="UserId", onchange="userChanged()"} ) ....
.... <script type="text/javascript">
function userChanged() {
}
</script> ....
You can define your controller action method as JsonResult and call it from your jquery using AJAX.
Once you get data using AJAX, you can parse it and fill appropriate textbox with that data.
you can use below code on how to call ajax in you userChanged method:
$.ajax ({
url: '/Controller/Action',
type: 'GET',
async: true,
cache: false,
data: { userId: useridofwhichdatatobefetched},
success: function (result) {
$("#usernametextbox").val = result.userName; }
});
$(document).ready(function(){
$("#UserId").change(function () {
if ($(this).val() != "" && $(this).val() != undefined && $(this).val() != null)
$.ajax({
type: "GET",
url: "/[ControllerName]/[ActionName]/" + $("#UserId").val()
})
.success(function (data) {
// 'data' consits of values returned from controller.
// fill textboxes with values in 'data'
});
});
});
Hope this helps you.
Try something like this (fiddle):
<select id="select1">
<option value="userId1">User 1</option>
<option value="userId2">User 2</option>
<option value="userId3">User 2</option>
</select>
<textarea id="txt1">
</textarea>
$(function(){
$('#select1').change(function(){
$.ajax({
url: "YourAction", // Url.Action()
data: {
userId: $(this).val()
},
success: function(data) {
$('#txt1').val(data);
}
});
});
});