Beeing new to Ajax i need help with how to add the querystring and invoke the Index action without a postback. Now the link looks like this:
#sectionGroup.Term, #sectionGroup.Count
My guess is using Ajax.ActionLink but how do i create the querystring?
Everything that you add to the routeValues and doesn't match a route segment will be added to the querystring.
Using your example, it would look something like this with Ajax.ActionLink:
#Ajax.ActionLink(
sectionGroup.Term + ", " + sectionGroup.Count,
"Index",
new { section = sectionGroup.Term },
new AjaxOptions { UpdateTargetId = "id-of-container" }
)
In your Index action you need to return a partial view when it is requested with ajax. This will remove the layout (master page) from the response.
if (Request.IsAjaxRequest())
return PartialView(model);
return View(model);
Remember to add a reference to the jquery.unobtrusive-ajax.js file.
Related
I have the following scenario:
- Area A -> PartialView A -> It is using Ajax.BeginForm calling action "Save" on Controller A
- Area B -> View B
I inserted "PartialView A" into "View B" but the Ajax.BeginForm form action is calling Controller B action instead of Controller A.
PartialView A:
#using (Ajax.BeginForm(null, null, new AjaxOptions<br>
{
Url = Url.Action("Save", "ControllerA", null, Request.Url.Scheme),
HttpMethod = "Post",
}
Controller A action:
[HttpPost]
public ActionResult Save(Model model)
{
}
My goal is to reuse/insert the partial view into other views without having to add any other action to the view's controller. How to solve this scenario? Thank you very much for any help.
why not just simply use the Ajax.BeginForm params?
#using (Ajax.BeginForm("Save", "ControllerA", null, new AjaxOptions(){
HttpMethod = "POST"
}, new { id = "someRandomForm" }))
{
<div>
<!-- your html code -->
</div>
}
add null after controller parameter and before the new AjaxOptions() parameter to somehow make us hit the controller we wanted, which is ControllerA
I couldn't make the Ajax.BeginForm to work as I want so my workaround was to use JQuery ajax call using the specific controller/action I need to invoke.
can you try this
#using (Ajax.BeginForm("Save", "ControllerA", new AjaxOptions() { HttpMethod = "POST" }))
In an .ASPX View (not Razor) ...Is it possible... or... How can I modify the action on
Html.BeginForm("**ACTION**", "controllername", FormMethod.Post, new { id = "formId" }))
of a view from an ActionResult of a Controller just before calling the view?
You can use following code for the dynamically assign action name.
#{
String actionName = /*Assign action name based on the applying condition or using ViewBag you can also get it from controller.*/;
}
#using (Html.BeginForm(actionName, "Basic"))
{
}
I have a Controller listed below:
//
// GET: /Customer/Details/5
public ActionResult Details(short id)
{
ActionResult actionResult = null;
if (HttpContext.User.IsInRole("Admin"))
{
// this is the logic that is getting executed
YeagerTechWcfService.Customer cust = db.GetCustomerID(Convert.ToInt16(id));
actionResult = View("Details", cust); }
else
{
HttpCookie cn = Request.Cookies["strCookieName"];
if (cn != null)
{
YeagerTechWcfService.Customer cust = db.GetCustomerID(Convert.ToInt16(id));
actionResult = View("Details", cust);
}
else
{
TempData["ErrCode"] = "CustView";
actionResult = RedirectToAction("Index", "Home");
}
}
return actionResult;
}
I have a View (where the ActionLink is) like below:
columns.Template(
#<text>
#Ajax.ActionLink("Detail", "Details", "Customer", new { id = item.CustomerID },
new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "detailCustomer" })
</text>
).Width(70);
The rendered output is now as follows:
<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#detailCustomer" href="/Customer/Details/2">Detail</a>
If I click on the link from within the source view of the browser, I get to my new View just fine.
However, if I try and click on the ActionLink, the View doesn't come up. I can verify during debugging, that I'm stepping thru the Details View after I hit that controller code. The present view just stays in place without switching to the new View.
Moreover, I can see that if I click on the ActionLink, it executes the same exact code (during debugging) as when I paste it into the address bar:
http://localhost:4514/Customer/Details/2
When I click on the ActionLink, even though the same code is executed, the address url doesn't change to the above. and the View is not being rendered.
What am I doing wrong?
even though the same code is executed, the address url doesn't change
to the above
You are using an Ajax.ActionLink meaning that it will send an AJAX request. The whole point of AJAX is to stay on the same page and not redirect.
You indicate UpdateTargetId = "detailCustomer" so make sure that in your page you have a container with this id:
<div id="detailCustomer"></div>
which will be updated with the results of the AJAX call. Also make sure that you have properly included the jquery.unobtrusive-ajax.js script to your page in order for the Ajax.ActionLink helper to do anything useful.
On the other hand if you want to perform a full postback and change the url of your browser you probably need a standard link:
Html.ActionLink("Detail", "Details", "Customer", new { id = item.CustomerID }, null)
How do I actually get the JSON from a controller method using Ajax.ActionLink? I tried searching the website, but the closest thing I got was ASP.NET MVC controller actions that return JSON or partial html
And the "best answer" doesn't actually tell you how to get JSON from the SomeActionMethod in the ajax.actionlink.
Personally I don't like the Ajax.* helpers. In ASP.NET MVC < 3 they pollute my HTML with javascript and in ASP.NET MVC 3 they pollute my HTML with HTML 5 data-* attributes which are totally redundant (such as the url of an anchor). Also they don't automatically parse the JSON objects in the success callbacks which is what your question is about.
I use normal Html.* helpers, like this:
#Html.ActionLink(
"click me", // linkText
"SomeAction", // action
"SomeController", // controller
null, // routeValues
new { id = "mylink" } // htmlAttributes
)
which obviously generate normal HTML:
click me
and which I unobtrusively AJAXify in separate javascript files:
$(function() {
$('#mylink').click(function() {
$.post(this.href, function(json) {
// TODO: Do something with the JSON object
// returned the your controller action
alert(json.someProperty);
});
return false;
});
});
Assuming the following controller action:
[HttpPost]
public ActionResult SomeAction()
{
return Json(new { someProperty = "Hello World" });
}
UPDATE:
As requested in the comments section here's how to do it using the Ajax.* helpers (I repeat once again, that's just an illustration of how this could be achieved and absolutely not something I recommend, see my initial answer for my recommended solution):
#Ajax.ActionLink(
"click me",
"SomeAction",
"SomeController",
new AjaxOptions {
HttpMethod = "POST",
OnSuccess = "success"
}
)
and inside the success callback:
function success(data) {
var json = $.parseJSON(data.responseText);
alert(json.someProperty);
}
I have a very simple view that has a DropDownListFor and a Button inside an Ajax.BeginForm helper. Clicking the button renders the whole view again inside the div I have set to update including the layout page (I also notice a spike in the cpu when clicking the button multiple times)
Here is the Ajax.BeginForm inside the view:
#using (Ajax.BeginForm("About2", "Home", new AjaxOptions { UpdateTargetId = "property22" }))
{
<div>
<div id="property22">
#Html.DropDownListFor(m => m.SomePropertyToBind, new SelectList(Model.list, "property1", "property2"))
</div>
<button type="submit" id="test">
Click me</button>
</div>
}
Any ideas where I'm going wrong?
I uploaded the whole project if someone has a couple of minutes to take a look at it:
http://www.sendspace.com/file/siu3r31 (free provider so there may be a popup)
Thanks
You are using a wrong overload of the Ajax.BeginForm helper. It should be like this:
#using (Ajax.BeginForm(
"About2",
"Home",
null,
new AjaxOptions { UpdateTargetId = "property22" },
new { #id = "refreshe" }
))
Notice the additional null value I am passing as the routeValues parameter. Also in the example you uploaded you forgot to include the TestView.cshtml view. This being said in order to fix the problem you have two possibilities:
Either return a partial view:
public ActionResult About2()
{
Random randomizer = new Random();
int random = randomizer.Next(1, 1000000000);
ModelTest newModelTest = new ModelTest();
string[] stringList = new string[] { "Red", "Blue", "Green" };
newModelTest.list = from test in stringList
select new ModelTestList
{
property1 = test,
property2 = test
};
newModelTest.SomePropertyToBind = stringList[random % 2];
return PartialView("TestView", newModelTest);
}
or disable the layout in the TestView.cshtml view:
#{
Layout = null;
}
Unfortunately from your explanation above and from the code, I am not sure what you are trying to achieve. However, I think your most worry is about having Ajax working in your view.
In your About2 action method, you are trying to return a complete view which is TestView (in that case, it doesnt exist) and passing it the newModelTest view Model. I would advise changing to return either a PartialView or JsonResult.
For example, changing the return statement of About2 action method to
public ActionResult About2()
{
...
return Json(newModelTest);
}
or changing it to a return type to string and returning "TestResult"
public String About2()
{
...
return "TestResult";
}
or you could change the return statement to return a PartialView
Thanks for your replies.
I just realized that About2 should have returned the "About" view instead of the "TestView". I had tried creating a partial view with the Ajax.BeginForm code but I came across the same problem.
This is my first attempt at Ajax.BeginForm (so far I have always used jquery), and I was under the impression that it works in a similar fashion in the sense that by specifying the target id only the contents of that element will get updated, not that the target will actually get replaced by the whole response object.
Thanks for your help, not only did I get it to work, but I now understand how it should work.
I suspect that what's happening is that you're returning the a complete View (including the layout template) in the Ajax response. Try changing your "Home" controller "About2" action temporarily to the following:
public ContentResult About2() {
return Content("Hello World");
}
I tested this sample Action with your Razor markup and clicking the button properly replaced your dropdown list with "Hello World!".
If this is indeed what's happening, then you'll want to return a View from "About2" without the layout by declaring the following at the top of the View that you're returning.
#{
Layout = null;
}