Load/Refresh only part of a page (View) using AJAX in ASP.NET MVC - ajax

I am trying to achieve the same result as mentioned by the OP in this post However when I try to render partial view by checking if it was an AJAX request in my Index action, its evaluating to false.
My Index View:
#using (Ajax.BeginForm("Index", "Home",
new AjaxOptions()
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "restaurantList"
}))
{
<input type="search" name="searchTerm" />
<input type="submit" value="Search By Name" />
}
#Html.Partial("_Restaurant",Model)
My Partial View:
<div id="restaurantList" style="border:2px dotted red; padding-left:2em; margin-top:4px;">
#foreach (var item in Model)
{
<div>
<h4>#item.Name</h4>
<div>#item.City, #item.Country</div>
<div>#item.CountOfReviews</div>
<hr />
</div>
}
</div>
My Index Action:
public ActionResult Index(string searchTerm = null)
{
var model = ...//Building model object here
if (Request.IsAjaxRequest())
{
return PartialView("_Restaurant", model);
}
return View(model);
I would prefer not to dive into use of any jQuery or javascript as I am in the process of learning ASP.NET MVC, and would want to know why the approach I took is not working? The second answer by Dennis, in the post that I referenced also suggested similar approach.
Could someone kindly tell me what I am doing wrong?
Thanks

This is just an example how you can load view from AJAX without page refresh, it may help you.
It send text value to controller by ajax call and load that value in other view which replace main view, if you don't want to replace main view then you can take other div instead same div to load content.
Controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
public PartialViewResult TestAjax(string Name)
{
ViewBag.Name = Name;
return PartialView();
}
Index.cshtml:
<input type="button" id="btnSearch" class="btn btn-warning" style="height:35px;width:120px" value="Search"/>
<label>Name:</label><input type="text" id="txtName" name="txtName" />
<script>
$('#btnSearch').click(function () {
$.ajax({
url: '#Url.Action("TestAjax", "Home")',
data: { Name: $("#txtName").val() },
type: 'POST',
success: function (data) {
$("#divContent").html(data);
}
});
});
</script>
TestAjax.cshtml:
#ViewBag.Name

As #StephenMuecke pointed out in his comments, the libraries not being loaded correctly was the problem. While creating a new bundle of all libraries and adding it in the BundkeConfig.cs I had missed ~/Scripts/jquery.unobtrusive-ajax.js*. Got it working now.

Related

ASP.NET MVC ViewBag values not being displayed in view after Ajax call

I have following view and controller code:
Index.cshtml
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<span style="color:green; font-weight:bold;" id="Message">#ViewBag.Message</span>
<input type="text" id="txtMessage" />
<input type="submit" id="btnSubmit" value="Submit" />
}
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$('#btnSubmit').click(function (event) {
$.ajax({
type: "POST",
url: "/Home/Create",
dataType: "json",
contentType: "application/json; charset=utf-8",
async: false,
data: JSON.stringify({
'message': $('#txtMessage').val()
})
});
});
</script>
Controller code:
public class HomeController : Controller
{
public ActionResult Index(string message)
{
return View();
}
[HttpPost]
public ActionResult Create(string message)
{
ViewBag.Message = message;
return View("Index");
}
}
After clicking the button and making ajax call I'm not able to see the message set in the Create method to ViewBag.Message inside the index view.
If you are using Begin form and button type as submit then why write ajax method?
Remove your btnSubmit click from javascript code and use textbox as TextBoxFor,
#Html.TextBoxFor(m => m.message, new { #class = "form-control" })
it should work.
Update Answer for without strongly type
As per code, you are using Begin Form so not required to ajax call.
So first remove javascript code or if you keep that code so no meaning of that.
Now need to update the following line:
<input type="text" id="txtMessage" **name = "txtMessage"** />
And in the controller code post method the following name should be the same.
[HttpPost]
public ActionResult Create(**string txtMessage**)
{
ViewBag.Message = **txtMessage**;
return View("Index");
}

ASP.net MVC 5 partial view Ajax POST not updating just the partial

I have a partial view that is not updating just the partial, it redirects to the action for the entire page.
In the partial view, _registerAccount.cshtml, that contains a post request to register, the request is made via Ajax in a view named _registerAccount as so:
#model LoginDemo.Models.LdapAccountModel
#using (Ajax.BeginForm("RegisterLdapAccount", "Account", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace
}))
{
#Html.ValidationSummary()
#Html.LabelFor(x => Model.Email) #Html.TextBoxFor(x => Model.Email, new { id = "reg-ytu-email" })
<br />
#Html.LabelFor(x => Model.Password) #Html.PasswordFor(x => Model.Password, new { id = "reg-pw" })
<input type="submit" value="Register" class="btn" />
}
In the parent page, Register.cshtml I have:
#model LoginDemo.Models.RegisterModel
...
<div class="panel hide register-type register-ytu">
#Html.Partial("_registerAccount")
</div>
In the Account Controller the ajax request goes to the RegisterAccount action:
[HttpPost]
public async Task<ActionResult> RegisterLdapAccount(LdapAccountModel model)
{
if (model.exists()) // pseudo code
{
return Json(new {foo: "bar"}); // return address to redirect to
}
else
{
ModelState.AddModelError("", "You must have a valid account.");
return PartialView(model); // return error
}
}
The problem I have is that whatever gets returned wipes out the entire page as opposed to updating just the partial within the parent page. That is, if successful the JSON return only returns the JSON, if failed the partial view return only returns the partial.
n.b. I have <add key="UnobtrusiveJavaScriptEnabled" value="true" /> in my web.config.
Amend the following code as follows:
#using (Ajax.BeginForm("RegisterLdapAccount", "Account", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "updatearea",
Amend the div to add the id:
<div id="updatearea" class="panel hide register-type register-ytu">
#Html.Partial("_registerAccount")
</div>
Now make sure you have unobtrustive ajax as a script on the page if you don't already.
<script type="text/javascript" src="#Url.Content("/scripts/jquery.unobtrusive-ajax.min.js")"></script>
To add this script it must be in the scripts folder for your project.
Amend the controller so that you are loading the correct partial view, if you don't state the name of the partial view the partial view loaded will be whatever matches the name of the action, if no partial view matches the name of the action no partial view will be loaded. So explicitly state which partial view you want to load like this:
return PartialView("_RegisterAccount", model)

Ajax.BeginForm does not insert partial view

Running ASP.NET MVC 2015 with C#.
Trying to add a partial view as a result of #using (Ajax.BeginForm(...)
All it does is to open a new page with my partial view in it. I found some answers in stackoverflow, but none works for me, unless I missed something.
Scenario:
index page here
Type A, B or C and partial view is expected below the current page
new page unexpected here
But it does open a new page instead
Controler:
public class TestController : Controller
{
public ActionResult Index()
{
return View();
}
[ChildActionOnly]
public ActionResult TestPartial()
{
ChoiceViewModel vm = new ChoiceViewModel();
return View(vm);
}
[HttpPost]
public ActionResult SelectChoice(ChoiceViewModel vm)
{
ModelState.Clear();
if (vm.MyChoice == "A")
return PartialView("APartial");
if (vm.MyChoice == "B")
return PartialView("BPartial");
if (vm.MyChoice == "C")
return PartialView("CPartial");
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
Index.cshtml:
<h2>Index</h2>
<div>
#Html.Partial("TestPartial")
</div>
<br/>
<div id="GoesHere">
</div>
TestPartial.cshtml:
#model TestPartial.ViewModels.ChoiceViewModel
#using (Ajax.BeginForm("SelectChoice", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "GoesHere", InsertionMode = InsertionMode.Replace }))
{
<div class="form-group">
<p>Give your choice please: A,B or C</p>
#Html.TextBoxFor(x => x.MyChoice, new { #class = "form-control" })
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Select">
</div>
}
APartial.cshtml (as well as B and C...)
<p>This is A choice</p>
Notes:
Yes, web.config has UnobtrusiveJavaScriptEnabled=true and ClientValidationEnabled=true
Yes, I installed the jquery.unobtrusive-ajax package
Can you tell me what I missed or did wrong ?
Thanks
The answer was that I was missing the unobtrusive-ajax inclusion line in my cshtml :
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

Passing hidden value to controller (asp.netmvc)

Trying to pass a value with Ajax.Beginform but not working for some reason.
What I’m doing:
I’m making an ajax call which returns an id and replaces a hidden element.
Ajax: Ajax.BeginForm("Action1", "Controller1", new AjaxOptions { InsertionMode
= InsertionMode.Replace, UpdateTargetId = "pageId" })
Hidden Element (which is outside of the above Ajax.BeginForm):
<input type="hidden" name="pageId" id="pageId" value=""/>
Now, I want to use that pageId (in the hidden value) and pass it to another action, using another Ajax.BeginForm.
Ajax.BeginForm("Action2", "Controller1”))
{
<input type="hidden" name="pageId" id="pageId" value=""/>
<input type="submit" />
}
The controller Action2 looks like this:
public void Action2(string pageId)
{
}
But this is not working obviously. What are your suggestions?
I think that i understand your problem what you are facing. Please correct me if i am wrong.
First Ajax call which will set your pageid
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
#using (Ajax.BeginForm("Foo", "FooController", new AjaxOptions {
HttpMethod = "Post",
OnSuccess = "success"
}))
{
<input type="submit" value="Save" id="btnsubmit" />
}
[HttpPost] // you said you return a string here
public string Foo()
{
return "1";
}
<script type="text/javascript">
function success(result) {
$('#pageId').val(result);
}
</script>
secondly here is the place where your pageid will be set. when you will press the submit button below the set value will be posted to the controller.
#using (Ajax.BeginForm("Foo1", "FooController", new AjaxOptions { OnSuccess = "HandlePostback" }))
{
<input type="hidden" name="pageId" id="pageId" />
<input type="submit" value="Save" id="btnsubmit" />
}
[HttpPost]
public ActionResult Foo1(int pageId)
{
return View();
}

Ajax.Beginform refreshing whole page

It redirects to whole new page instead of just updating the current one, I have unobtrusive scripts and web.config stuff. Why is this not working?
<div id="preview-image-placeholder"></div>
#foreach (var item in Model)
{
using (Ajax.BeginForm("PreviewImage/" + #item.Id.ToString(), "Music", null, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, UpdateTargetId = "preview-image-placeholder" },
new { #enctype = "multipart/form-data", #item.Id }))
{
#Html.AntiForgeryToken()
<input type="file" class="upload-image" id="upload-image-file_#item.Id" name="file" accept="image/*">
<button class="btn btn-default" id="btn-preview_#item.Id" style="display: none" type="submit"></button>
}
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
Controller:
[ValidateAntiForgeryToken]
[HttpPost]
public PartialViewResult PreviewImage(HttpPostedFileBase file, int id)
{
//Do other code stuff
return PartialView("_DisplayImage", song);
}
_DisplayImage partial view:
#model IEnumerable<MusicSite.Models.UploadedSong>
#using MusicSite.CustomHtmlHelpers;
#foreach(var item in Model)
{
if (#item.CoverImageBytes != null)
{
#Html.ImageFor(x => item.CoverImageBytes, #item.SongName + " Image", new { #id = "preview-image" })
}
}
Besides unobtrusive scripts you must add Microsoft Ajax libraries too (MicrosoftAjax.js and MicrosoftMvcAjax.js) so that Ajax.BeginForm works correctly.
Regards,

Resources