Need to simulate an #Html.action() on a button click - c#

I'm having some issues with updating a partial view in my index view. Basically, based on a click, I would like to have updated information.
//controller
public ActionResult Index()
{
var filteredObservations = getFilteredObservationSessions().ToList();
var observationManagementVm = new ObservationManagementVM(filteredObservations);
return View(observationManagementVm);
}
public ActionResult indexPagedSummaries(int? page, List<ObservationSessionModel> data)
{
var alreadyFilteredObservations = data;
int PageSize = 10;
int PageNumber = (page ?? 1);
return PartialView(alreadyFilteredObservations.ToPagedList(PageNumber, PageSize));
}
My main view
//index.cshtml
#model AF.Web.ViewModels.ObservationManagementVM
....
<div id="testsim">
#Html.Action("indexPagedSummaries", new { data = Model.ObservationSessions })
</div>
<input id="new-view" value="Sessions" type="button" />
<script>
$("#new-view").click(function() {
$.ajax({
type: "GET",
data: { data: "#Model.FeedBackSessions" },
url: '#Url.Action("indexPagedSummaries")',
cache: false,
async: true,
success: function (result) {
console.log(result);
$('#testsim').html(result);
$('#testsim').show();
}
});
});
</script>
....
And my partial view
//indexPagedSummaries.cshtml
#model PagedList.IPagedList<AF.Services.Observations.ObservationSessionModel>
#using (Html.BeginForm("indexPagedSummaries"))
{
<ol class="vList vList_md js-filterItems">
#foreach (var item in Model)
{
#Html.DisplayFor(modelItem => item)
}
</ol>
<div>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page }))
</div>
}
Html.Action() returns what I want perfectly, but it doesn't seem to be able to be triggered by a button click.
So, I'm not getting any errors, but the url doesn't give any data back. When I try to run the Observation/indexPagedSummary url without passing in data, I get a System.ArgumentNullException error, so I'm assuming that something is being transferred to the view model. Any help would be so appreciated.

Have not run your code but I believe it is because you are not sending the data along with the #Url.Action
Main View:
//index.cshtml
#model AF.Web.ViewModels.ObservationManagementVM
....
<div id="testsim">
#Html.Action("indexPagedSummaries", new { data = Model.ObservationSessions })
</div>
<input id="new-view" value="Sessions" type="button" />
<script>
$("#new-view").click(function() {
$.ajax({
type: "GET",
data: { data: "#Model.FeedBackSessions" },
url: '#Url.Action("indexPagedSummaries", "[Controller Name]", new { data = Model.ObservationSessions})',
cache: false,
async: true,
success: function (result) {
console.log(result);
$('#testsim').html(result);
$('#testsim').show();
}
});
});
</script>
If that doesn't help I have had issues when I have had a content-type mismatch or a datatype mismatch. You may need to add those to you ajax request.

Change your ajax data line to this:
data: { data: JSON.stringify(#Model.FeedBackSessions) },
You may also need to add these lines to the ajax:
dataType: 'json',
contentType: 'application/json; charset=utf-8',
You can see in one of your comments above that the current URL is being formed with a description of the List Object, rather than the contents of it:
http://localhost:60985/Observation/indexPagedSummaries?data=System.Collections.Generic.List%601%5BAF.Services.Observations.ObservationSessionModel%5D&data=System.Collections.Generic.List%601%5BAF.Services.Observations.ObservationSessionModel%5D&_=1482453264080
I'm not sure if there's a better way, but you may even have to manually get the model data into Javascript before posting it.
eg:
<script>
var temp = [];
#foreach (var item in Model.FeedBackSessions){
#:temp.push(#item);
}
</script>
and then data: { data: JSON.stringify(temp) },

Related

MVC: 404 not found in ajax

I am showing a number of flights in a view. I have created a button for every flight. On clicking this button I am getting the details of a single flight shown in the view.
here is my view code:
foreach (var item in Model)
{
<div class="toFrom">
<h3 id="FCity_#item.FlightID">#item.FromCity </h3>
<span><i class="fa mx-4 fa-plane"></i></span>
<h3 id="TCity_#item.FlightID">#item.ToCity</h3>
</div>
<div class="info d-flex">
<p class="me-2 " id="DDate_#item.FlightID">#item.DepartureDate.ToShortDateString()</p>
<p class="me-2" id="DTime_#item.FlightID">#item.DepartureTime.ToShortTimeString()</p>
<p class="me-2 " id="ATime_#item.FlightID">#item.ArrivalTime.ToShortTimeString()</p>
<select id="CFare_#item.Fare" class="form-control me-2">
#foreach (var re in ddlcabin)
{
<option value="#re.Fare">#re.CabinName (#re.Fare)</option>
}
</select>
<button class="form-control btn btn-primary" onclick="Save(#item.FlightID,#item.Fare)">select </button>
</div>
}
Now I want to get these values using and pass them to an action method without using a form in the view.
here is my js code:
function Save(id, fare) {
var fct = $("#FCity_" + id).text();
var tct = $("#TCity_" + id).text();
var ddt = $("#DDate_" + id).text();
var dt = $("#DTime_" + id).text();
var at = $("#ATime_" + id).text();
var cf = $("#CFare_" + fare).val();
$.ajax({
method: 'GET',
url: 'Flights/ReserveFlight',
data: { FromCity: fct, ToCity: tct, DepDate: ddt, DepTime: dt, ArrTime: at, CabinFare: cf },
success: function (data) {
console.log("data is inserted")
},
error: function (err) {
console.log(err)
}
});
}
when I click the save button it shows an error in the browser console and doesn't hit the debugger applied to the action method
here is my action method:
public ActionResult ReserveFlight(string FromCity, string ToCity, DateTime DepDate, DateTime DepTime, DateTime ArrTime, int CabinFare)
{
return View();
}
here is the error:
GET
http://localhost:64480/Flights/Flights/ReserveFlight?FromCity=Islamabd%20&ToCity=Karachi&DepDate=5%2F20%2F2022&DepTime=8%3A30%20AM&ArrTime=12%3A00%20AM&CabinFare=4500 404 (Not Found)
Modify the URL in ajax as:
$.ajax({
method: 'GET',
url: '/Flights/ReserveFlight',
data: { FromCity: fct, ToCity: tct, DepDate: ddt, DepTime: dt, ArrTime: at, CabinFare: cf },
success: function (data) {
console.log("data is inserted")
},
error: function (err) {
console.log(err)
}
});
Or work with UrlHelper.
$.ajax({
method: 'GET',
url: '#Url.Action("Flights", "ReserveFlight")',
data: { FromCity: fct, ToCity: tct, DepDate: ddt, DepTime: dt, ArrTime: at, CabinFare: cf },
success: function (data) {
console.log("data is inserted")
},
error: function (err) {
console.log(err)
}
});
Reference: Action(String, String) | UriHelper.Action() Method

Call Action Method in controller on Ajax success function to Render partial view

I am trying to call controller action method to render partial view to update the part of big web page. I am trying to do this on Ajax success function.
Code Control Flow:
Jquery Ajax calls a web api to add something to database, on the success function of the Ajax call, I am calling controller action method that returns partial view.
Jquery Script
$(document).ready(function () {
$("#sendMessage").on("click", function (e) {
e.preventDefault();
var MessageReplyParam = $('#messageToBeSent').val();
var FromUserNameParam = $('#FromUserName').val();
var FromUserIDParam = $('#FromUserID').val();
var ToUserNameParam = $('#ToUserName').val();
var ToUserIDParam = $('#ToUserID').val();
var button = $(this);
$.ajax({
//url: "/api/messages/SendMessages?MessageID=" + button.attr("data-message-id"),
url: "/api/messages/SendMessages",
method: "POST",
data: {
lngMessageID: button.data("message-id"),
Reply: MessageReplyParam,
FromUserID: FromUserIDParam,
FromUserName: FromUserNameParam,
ToUserID: ToUserIDParam,
ToUserName: ToUserNameParam
},
dataType: 'html',
success: function (data) {
$.ajax({
url: "/Booking/SendMessagesTest",
method: "POST",
data:
{
MessageID:2
}
});
}
});
});
});
Controller method to update Partial View
public ActionResult SendMessagesTest(int? MessageID)
{
var messagesReplies = from mrp in _context.MessageReply
where mrp.lngMessageID == MessageID
select mrp;
List<MessageReply> MessageReplies = new List<MessageReply>();
MessageReplies = messagesReplies.ToList();
BookingViewModel bvm = new BookingViewModel();
bvm.MessageReplies = MessageReplies;
return PartialView("_MessagesView", bvm);
}
_MessagesView.cshtml
#model DatabaseMVCPractice.ViewModels.BookingViewModel
#if (Model.MessageReplies != null)
{
foreach (var msg in Model.MessageReplies)
{
<p class="chatMessage">#msg.FromUserName: #msg.Reply</p>
}
}
Main View that has other html and also render partial view of _MessageView
<div id="partial">
<div class="messages">
<div class="bg-dark rounded padding-x4">
#{
Html.RenderPartial("_MessagesView", Model);
}
</div>
<p>#Html.DisplayFor(model => model.Messages.Message)</p>
</div>
</div>
When I debug the code, control flow works properly, at last, it goes to _MessageView but it never goes to MainView to render the partial view on Ajax success function. What am I doing wrong?
you are returning partial view return PartialView("_MessagesView", bvm); from ajax, partial view is returning only that part contains in it not main view, if your requirement is render partial view from ajax then you can get partial view response in your ajax success and replace your main view div with partial response.
your controllers action SendMessagesTest(int? MessageID) return partial view string in your ajax response.
like below is your Main View
<div id="partial">
<div class="messages">
<div id="divMessages" class="bg-dark rounded padding-x4">
#{
Html.RenderPartial("_MessagesView", Model);
}
</div>
<p>#Html.DisplayFor(model => model.Messages.Message)</p>
</div>
</div>
and your ajax only for your return partial view is like
$(document).ready(function () {
$("#sendMessage").on("click", function (e) {
e.preventDefault();
var MessageReplyParam = $('#messageToBeSent').val();
var FromUserNameParam = $('#FromUserName').val();
var FromUserIDParam = $('#FromUserID').val();
var ToUserNameParam = $('#ToUserName').val();
var ToUserIDParam = $('#ToUserID').val();
var button = $(this);
$.ajax({
//url: "/api/messages/SendMessages?MessageID=" + button.attr("data-message-id"),
url: "/api/messages/SendMessages",
method: "POST",
data: {
lngMessageID: button.data("message-id"),
Reply: MessageReplyParam,
FromUserID: FromUserIDParam,
FromUserName: FromUserNameParam,
ToUserID: ToUserIDParam,
ToUserName: ToUserNameParam
},
dataType: 'html',
success: function (data) {
$.ajax({
url: "/Booking/SendMessagesTest",
method: "POST",
data:
{
MessageID: 2
},
success: function (response) {
$("#divMessages").html("");
$("#divMessages").html(response);
}
});
}
});
});
});
i hope it should helps you let me know if require more information.

How to show Result after selecting dropdown

I want to show Course Code after selecting a department from drop down.
it searches from database and get but does not show at browser. Here is the drop down:
<select name="Id" id="Id">
<option value="">Select Department</option>
#foreach (var departments in ViewBag.ShowDepartments)
{
<option value="#departments.Id">#departments.Name</option>
}
</select>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script>
$(document).ready(function() {
$("#Id").change(function() {
var departmentId = $("#Id").val();
var json = { departmentId: departmentId };
$.ajax({
type: "POST",
url: '#Url.Action("ViewAllScheduleByDept", "ClassSchedule")',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(json),
success: function (data) {
//$("#myTable").append('<tr><th>ID</th><th>Name</th></tr>');
$('#Code').val(data.Code);
//$('#ContactNo').val(data.ContactNo);
//$('#Type').val(data.Type);
}
});
});
});
</script>
I am using mvc.
Your code should work fine as long as ViewAllScheduleByDept action method returns a json structure with a Code property.
[HttpPost]
public ActionResult ViewAllScheduleByDept(int departmentId)
{
//values hardcoded for demo. you may replace it value from db table(s)
return Json( new { Code="HardcodedValue", ContactNo="12345"} );
}
and you have an input form element with Id property value as Code in your page
<input type="text" id="Code" />
and you do not have any other script errors which is preventing your js code to execute.
Also, since you are sending just the Id value, you don't really need to use JSON.stringify method and no need to specify contentType property value.
$("#Id").change(function () {
$.ajax({
type: "POST",
url: '#Url.Action("ViewAllScheduleByDept", "ClassSchedule")',
data: { departmentId: $("#Id").val() },
success: function (data) {
alert(data.Code);
$('#Code').val(data.Code);
}
,error:function(a, b, c) {
alert("Error" + c);
}
});
});
use last before append
$("#myTable").last().append("<tr><td>ID</td></tr><tr><td>Name</td></tr>");
please see the link for details
Add table row in jQuery

Update Panel in ASP.NET MVC 3

I'm looking for a way to do a "Update Panel" in ASP.NET MVC 3. I found this link: How to make update panel in ASP.NET MVC but didn't work.
So, i did this in my view:
<div>
<input type="text" id="userName" />
<button type="button" onclick="searchUserByName()">Search</button>
</div>
<div id="usersPanel">
#{Html.RenderPartial("_UserList", Model);}
</div>
<script type="text/javascript">
function searchUserByName() {
var userName = $("#userName").val();
$.post('#Url.Action("SearchUserByName")',
{username: userName},
function (htmlPartialView) {
$("#usersPanel").html(htmlPartialView);
}
);
}
</script>
And in my controller:
public ActionResult SearchUserByName(string userName)
{
List<User> users = // code to search users by name
return PartialView("_UserList", users);
}
But i don't know if is a good (or right) way to do that, or if there is a way to do this with asp.net mvc 3. There is a better way to do this, or with asp.net mvc 3?
Just use ajax request to get the results from your action methods. It basically does the same thing as update panels in asp.net.
So something like the following.
$.ajax({
async: false,
cache: false,
type: 'POST',
url: /controller/action,
data: { id: idParam },
beforeSend: function (XMLHttpRequest) {
if (confirmMessage !== undefined) {
return confirm(confirmMessage);
}
return true;
},
success: function (data) {
// do stuff
},
error: function () {
alert('An error occured');
}
});
I would do it like that.
You might also want to take a look at client side libraries for handling bindings etc. Looks like knockoutjs will be included in MVC4
In View:
<script type="text/javascript">
var userName = $("#userName").val();
$.ajax({
url: "/<ControolerName>/SearchUserByName",
type: "POST",
data: { userName: userName},
success: function (result) {
$('#divResults').html(result);
},
error: function (ex) {
alert("Error");
}
<script>
<div id="divResults">
</div>
In controller:
public PartialViewResult SearchUserByName(string userName)
{
List<User> users = // code to search users by name
return PartialView("_users", users);
}

Passing parameters when submitting a form via jQuery in ASP.NET MVC

I'm trying to do a form submit to my controller through jQuery Ajax. The following code works for the most part, however, the ThreadId parameter does not get passed. If I call the controller directly without using jQuery, it gets passed, but when using jquery, I don't see the ThreadId after form.serialize(). WHat would be the easiest way to pass parameters (like ThreadId) to jQuery form post?
ASPX
<% Html.BeginForm("AddComment", "Home", new { ThreadId = Model.Id },
FormMethod.Post, new { #id = "AddComment" + Model.Id.ToString(),
#onsubmit = "javascript:AddComment(this);return false" }); %>
<%: Html.TextBox("CommentText", "", new { #class = "comment-textbox" })%>
<input id="Comment" type="submit" name="submitButton" value="Post Comment" />
<% Html.EndForm(); %>
JavaScript
AddComment = function (sender) {
var form = $(sender);
var data = form.serialize();
$.ajax({
type: "POST",
url: "/Home/AddComment",
data: data,
dataType: "html",
success: function (response) {
alert(response);
},
error: function (error) {
alert(error);
}
});
return false;
};
CONTROLLER
[HttpPost]
public ActionResult AddComment(string submitButton, Comment comment)
{
comment.CreatedDate = DateTime.Now;
comment.PosterId = LoggedInUser.Id;
_repository.AddComment(comment);
_repository.Save();
if (Request.IsAjaxRequest())
{
return View("Comment", comment);
}
else
return RedirectToAction("Index");
}
The ThreadId parameter is included in the action attribute of the form. When you are ajaxifying this form you are posting to /Home/AddComment and no longer supplying this parameter. You could do the following to ajaxify it:
$('#idofyourform').submit(function() {
$.ajax({
// use the method as defined in the <form method="POST" ...
type: this.method,
// use the action as defined in <form action="/Home/AddComment?ThreadId=123"
url: this.action,
data: $(this).serialize(),
dataType: 'html',
success: function (response) {
alert(response);
},
error: function (error) {
alert(error);
}
});
return false;
});
Another possibility is to include the ThreadId parameter inside the form as hidden field instead if putting it in the action attribute.

Categories