I create a survey. For whole survey I have only View and for every question partial view. Also I have a pagination. All these demonstrated in the picture below.
Now people can post the form (whole question) to server using GetAnswersMulti method. (I need the form be posted asynchronously). I want to add a feature - when person see the last not answered question - button changes from Answer to Answer and exit. I suppose to do it by removing one button and add another with specific Url. The problem is - server should check if this question is last.
I try to call corresponding method in controller asynchronously and get the returned value.
I tried much from SO and there is what I came to:
View
<script>
function isLast(data) {
$.ajax({
type: "POST",
url: "#Url.Action("Survey", "IsLastQuestion")",
data: { idQuestion: data },
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert("success");
if (msg == "True") {
$(".submitbutton").remove();
}
},
error: function (e) {
alert("Fail");
}
});
}
</script>
#using (Html.BeginForm("GetAnswersMulti", "Survey", FormMethod.Post))
{
<input value="Ответить" type="submit"
class="btn btn-default submitbutton"
onclick="isLast(#Model.FirstOrDefault().IdQuestion);" />
}
Controller
[HttpPost]
public ActionResult IsLastQuestion(int idQuestion)
{
Question question = Manager.GetQuestion(idQuestion);
List<Question> questions = Manager.SelectQuestions(question.idAnketa);
if (questions.Count == Manager.GetCountQuestionsAnswered(question.idAnketa, SessionUser.PersonID))
return new JsonResult() { Data = true };
else
return new JsonResult() { Data = false };
}
[HttpPost]
public void GetAnswersMulti(List<PossibleAnswerVM> possibleAnswers)
{
List<Answer> answers = new List<Answer>();
foreach (PossibleAnswerVM possibleAnswer in possibleAnswers)
{
Answer answer = new Answer();
answer.datetimeAnswer = DateTime.Now;
answer.idOption = possibleAnswer.IdOption;
answer.idPerson = SessionUser.PersonID;
if (possibleAnswer.IsChecked)
{
if (IsValid(answer))
answers.Add(answer);
}
}
Manager.SaveAnswers(answers,possibleAnswers.FirstOrDefault().IdQuestion, SessionUser.PersonID);
}
Now method in controller is called and idQuestion is passed. Method in controller returns true (when it IS the last question). Then I get fail in js code.
Help me with this please. I searched 2 days through SO but didn't find anything that works for me.
Maybe better to use Html.Beginform() and use this script:
<script>
function isLast(data) {
$.ajax({
type: "POST",
url: "#Url.Action("Survey", "IsLastQuestion")",
data: { idQuestion : data},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg){
alert($.parseJSON(msg.d));
if (msg == "True") {
$(".submitbutton").remove();
}
},
error: function (e) {
alert("Fail");
}
});
}
</script>
#using (Html.BeginForm("GetAnswersMulti", "Survey", FormMethod.Post)
<input type="text" id="commentText" placeholder="Введите коментарий"/>
<input value="Ответить" type="submit"
class="btn btn-default submitbutton"
onclick="isLast(#Model.FirstOrDefault().IdQuestion);" />
}
In order for your action to return Json, then the return type of the action needs to be Json. Since the action returns a boolean value (true or false), then it is not considered as an action method. It needs to return an ActionResult type like so
public ActionResult IsLastQuestion(int idQuestion)
{
Question question = Manager.GetQuestion(idQuestion);
List<Question> questions = Manager.SelectQuestions(question.idSurvey);
if (questions.Count == Manager.GetCountQuestionsAnswered(
question.idSurvey,SessionUser.PersonID))
return Json(new{ d = true});
else
return Json(new{ d = false});
}
Notice that when I return Json like so return Json(new{ d = true});, there is an anonymous variable d which is the boolean value you will check in your success function like this
success: function (msg){
alert($.parseJSON(msg.d));
if (msg.d === true) {
$(".submitbutton").remove();
}
else if(msg.d == false){
// Do something if false retured.
}
}
Can you try like this?
[HttpGet]
public ActionResult IsLastQuestion(int idQuestion)
{
Question question = Manager.GetQuestion(idQuestion);
List<Question> questions = Manager.SelectQuestions(question.idSurvey);
if (questions.Count == Manager.GetCountQuestionsAnswered(question.idSurvey, SessionUser.PersonID))
return Content("True", "application/json" );
else
return Content("False", "application/json" );
}
In your ajax call-
function isLast(data) {
$.ajax({
type: "GET",
url: "#Url.Action("Survey", "IsLastQuestion")",
data: { idQuestion: data },
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result)
{
//check the value inside result here..
},
error: function (e) {
alert("Fail");
}
});
}
Parameter is needed in IsLastQuestion function and you dont pass it in script.
function isLast(parameter) {
$.ajax({
type: "POST",
url: "#Url.Action("Survey", "IsLastQuestion")",
data: "{parameter}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg){
alert($.parseJSON(msg.d));
},
error: function (e) {
alert("Fail");
}
});
if (isLast2 == true) {
$(".submitbutton").remove();
}
}
Related
I have this controller action:
[HttpPost]
public ActionResult OrderData(Order order)
{
var result = new { redirectToUrl = Url.Action("SeatSelection", "Orders", new { id = order.ScreeningId }), order };
return Json(result);
}
and I'm trying to pass the order object to another action:
public ActionResult SeatSelection(int id, Order order)
{
var screeningInDb = _context.Screenings.Include(s => s.Seats).Single(s => s.Id == order.ScreeningId);
var viewModel = new SeatSelectionViewModel
{
Seats = screeningInDb.Seats,
NumberOfTicketsOrdered = order.NumberOfTicketsOrdered
};
return View("SeatSelection", viewModel);
}
The problem is - the only parameter I'm receiving in SeatSelection Action is the id parameter, although the order object in OrderData Action is valid. I'm pretty sure the problem is within the way I'm trying to pass the order object, maybe something with the syntax?
Here is the way I'm posting my form data to the OrderData Action:
$.ajax({
type: "POST",
url: '#Url.Action("OrderData", "Orders")',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(orderData),
dataType: "json",
success: function (res) {
alert("Success!");
window.location.href = res.redirectToUrl;
},
error: function (xhr, status, error) {
alert(status);
}
});
Bottom line - What I'm eventually trying to do is to pass the form to a Controller Action where the data will be processed, and then pass the new data to "SeatSelection" view. I had trouble doing this as my post method sends JSON data, so if there is a better way to do what I'm trying to do, I would be happy to learn!
Your model doesn't match SeatSelection parameter signature.
Try:
$.ajax({
type: "POST",
url: '#Url.Action("OrderData", "Orders")',
contentType: "application/json; charset=utf-8",
data: `{"order": ${JSON.stringify(orderData)}}`,
dataType: "json",
success: function (res) {
alert("Success!");
window.location.href = res.redirectToUrl;
},
error: function (xhr, status, error) {
alert(status);
}
});
or (this one just creates a javascript object, which has the two signature properties in):
const sendObj = { id: 0, order: orderData };
$.ajax({
type: "POST",
url: '#Url.Action("OrderData", "Orders")',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(sendObj),
dataType: "json",
success: function (res) {
alert("Success!");
window.location.href = res.redirectToUrl;
},
error: function (xhr, status, error) {
alert(status);
}
});
you can't use
window.location.href = ...
because in this case browser always calls a GET method that can only keep data in a query string with primitives parameters and it doesn't convert Order to a qusery string parameters. This is why you can get only id.
in your case it would be much easier to redirect directly in the action
public ActionResult OrderData(Order order)
{
return RedirectToAction( ( "SeatSelection", "Orders", new { id = order.ScreeningId }), order });
}
or when it is the same controller I usually do this
public ActionResult OrderData(Order order)
{
return SeatSelection (order.ScreeningId, order };
}
but since you are using ajax it will redirect, but will not update your view. For ajax you need a partial view that should be updated on success. So instead of ajax you can only submit form using button. In this case everything will be working ok.
Another way you can use ajax is you can try to split the order in properties and create a query string.
I have the following jquery function which is sending data to a controller:
function bound(e) {
var ele = document.getElementsByClassName("e-grid")[0]
ele.addEventListener('click', function (e) {
if (e.target.classList.contains('e-up')) {
var grid = document.getElementById('FlatGrid').ej2_instances[0]; //Grid Instance
var rowObj = grid.getRowObjectFromUID(ej.base.closest(e.target, '.e-row').getAttribute('data-uid'));
var data = rowObj.data;
//alert(JSON.stringify(data));
var code = data.ClientCode;
$.ajax({
type: "POST",
url: "/Client/ShowClient",
data: { "ClientCode": code }, //First item has latest ID
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.length !== 0) {
console.log(data);
}
},
error: function (data) {
console.log(data);
}
});
}
});
}
And my controller method:
[HttpPost]
public ActionResult ShowClient(string ClientCode)
{
if (ClientCode == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
*action*
}
However I am getting a 500 (Internal Server Error) error for this. Any idea what I am missing cause my method is not being hit at all.
And I can see that var code does have the correct string value.
Remove commas from the parameter name "ClientCode" and contentType and will be work
$.ajax({
type: "POST",
url: "/Client/ShowClient",
data: { ClientCode: code }, //First item has latest ID
success: function (data) {
if (data.length !== 0) {
console.log(data);
}
},
error: function (data) {
console.log(data);
}
});
The comments have provided you with a combination of suggestions that when put together will give you the desired behavior.
First, you can build the URL in teh view using #Url.Action
url: '#(Url.Action("ShowClient","Client"))',
Next, the object model is not being built correctly
data: { ClientCode: code },
Note the last of quotes around the key.
And finally remove the JSON content type.
Which results to portion of code.
$.ajax({
type: "POST",
url: '#(Url.Action("ShowClient","Client"))',
data: { ClientCode: code },
success: function (data) {
if (data.length !== 0) {
console.log(data);
}
},
error: function (data) {
console.log(data);
}
});
Change the url to this:
url: "../Client/ShowClient"
This ajax is calling from .cshtml file to controller but getValue function is taking Null value on load, but afterwards it works fine. It evens shows the value on alert on ajax call, but getting null on controller. Any help would be highly appreciated.
<script>
$(document).ready(function(){
//get value from dropdown list
var ID = $('#cmb').val();
// ID is taking value
$.ajax({
// /ControllerName/FunctionName
// /Home/getvalue
url: "/Home/getValue",
type: "POST",
// ID is getting from dropdownList
// parameterName/value
data: JSON.stringify({'_ID':ID}),
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status == "success") {
//if got response
//alert(data.status);
}
},
error: function () {
//if if not response
//alert('something went wrong');
}
});
});
</script>
[HttpPost]
public JsonResult getValue(string _ID)
{
string a = _ID;
}
It is reasonable that you are taking null on the load, since the value of HTML element with id cmd would be undefined, since I assume that there isn't any value that is selected (option of a select element has an attribute called selected, when you have selected a value this attribute has the value true).
The strange thing is that you say that afterwards works as it is expected. I doubt this, except if you have any other code that you haven't include it in your post. As it seems there is only an AJAX call after the successfull load of the DOM.
Usually we register to an event, when we make an AJAX call like this. I could assume that you could register to the onChange event of the value of select element (dropdown)
$(document).ready(function(){
$("#cmb").on("change", function(){
//get value from dropdown list
var ID = $(this).val();
// ID is taking value
$.ajax({
// /ControllerName/FunctionName
// /Home/getvalue
url: "/Home/getValue",
type: "POST",
// ID is getting from dropdownList
// parameterName/value
data: JSON.stringify({'_ID':ID}),
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status == "success") {
//if got response
//alert(data.status);
}
},
error: function () {
//if if not response
//alert('something went wrong');
}
});
});
});
You have to change your URL and parameter check below code for that :
$(document).ready(function(){
//get value from dropdown list
var ID = $('#cmb').val();
// ID is taking value
$.ajax({
url: "/Home/getValue?_ID=" + ID,
type: "POST",
dataType: "json",
data: 'json',
success: function (data) {
if (data.status == "success") {
//if got response
//alert(data.status);
}
},
error: function () {
//if if not response
//alert('something went wrong');
}
});
});
Cheers !!
Change Paramaters Name
use id in replace of _ID
[HttpPost]
public JsonResult getValue(string id)
{
string a = id;
}
$(document).ready(function(){
$("#cmb").on("change", function(){
//get value from dropdown list
var id= $(this).val();
// ID is taking value
$.ajax({
// /ControllerName/FunctionName
// /Home/getvalue
url: "/Home/getValue",
type: "POST",
// ID is getting from dropdownList
// parameterName/value
data: JSON.stringify({'id':ID}),
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status == "success") {
//if got response
//alert(data.status);
}
},
error: function () {
//if if not response
//alert('something went wrong');
}
});
});
});
if you are sure that your ID is not null then just try this.
<script>
$(document).ready(function(){
var ID = $('#cmb').val();
$.ajax({
url: "/Home/getValue",
type: "POST",
data: {_ID:ID},
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status == "success") {
//if got response
//alert(data.status);
}
},
error: function () {
//if if not response
//alert('something went wrong');
}
});
});
Ajax doesn't send any strings to the controller.
Here's my function:
$(function () {
$('#btnAnswer').click(function () {
var code = $('#Answer').val();
$.ajax({
url: '#Url.Action("CheckAnswer", "Home")',
type: "POST",
data: code ,
datatype: "text",
success: function (resultFromFunct) {
$("#resultsBox").append(resultFromFunct);
}
});
$('#Answer').val('');
});
});
Here's my controller:
[HttpPost]
public string CheckAnswer(string answer)/
{
game.LogUserAnswer(Request.Cookies["user"].Value, answer);
return String.Format("<strong>{0}</strong>: {1} <br>", Request.Cookies["user"].Value, game.UserGuess(answer));
}
Ajax is correctly get into CheckAnswer method but answer is always null. I've tried other examples from stack, for instance Asp.Net Mvc JQuery ajax input parameters are null but always get null result. Do you have any thoughts of the cause?
Change your request parameters to data: { answer: code } in your request. It probably can not match code to the parameter on your action.
$(function () {
$('#btnAnswer').click(function () {
var code = $('#Answer').val();
$.ajax({
url: '#Url.Action("CheckAnswer", "Home")',
type: "POST",
data: { answer: code },
datatype: "text",
success: function (resultFromFunct) {
$("#resultsBox").append(resultFromFunct);
}
});
$('#Answer').val('');
});
});
I'm new to AJAX, and I don't understand, why my data was not sent to controller.
So, on my View I have two input forms and a button:
HTML:
<input type="text" name="AddName">
<input type="text" name="AddEmail">
<button class="btn btn-mini btn-primary" type="button" name="add_btn" onclick="DbAdd()">Add</button>
I need after button "add_btn" clicked take data from these two inputs and send them to controller.
JavaScript:
<script type="text/javascript">
function DbAdd()
{
// Get some values from elements on the page:
var $form = $(this),
addedName = $form.find("input[name='AddName']").val(),
addedEmail = $form.find("input[name='AddEmail']").val();
$("#UserTable").html("<div>Please Wait...</div>");
$.ajax(
{
type: "POST",
url: "Save",
data:
{
name: addedName, email: addedEmail,
},
dataType: "json",
contentType: "application/json; charset=utf-8",
success: OnSuccess,
error: OnError
});
}
And this is my controller's method "Save" (I need to save data got from ajax to my DB):
[HttpPost]
public ActionResult Save(User userinfo)
{
string message = "";
using (var uc = new UserContext())
{
uc.UserList.Add(userinfo);
uc.SaveChanges();
message = "Successfully Saved!";
}
if (Request.IsAjaxRequest())
{
return new JsonResult { Data = message };
}
else
{
ViewBag.Message = message;
return View(userinfo);
}
}
The problem is that when I put a break point to my controller's method, I don't receive data from ajax, null's only. So I add an empty record to DB.
Any suggestions?
Looks like $form.find("input[name='AddName']").val() and $form.find("input[name='AddEmail']").val() both return null. You should use $("input[name='AddName']").val() and $("input[name='AddEmail']").val() instead. Change the definition of DbAdd() to below
<script type="text/javascript">
function DbAdd()
{
// Get some values from elements on the page:
var addedName = $("input[name='AddName']").val(),
addedEmail = $("input[name='AddEmail']").val();
var user = { Name: addedName, Email: addedEmail };
$("#UserTable").html("<div>Please Wait...</div>");
$.ajax(
{
type: "POST",
url: "Save",
data: JSON.stringify({ userinfo: user }),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: OnSuccess,
error: OnError
});
}
</script>
There is an extra comma which may be causing syntax error:
data:
{
name: addedName, email: addedEmail, //<------------ here
}
and pass data like this:
var userinfo = { name: addedName, email: addedEmail };
data: JSON.stringify(userinfo)
Also you should see : Posting JavaScript objects with Ajax and ASP.NET MVC