Is there a way to submit a partial view form in asp.net mvc without reloading the parent page, but reloading the partial view only to its new state? Similar to how knockout.js updates using data-bind.
My data table renders with a variable number of columns/names so I don't think knockout.js is an option for this one, so I am trying to use a partial view instead.
Not without jQuery.
What you would have to do is put your Partial in a div, something like:
<div id="partial">
#Html.Partial("YourPartial")
</div>
Then, to update (for example clicking a button with the id button), you could do:
$("#button").click(function () {
$.ajax({
url: "YourController/GetData",
type: "get",
data: $("form").serialize(), //if you need to post Model data, use this
success: function (result) {
$("#partial").html(result);
}
});
})
Then your action would look something like:
public ActionResult GetData(YourModel model) //that's if you need the model
{
//do whatever
return View(model);
}
Actually, if your Partial has a child action method, you can post (or even use an anchor link) directly to the child action and get an Ajax-like affect. We do this in several Views.
The syntax is
#Html.Action("MyPartial")
The Child Action is
public ActionResult MyPartial()
{
return PartialView(Model);
}
If your form posts to the child action
#using (Html.BeginForm("MyPartial"))
{
...
}
The Partial View will be updated with the partial view returned from the child action.
Jquery is still a legitimate way to update a partial. But technically, the answer to your question is YES.
As normal what I find when looking for things like this is people give too limited information so I will attempt to help here. The key is to set up a div with an ID you can append the return html to. Also when hitting your controller make sure it returns the partial. There are some potential problems with this method but on a good day it should work.
<div id="CategoryList" class="widget">
#{
Html.RenderPartial("WidgetCategories.cshtml");
}
</div>
function DeleteCategory(CategoryID) {
$.get('/Dashboard/DeleteWidgetCategory?CategoryID=' + CategoryID,
function (data) {
if (data == "No") {
alert('The Category has report widgets assigned to it and cannot be deleted.');
}
else {
$('#CategoryList').html(data);
}
}
);
}
[HttpGet("DeleteWidgetCategory")]
[HttpPost("DeleteWidgetCategory")]
public IActionResult DeleteWidgetCategory(string CategoryID)
{
string Deleted = CategoryModel.DeleteCategory(CategoryID);
if (Deleted == "Yes")
{
return PartialView("WidgetCategories");
}
else
{
return this.Json("No");
}
}
I would use the Ajax Form helper for such scenarios using a partial view and #html.RenderPartial("partialName")
partial helpers
In your Main View
<div id=SearchResult>
#Html.Partial("_NameOfPartialView", Model)
</div>
<input type="button" id="btnSubmit" value="Submit">
In your Javascript file
$('#btnSubmit').click(function () {
GetData(Id);
});
function GetData(Id){
$.ajax({
url: "/Home/GetEmployee/",
type: "get",
data: { Id:Id },
success: function (result) {
$('#SearchResult').html(result);
}
});
}
In your Home Controller
public ActionResult GetEmployee(int Id)
{
var employee= context.Employee.Where(x=> x.EmployeeId == Id)
return this.PartialView("_NameOfPartialView", employee);
}
Related
In my web app I have a grid list. I select a row and then click the edit button to show a partial update view (which I use to add new data too) in a popup window. The view shows, but I don't have any values in the textboxes. I use devextreme components, but I think, my issue has nothing to do with it (maybe I'm wrong).
This is the onClick code:
function editrow_onClick() {
var key = $("#grid").dxDataGrid("instance").getKeyByRowIndex(selectedRowIndex);
$.ajax({
url: '/MasterData/Sender/UpdateSender/'+key,
}).done(function (response) {
var popup = $("#sender-popup").dxPopup("instance");
popup.option("contentTemplate", function (content) {
content.append(response);
});
popup.show();
});
}
If I click the edit button, I get the right url like /MasterData/Sender/UpdateSender/3.
The corresponding controller action looks like this:
[Route("{id}")]
public IActionResult UpdateSender(long SenderId)
{
return PartialView("NewSender", SenderRepository.GetSender(SenderId));
}
On top of the controller class I have the corresponging attribute: [Route("MasterData/[controller]/[action]")]
I testet id, the action is reached, but the SenderId is 0. I would expect f.e. 3. This should be causing the empty view, I think. Why is SenderId 0 (the default value)?
I post the update view too, maybe this is the source of the problem (don't bother the AddSender action, I plan to change it conditionally, if I get the update data working):
#model Sender
<form asp-action="AddSender" asp-controller="Sender" method="post">
#using(Html.DevExtreme().ValidationGroup()) {
#(Html.DevExtreme().Form<Sender>()
.ID("form")
.ColCount(1)
.Items(items => {
items.AddSimpleFor(m => Model.Name);
items.AddSimpleFor(m => Model.Address);
items.AddSimpleFor(m => Model.ContactPerson);
items.AddSimpleFor(m => Model.ContactEmail);
items.AddGroup().Items(groupItem => groupItem.AddSimple().Template(
#<text>
<div style="text-align: right">
#(Html.DevExtreme().Button().ID("save").Text("Mentés").Width(100).Type(ButtonType.Success).UseSubmitBehavior(true))
#(Html.DevExtreme().Button().ID("cancel").Text("Mégsem").Width(100).Type(ButtonType.Normal).OnClick("close_onClick"))
</div>
</text>));
})
.LabelLocation(FormLabelLocation.Top)
.FormData(Model)
)
}
</form>
<script>
function close_onClick() {
$("#sender-popup").dxPopup("hide");
}
</script>
[Route("{SenderId}")] public IActionResult UpdateSender(long SenderId) { return PartialView("NewSender", SenderRepository.GetSender(SenderId)); }
Try replacing id with SenderId.
Then action method will hit with the desired value.
What would be the best way to display on home page (HomeController, view Index) two last news from other model (News)?
I've created partial view in shared views directory, there is how it looks like:
#model IEnumerable<MyApp.Models.News>
#foreach (var item in Model.Where(x => x.IsActive ==
true).OrderByDescending(x => x.DateCreated).Take(2)) {
<li>
#Html.ActionLink(item.DateCreated.ToString(), "Details", "News", new { id = item.NewsId})
<p>#item.Content</p>
</li>
}
but this way I'm getting error:
An exception of type 'System.ArgumentNullException' occurred in
System.Core.dll but was not handled in user code
Model is not null, there are exactly two "active" records in my db, index file for this model is also correct, but I don't have any idea how to render this partial to my index homepage... (now I have in Index.cshtml view for HomeController #Html.Partial("_LatestNews"))
Thanks for advance for any help.
You'd need to pass the model into the partial, like such;
#Html.Partial("_LatestNews", Model.News))
Your partial view is expecting IEnumerable which you missed to pass, it should have something like this.
#Html.Partial("_LatestNews", new IEnumerable<MyApp.Models.News>)
However, I would do rather following in this case.
Layout View Page
Latest News
<script>
$(function () {
$("#content").html("Loading...");
//Use setTimeout if you want to keep update or call LoadPartialView() directly.
setTimeout(function () { LoadPartialView(); }, 5000);
});
function LoadPartialView() {
$.ajax({
type: "GET",
url: '#Url.Action("GetNews", "Home")',
dataType: "html",
success: function (data) {
$("#content").empty();
$("#content").html(data);
$("#content").fadeIn('slow');
},
error: function (data) {
$("#content").empty();
}
});
};
</script>
Controller
[HttpPost]
public ActionResult GetNews()
{
List<MyApp.Models.News> model = db.GetNews();
return PartialView("_LatestNews", model);
}
How to Pass value from text using #html.actionlink in asp.net mvc3 ?
None of the answers here really work. The accepted answer doesn't refresh the page as a normal action link would; the rest simply don't work at all or want you to abandon your question as stated and quit using ActionLink.
MVC3/4
You can use the htmlAttributes of the ActionLink method to do what you want:
Html.ActionLink("My Link Title", "MyAction", "MyController", null, new { onclick = "this.href += '&myRouteValueName=' + document.getElementById('myHtmlInputElementId').value;" })
MVC5
The following error has been reported, but I have not verified it:
A potentially dangerous Request.Path value was detected
Rather than passing your value using #Html.actionlink, try jquery to pass your textbox value to the controller as:
$(function () {
$('form').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: { search: $('#textboxid').val()},
success: function (result) {
$('#mydiv').html(result);
}
});
return false;
});
});
This code will post your textbox value to the controller and returns the output result which will be loaded in the div "mydiv".
to pass data from the client to the server you could use a html form:
#using (Html.BeginForm(actionName,controllerName)) {
<input type="text" name="myText"/>
<input type="submit" value="Check your value!">
}
be sure to catch your myText variable inside your controller's method
you can use this code (YourValue = TextBox.Text)
Html.ActionLink("Test", new { controller = "YourController", action = "YourAction", new { id = YourValue }, null );
public class YourController : Controller
{
public ActionResult YourAction(int id)
{
return View("here your value", id);
}
}
I have a partial view which has a Ajax.BeginForm, with a UpdateTargetID set. When the validation on the form fails the update target id is replaced with the validation errors, but when there are no validation errors users should be redirected to a new page.
The code in my Partial view is
<div id="div_UID">
<% using (Ajax.BeginForm("FindChildByUID", new AjaxOptions { UpdateTargetId = "div_UID" } ))
{%>
<p>
<label>UID:</label>
<%= Html.TextBox("UID") %>
</p>
<input type="submit" value="Continue" />
<% } %>
</div>
</pre>
The code in my controller is as follows
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult FindChildByUID(Student student)
{
Student matchingStudent = _studentService.FindChildByUID(student.UID);
if (matchingStudent == null)
{
ModelState.AddModelError("UID", String.Format("No matching child found for the entered UID: {0}", student.UID));
return PartialView();
}
else
{
// full view
return RedirectToAction("ConfirmChildDetails", matchingStudent);
}
}
So, for I have been unsuccessful to display the full view on it's own, as it always seems to dipslay the full view in the UpdateTargetID div specfied in the Ajax.BeginForm.
Any suggestions on how I can get this to work?
Thanks
What your AJAX post is doing is making a request and waiting on a response that contains html to input onto the page. The configuration is such that whatever html is returned will be injected into the div you've named "div_UID".
I typically avoid scenarios like this and use traditional posting if a redirect is required upon a successful outcome of the POST.
I imagine you could do it like this using jQuery to submit rather than the Ajax.BeginForm (or just set a callback function for your Ajax.BeginForm):
function SubmitForm(form) {
$(form).ajaxSubmit({ target: "#div_to_update", success: CheckValidity });
}
function CheckValidity(responseText) {
var value = $("#did_process_succeed").val();
if (value == "True") {
window.location.replace("url_of_new_action_here");
}
}
You just have to have a hidden field in your partial view called "did_process_succeed" and set the value of True or False based on some logic in your controller.
There are likely other ways as well. Perhaps someone else will chime in. I hope this helps for now.
I'm very new to web app development and I thought I would start with recent technology and so I'm trying to learn asp.net as-well as the MVC framework at once. This is probably a very simple question for you, MVC professionals.
My question is should a partial view have an associated action, and if so, does this action get invoked whenever a normal page uses RenderPartial() on the partial view?
While you can have an action that returns a partial view, you don't need an action to render a partial view. RenderPartial takes the partial view and renders it, using the given model and view data if supplied, into the current (parent) view.
You might want an action that returns a partial view if you are using AJAX to load/reload part of a page. In that case, returning the full view is not desired since you only want to reload part of the page. In this case you can have the action just return the partial view that corresponds to that section of the page.
Standard mechanism
Making use of partial view within a normal view (no action needed)
...some html...
<% Html.RenderPartial( "Partial", Model.PartialModel ); %>
...more html..
Ajax mechanism
Reloading part of a page via AJAX (note partial is rendered inline in initial page load)
...some html...
<div id="partial">
<% Html.RenderPartial( "Partial", Model.PartialModel ); %>
</div>
...more html...
<script type="text/javascript">
$(function() {
$('#someButton').click( function() {
$.ajax({
url: '/controller/action',
data: ...some data for action...,
dataType: 'html',
success: function(data) {
$('#partial').html(data);
},
...
});
});
});
</script>
Controller for AJAX
public ActionResult Action(...)
{
var model = ...
...
if (Request.IsAjaxRequest())
{
return PartialView( "Partial", model.PartialModel );
}
else
{
return View( model );
}
}
The accepted answer is completely correct, but I want to add that you can load your partial view using jQuery load. Less configuration needed, if you don't want to consider concurrency.
$("#Your-Container").load("/controller/action/id");
I was able to achieve something similar with this logic.
Within the .cshtml
#Html.Action("ActionMethodName", "ControllerName");
Within the controller
[Route("some-action")]
public ActionResult ActionMethodName()
{
var someModel = new SomeModel();
...
return PartialView("SomeView.cshtml", someModel);
}
And that's it.
If you need to pass values from the .cshtml to the action method then that is possible to.
The answer is no. But sometimes you need some controller action behind a partial view. Then you can create an actionMethod wich returns a partial view. This actionMethod can be called within another view:
#Html.Action("StockWarningsPartial", "Stores")
The actionmethod can look like:
public ActionResult StockWarningsPartial()
{
....
return View("StockWarningsPartial", warnings);
}
and the view 'StockWarningsPartial.cshtml' starts with:
#{
Layout = null;
}
to make it not render your surrounding layout again.
public ActionResult GetStateList(int country_id)
{
List<stateDTO> stateList = new List<stateDTO>();
stateList = bll.GetState(country_id);
ViewBag.sList = new SelectList(stateList, "state_id", "State_Name");
return PartialView("DisplayStates");
}