Asp.net MVC Selected Index Changed / Ajax.ActionLink - asp.net

I have a page in Asp.Net MVC using the Razor syntax. In the page I have a DropDownList, and a DIV section that I would like to replace the content in the DIV depending on the selected value of the combobox using the Ajax.ActionLink functionality
Is there a way to do this?
Thanks
Mark

I would rather use a form than a link as it is more adapted to what you are trying to achieve:
#using (Ajax.BeginForm(
"Change",
"Home",
new AjaxOptions { UpdateTargetId = "result" }
))
{
#Html.FropDownListFor(x => x.Foo, Model.Foos, "-- Select a foo --")
<input type="submit" value="Change" />
}
<div id="result"></div>
And the corresponding controller action:
public ActionResult Change(string foo)
{
string view = ... // select the partial based on the selected value
return PartialView(view);
}

you can use jquery to call your ajax action
function OnDddlChanged() {
$.ajax({
url: "controller/action/"+$("#SelectTagID").val(),
dataType: 'html',
type: 'Get',
success: function (r) {
$('#DivID').html(r);
},
error: function () {
alert('Error');
}
});
}
mvc ajax action will like that
public MvcHtmlString MyAction(string id)
{
if(Request.IsAjaxRequest)
{
//return your html as MvcHtmlString
}
}

Related

ASP MVC - Html.Action [post] firing for every post request

I have a newsletter subscription form in a website I'm creating (it's part of the layout) and I'm using Html.Action() in my layout.cshtml file to call my Subscribe() action method. The method has 'two' versions: one for get and other for post requests.
Problem:
the Subscribe() POST action method gets called whenever any other form is submitted - I don't want that: it should only be called when someone clicks on the 'subscribe' button (then there's an ajax call to update the page without reloading)
For instance, in my contacts page, when I submit the form, the Subscribe() post method also gets called
I'm not sure why this happens but I believe it is because there's a post request and hence my Subscribe() POST method gets called automatically instead of the Subscribe() GET one.I tried using Html.Partial for this instead but it doesn't work because I have to pass a model to the partial view through the layout.cshtml file
_layout.cshtml:
// more code
#Html.Action("Subscribe", "Newsletter", new { area = "" })
// mode code
NewsletterController:
public ActionResult Subscribe() {
NewsletterSubscribeVM model = new NewsletterSubscribeVM();
return PartialView("NewsletterSubscription", model);
}
/// always gets called, even when it shouldn't
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Subscribe(NewsletterSubscribeVM subscriber) {
string message;
if (!ModelState.IsValid) {
message = "Ops! Something went wrong.";
return Json(message, JsonRequestBehavior.AllowGet);
}
Newsletter sub = new Newsletter { Email = subscriber.SubscriberEmail };
this._service.Add(sub);
message = "Thank you for subscribing!";
return Json(message, JsonRequestBehavior.AllowGet);
}
}
NewsletterSubscription.chtml
#model Web.ViewModels.NewsletterSubscribeVM
#using (Html.BeginForm("Subscribe", "Newsletter", new { area = "" }, FormMethod.Post, new { id = "newsletter-form", #class = "col-xs-12" })) {
#Html.AntiForgeryToken()
#Html.Label("Subcribe!", new { id = "newsletter-msg", #class = "col-xs-12 no-padding" })
#Html.TextBoxFor(m => m.SubscriberEmail, new { placeholder = "Email", #class = "col-xs-7", id = "newsletter-box" })
<button id="newsletter-btn" class="col-xs-1">
<i class="fa fa-arrow-right absolute-both-centered" aria-hidden="true"></i> </button>
}
Javascript:
$('#newsletter-btn').click(function (e) {
var form = $('#newsletter-form');
e.preventDefault();
// if the user has inserted at least one character and the 'thank you' msg isn't showing yet:
if ($('#newsletter-box').val().length != 0 && $('#subscription-status-msg').length == 0) {
$.ajax({
method: "POST",
url: "/newsletter/subscribe",
data: form.serialize(),
dataType: "json",
success: function(data) {
$('<div id="subscription-status-msg" class="col-xs-12 no-padding">' + data + '</div>').appendTo($("#newsletter-form")).hide().fadeIn(500);
}
})
}
})
Thanks in advance!

Change UpdateTargetId of Ajax.BeginForm() dynamically based on form submission result

I'd appreciate if someone could help.
I want to return different partial views based on user type:
[HttpPost]
public ActionResult Edit(ContractModel model)
{
if(ModelState.IsValid)
{
if (curUser.IsInputer) { .... return View("Contracts");}
else if(curUser.IsAuthorizer) { ..... return View("Details");}
}
return PartialView(model);
}
View:
#{
string updateRegion = "";
if (curUser.IsInputer)
{
updateRegion = "content";
}
else if (curUser.IsAuthorizer)
{
updateRegion = "mainPane";
}
}
<script>
function returnViewOnFailure(result) { //not firing on submission failure
$("#mainPane").html(result);
}
</script>
#using (Ajax.BeginForm("Edit", new AjaxOptions() { UpdateTargetId = updateRegion,
InsertionMode = InsertionMode.Replace,
OnFailure = "returnViewOnFailure" }))
{.........}
The problem is when ModetState.IsValid= false my function returnViewOnFailure is not firing.
I would like UpdateTargetId be "mainPane" if form submission fails (regardless of user type), otherwise it should depend on curUser.
EDIT:
So, as advised I'm using ajax call to sumbit the form:
<script>
var form = $('#contract_form');
form.submit(function (ev) {
$.ajax({
cache: false,
async: true,
type: "POST",
url: form.attr('action'),
data: form.serialize(),
success: function (data) {
$("#content").html(data);
//How to check ModelState.IsValid and show errors?
}
});
ev.preventDefault();
});
Because the validation is done serverside you can set the statuscode of the response (Controller.Response).
If the validation does not succeed set it to 500 (internal server error) so the ajax.onfailure gets called. Put the validationerror logic (replacing divs content) in there. Or maybee you can even change the updatetargetid in the onfailure (by javascript).

Ajax success when a view is returned

I'm struggling to return a view or partial view with Ajax. Whenever I change the return type to something that isn't JSon the ajax command never succeeds. I need to return a partial view because I want to return a lot of data back.
This is my current code:
(Controller)
[HttpPost]
public ActionResult AjaxTestController(string Input)
{
string Results = Input + " -- TestTestTest";
return PartialView("Test", Results);
//return new JsonResult() { };
}
(View)
function AjaxTest() {
alert("test");
$.ajax({
type: "POST",
url: "Home/AjaxTestController",
data: "Input=Test11111",
success: function () {
alert("Success!");
}
});
Thanks!
You can use the $.post command for that:
function AjaxTest() {
alert("test");
$.post({
url: "Home/AjaxTestController",
data: "Input=Test11111",
success: function (response) {
alert(response);
}
});
try the following:
$(function () {
$('#submit').live('click', function () {
AjaxTest();
});
});
function AjaxTest() {
$.ajax({
type: "POST",
url: '#Url.Action("AjaxTestController", "Home")',
data: { Input: "Test - " + new Date() },
success: function (data) {
$('#partialResult').html(data);
},
error: function (xhr, err) {
alert(xhr.responseText);
}
});
};
inside your view and ensure that you have your target div set up for the partial to be populated into:
<div id="partialResult"></div>
also, for the example above, I added a button to the view to initiate the ajax (purely for testing):
<input type="button" value="Submit" id="submit" />
your 'partialview' should look something like this:
#model string
<h2>
Partial Test</h2>
<p>
#Model
</p>
no other changes are required to the existing action for this to now function as required.
[UPDATE] - I changed the AjaxTest() method to include the error event (the result of which is captured in an alert). hopefully, this may help further.
partial View is different than view you have to specify the whole path to the partial view or have it in share folder. otherwise is going to return not found and never success. any way this always work for me, try
partialView("~/Views/ControllerView/Test.cshtml")

asp.net mvc ajax.beginform onsuccess event

Is it possible to do something like this using asp.net mvc 3
#using(Ajax.BeginForm("SomeAction","MyController",new AjaxOptions {OnSuccess="function(content){ alert(content); }"}))
{
#Html.Partial("Recorder")
<input type="submit" />
}
I am using Jquery for ajax operations and not MSAjax.
Thanks
You can just use a normal Html.BeginForm, assign a id to the form, and use the jquery ajax to handle submission:
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "formData" }))
The submission function:
// Function to submit form data
function submitForm() {
var frm = $('#formData');
$.ajax({
url: '/Home/Create',
type: 'POST',
data: frm.serialize(),
beforeSend: function () {
},
onsuccess: function (){},
success: function (result) { },
error: function () { }
});
}
Hope this what you mean/need :)

Calling ASP.NET MVC Controller explicitly via AJAX

I know that I can use following piece of code to refresh a div:
<%=Ajax.ActionLink( "Update", "Administration", new AjaxOptions { UpdateTargetId = "grid", LoadingElementId = "grid-wait" } ) %>
But this creates a link; user will have to click on it to get the view refreshed.
How can I make it automatic, i.e., like say if I want the grid to be refreshed after every five seconds?
Try this:
<p id="CurrentDateTime"></p>
<script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.setInterval(updateDateTime, 5000);
function updateDateTime() {
$.get("GetCurrentDate?rnd=" + Math.random(1000), {}, function (r) {
$("#CurrentDateTime").html(r);
}, "text");
}
</script>
public ActionResult GetCurrentDate()
{
return Content(DateTime.Now.ToString("U"));
}

Resources