I have DropDownList and a submit button on my page. DropDownListhas list of data from the database, and while selecting value from the dropdown and then clicking on submit button, I am getting number of records of selected dropdown list value in partial view of the main view page. My code is giving proper output. I have bind View to controller through model. Using html.hiddenfor.
But whenever I click on submit button as usual my whole page gets refreshed. But I need to refresh only partial view rather than whole page.
This is my code which is working properly. But by this code my whole page is getting refreshed. And I want to prevent it. :
view:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ApricaCRMEvent.Models.CRM.DatabaseEntities.CRM_Doctor_Request>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
MDLNoDDLIndex
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
function TestFun() {
var mdlno = $("#ddlMDLNo").val();
var txtmdlno = document.getElementById("Request_For_Id");
txtmdlno.value = mdlno;
}
</script>
<div>
<h2>Search by MDLNo</h2>
<% using (Html.BeginForm())
{ %>
Select MDLno
<%= Html.DropDownList("ddlMDLNo", ViewData["MDLno"] as SelectList, "--Select One--", new { onchange = "TestFun()" })%>
<%: Html.HiddenFor(model => model.Request_For_Id) %>
<input type="submit" value="search" name="SearchMDLNo" id="btnclick" />
<% } %>
</div>
<div id="showtable"> //partial view
<% if (ViewBag.load == true)
{ %>
<%Html.RenderAction("MDLNoDataList"); %>
<% } %>
</div>
</asp:Content>
Controller:
// Search by mdl no
public ActionResult MDLNoDDLIndex()
{
ViewData["MDLno"] = new SelectList(CRMSearchReportDL.getAllMDLno(), "Request_For_Id", "Request_For_Id");
ViewBag.load = false;
return View();
}
[HttpPost]
public ActionResult MDLNoDDLIndex(CRM_Doctor_Request model)
{
ViewData["MDLno"] = new SelectList(CRMSearchReportDL.getAllMDLno(), "Request_For_Id", "Request_For_Id",model.Request_For_Id);
ViewBag.load = true;
return View();
}
public ActionResult MDLNoDataList()
{
List<CRM_Doctor_Request> drlist = new List<CRM_Doctor_Request>();
return PartialView(drlist);
}
[HttpPost]
public ActionResult MDLNoDataList(CRM_Doctor_Request model)
{
return PartialView(CRMSearchReportDL.getMDLNoWiseDetails(model.Request_For_Id));
}
You can use jQuery to do this for you. Capture the form submit in jQuery and instead of performing a full form post through the browser, submit your form data to a controller action using jQuery's .ajax() method.
Something like this:
$.ajax({
url: urlToControllerAction,
data: {
ddlMDLNo: ddlMDLNo,
Request_For_Id: Request_For_Id
},
type: 'POST',
success: function (results) {
var partialData = $(results);
$('#showtable').html(partialData);
},
error: function (xhr, ajaxOptions, thrownError) {
// do something
}
});
Related
Decided to learn ASP.NET MVC and instantly got stuck on something simple.
In Web Forms user controls allowed to separate application into components based on functionality and facilitated reuse. It seems partial views are supposed to do something similar in ASP.NET MVC, but either I am getting this wrong, or each visible page is handled by single controller and it is not possible to delegate certain page portions to separate controllers without hard-coding these controller relationships.
RenderAction can render a partial view and insert resulting HTML in the page, but if we want this view to be refreshed when the user clicks on some link within this view together with the entire page, we need all the partial view links to refer to the parent controller?
For example:
Home\Index.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">Home</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
...
<% Html.RenderAction("Index", "Posts"); %>
...
Posts\Index.aspx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BlogEngine.Models.PostsViewModel>" %>
<% foreach(var item in Model.Posts){ %>
<p class="postMeta"><%: string.Format("{0} {1}", item.CreatedAt, item.CreatedBy) %></p>
<h1><%: item.Title %></h1>
<div><%: item.Content %></div>
<% } %>
<% if (Model.CurrentPage > 0){ %>
<%: Html.ActionLink("Newer posts", "Index", "Home", new { page=Model.CurrentPage - 1}, null) %>
<%} %>
<% if (Model.CurrentPage + 1 < Model.TotalPages) { %>
<%: Html.ActionLink("Older posts", "Index", "Home", new { page=Model.CurrentPage + 1}, null) %>
<% } %>
PostsController:
public class PostsController : Controller
{
private const int PostsPerPage = 2;
private readonly IPostRepository _postRepository;
public PostsController()
{
...
}
public ActionResult Index(int page = 0)
{
var model = new PostsViewModel();
int totalPages = 1;
model.CurrentPage = page;
model.Posts = _postRepository.GetPosts(page, PostsPerPage, out totalPages);
model.TotalPages = totalPages;
return PartialView(model);
}
}
There's got to be a better way than this?
I don't know if I understand correctly but you could load this Partial View in a using Ajax (by jQuery), and when you need to refresh only this part of content you reload the element. Something like this:
In Javascript:
function LoadComments(page) {
//It'll return a partial view
$("#comments").load("<%=Url.Action("Posts", "Index")%>?page=" + page);
}
$(document).ready(function() {
LoadComments(0);
});
Inside of yoru PartialView you need to render a javascript code to call the "reload" of the next (page) content, so call LoadComments(index-page)...
Look the Ajax APi of jQuery: http://api.jquery.com/category/ajax/
Cheers
I have an AJAX form which returns a partial view, but instead of the target div getting updated, when I submit, only the partial view is shown. As far as I can tell, I have everything set up the way it's supposed to be, what's going wrong?
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ApplianceSurvey.Models.Item>" %>
<% using (Ajax.BeginForm("AddSurveysAJAX",
new AjaxOptions { UpdateTargetId = "SurveyListContent", InsertionMode = InsertionMode.Replace }))
{ %>
<%= Html.Hidden("itemID", Model == null ? ViewData["itemID"] : Model.ItemID) %>
<%= Html.ListBox("SurveysLst", ViewData["Surveys"] as MultiSelectList)%>
<input type="submit" value=">>>" />
<%= Html.ListBox("SelSurveysLst", ViewData["ItemSurveys"] as MultiSelectList)%>
<% } %>
and in the controller:
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult AddSurveysAJAX(FormCollection formValues)
{
//do stuff
return PartialView("ItemSurveys");
}
I have a strongly typed partial view that populates all the Records from Search table.
Now i have a textbox to enter name & a button to filter the records that can match a name.(Like Search page).
Can anybody provide code sample for this scenario?
My Main Page loads particular view based on the radiobutton selection(Search or Inquiry) as below using JQuery:
/* Loading the partial view based on radio button click... */
$(document).ready(function() {
$(':radio').click(function() {
if (this.value == '2') {
$('#ViewAllInquiries').load('/Home/Inquiry', function(html) { $('#ViewAllInquiries')[0].value = html; });
}
else {
$('#ViewAllInquiries').load('/Home/Search', function(html) { $('#ViewAllInquiries')[0].value = html; });
}
});
})
Here is my one of the Partial view ControllerCode:
[HttpGet]
public ActionResult Search()
{
var search = from s in entity.Search
select s; return PartialView(search);
}
Here is the User control Partial view(Search.ascx):
>" %>
<table >
<thead>
<tr>
<th align="left"> </th>
<th align="left"> TX_Id</th>
<th align="left">Name
<%= Html.TextBox("Name")%> <input type="submit" value="Filter" /></th>
<th align="left">Email Address</th>
</tr>
<% foreach (var item in Model)
{ %>
<%= Html.Encode(item.TX_Id) %>
"><%= Html.Encode(item.CustomerMaster.FullName()) %>
<%= Html.Encode(item.CustomerMaster.MS_Id) %>
<% } %>
Thanks for your time.
I do the same thing using an Ajax form. It's really easy. Here's the code I use:
Html:
<div>
<%
using (Ajax.BeginForm("Home", "Search", null,
new AjaxOptions { UpdateTargetId = "Output" },
new { id = "SearchForm" }))
{
%>
<!-- Form Fields -->
<input name="searchField" />
<input type="submit" value="Search" />
<%
}
%>
<div id="Output">
</div>
</div>
Then in the controller you just have:
public PartialViewResult Search(FormCollection form)
{
var model = YourSearchMethod(form["searchField"]);
return PartialView("Search", model);
}
The div with the id "Output" will be updated with your partial view result every time the submit button is clicked. In your case you have two different potential partial views, just submit the radio button value as part of your form and you can switch the output view from within the controller.
Why use FormCollection instead of parameters? I've had some difficult using named parameters with ajax forms, but you can try it and see how it works. It should look something like this instead:
public PartialViewResult Search(string searchField, bool inquiry)
{
if (inquiry)
{
var model = YourInquiryMethod(searchField);
return PartialView("Inquiry", model);
}
else
{
var model = YourSearchMethod(searchField);
return PartialView("Search", model);
}
}
I do the same on one of my sites but have implmented it a little diffently.
I have, in my View the following html;
<div class="EditProductContainer hidden"></div>
I also have the following jQuery;
function editBenefit(objThis) {
var id = $(objThis).parents('.Benefit').attr("id");
$.post("/Home/jQueryGetBenefit", { Id: id },
function(newHTML) {
$('.EditProductContainer').html(newHTML);
});
}
Then in my controller I have;
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult jQueryGetBenefit(int Id)
{
Application application = Helpers.CacheHelper.Get();
Benefit thisBenefit = application.findBenefit(Id);
return PartialView("EditBenefit", thisBenefit);
}
I think this is doing what you want but I'm returning a rendered PartialView and replacing the contents of a containing div with the html generated by the partial view.
Hope this is of some help.
I try to creat list for detail view. then put a search text box on the top of the list. Hope the search result will replace the list partially.
My control code like:
public ActionResult Index(int? page)
{
Repository repository = new Repository();
var listitems= repository.FindAllItems();
return View(registry_page);
}
public ActionResult Search(string keyword)
{
try
{
Repository repository = new Repository();
var listitems = repository.FindItemsByKeyWord(keyword);
return View("Index", registries);
}
catch
{
return View("Index");
}
}
My View code like:
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>" type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>" type="text/javascript"></script>
<% using (Ajax.BeginForm("Search", new AjaxOptions { UpdateTargetId = "MyList" }))
{ %>
<p>
Search:
<input id="keyword" name="keyword" type="text" />
<input type="submit" value="Go" />
</p>
<% } %>
<div id="MyList">
<table idth="780px">
...
<% foreach (var item in Model)
{ %>
<tr>
...
</tr>
<% } %>
</table>
</div>
When I submit the ajax form, it did reach the right action Searcn and I did get the right result from repository, but the list in the view wasn't replaced with the new result.
If I change search action like:
public ActionResult Search(string keyword)
{
string teststring = "<div>This is a test string to replace the list</div>";
return Content(teststring);
}
The list wil be replace by the test string.
How to fix this problem?
You can pull MyList out into a Partial view, MyPartialList.ascx
Your search actionresult should then return this partial view, something like this:
public ActionResult Search(string keyword)
{
Repository repository = new Repository();
var listitems = repository.FindItemsByKeyWord(keyword);
return PartialView("MyPartialList", listitems);
}
In the index view, render the initial list like this:
<div id="MyList">
<% Html.RenderPartial("MyPartialList",Model); %>
</div>
Your partial, MyPartialList.ascx would look like this:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Item>>" %>
<table ..>
<% foreach(var item in Model){%>
// print it out
<%}%>
</table>
having a problem passing ViewData.Model to the partial views. It always is defaulting to null even if I equate it to a result query. I cannot access the strongly typed data because the Model is null. My current code is this,
ViewPage
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("header", this.ViewData.Model); %>
<% Html.RenderPartial("test", this.ViewData.Model); %>
<div id="userControls">
</div>
</asp:Content>
UserControl - header
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<testMVCProject.Models.information>" %>
<h2>
ACReport</h2>
<p>
id:
<%= Html.Encode(Model.id) %>
</p>
<p>
type:
<%= Html.Encode(Model.type) %>
</p>
UserControl - test
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<testMVCProject.Models.information>" %>
<% using (Ajax.BeginForm(
"pressureV2",
"Home",
new { id = ViewData.Model.id },
new AjaxOptions
{
UpdateTargetId = "userControls",
HttpMethod = "GET"
},
new { #id = "genInfoLinkForm" }))
{%>
<%= Html.SubmitButton("hey", "Lol") %>
<%} %>
Controller
public ActionResult header(int id)
{
var headerResults = from c in db.information
where c.id == id
select new information
{
id = c.id,
type = c.type
};
ViewData.Model = headerResults.FirstOrDefault();
return View(ViewData.Model);
}
public ActionResult pressureV2(int id)
{
var pressureVResults = from c in db.pressure_volume_tests
where c.id == id
select new pressureVT
{
bottomCVP = c.bottom_CVP,
topCVP = c.top_CVP
};
ViewData.Model = pressureVResults.FirstOrDefault();
return View(ViewData.Model);
}
In the comments you have said that the view is not strongly typed. Because of that:
<% Html.RenderPartial("header", this.ViewData.Model); %>
<% Html.RenderPartial("test", this.ViewData.Model); %>
will not work. If you strongly type your view to testMVCProject.Models.information and then pass an instance of that type from your constructor it will work.
Controller:
public ActionResult ShowAView()
{
Return View("WhateverYourViewIsCalled", new information());
}
You have a misunderstanding of the use of Html.RenderPartial helper.
When you use the RenderPartial you will show the view without requesting the model from the controller.
So you have to refactor your ViewPage and pass the good Model to your usercontrols:
Exemple:
Controller:
ActionResult MainView()
{
var mainviewobj = new MainViewObject();
var headerResults = from c in db.information
where c.id == id
select new information
{
id = c.id,
type = c.type
};
mainviewobj.info = headerResults.FirstOrDefault();
return view(mainviewobj);
}
View Code:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("header", this.ViewData.Model.info); %>
<% Html.RenderPartial("test", this.ViewData.Model.info); %>
<div id="userControls">
</div>
</asp:Content>
View Code Behind
public partial class MainView : ViewPage<MainViewObject>
{
}
Now the Model will not be null in your usercontrol.
But remember the usercontrol rendering partially dun execute the code in the controller
So you dun need the public ActionResult header(int id) in your Controller
Hope this helps.
Have you tried making the ViewPage generic as well?
The Controller doesn't get called when you RenderPartial - it is bypassed and the view is rendered directly. So whatever you want to pass in as a model needs to be done from the calling View.
I found this worked for me, reference the partial as you do, like so.
...form
#Html.Partial("_AboutYou", Model.AboutYou);
..end form
within the partial view at the top...
#model <namespace1>.<namespace2>.<namespace3>.CustomerInfo.AboutYou
#{
ViewData.TemplateInfo.HtmlFieldPrefix = "AboutYou";
if (this.ViewContext.FormContext == null)
{
this.ViewContext.FormContext = new FormContext();
}
}
I believe the problem might be that you're missing an element in the form with the name "id" so the parameter of the Action method is never populated with a value?
That way the query would always return null with the FirstOrDefault, hence the null Model.
Just my guess...