I have a page with partial view that contains DevEx ComboBox with Add button and DevEx GridView ( I omitted GridView code). Page is showing properly with that partial view, only I have a problem with refreshing it.
//_ProductAppsGridViewPartial
<div class="form-horizontal">
<h4>Apps</h4>
#using (Html.BeginForm("AppsGridViewPartialAddNew", "Products", new { ProductID = ViewBag.ProductID }))
{
<div class="form-group">
<h5>Add new App:</h5>
#Html.DevExpress().ComboBox(settings =>
{
//..do some settings for ComboBox - some code omitted
settings.Properties.ValueField = "ApplicationID";
settings.Properties.TextField = "Name";
}).BindList(Model.AppsNotInProduct).GetHtml()
<input type="submit" value="Add" class="btn btn-default" />
</div>
}
</div>
I have action on my controller that adds selected app in database and returns a PartialView with the same (but refreshed) model, but response shows only that partial View. Here is a part of Controller's action that returns PartialView after updating database:
public ActionResult ProductAppsGridViewPartialAddNew(int ProductID)
{
//....update DB code - WORKS FINE
..
var model = GetProductAppsPartialModel(ProductID);
ViewBag.ProductID = ProductID;
ViewBag.CanEdit = true;
return PartialView("_ProductAppsGridViewPartial", model);
}
Is it possible to refresh a partial view wihout AJAX, maybe something i wrote above? So the main problem here is that i get new page showing only a partial view.
To refresh part of a page you will need to use ajax to replace only the needed content. You will also need to use JavaScript to re-render the HTML contained in the partial. MVC comes with some ajax helpers or you can do it yourself with jquery. At the moment the action result is returning the partial as requested but the browser is being told it is receiving a whole new page and is displaying as such.
Adding this link to Microsoft ajax to show some of your options.
I would use jquery and do this yourself. Also try to remember that mvc is a server side framework to help you return http messages to the browser. You are trying to manipulate things client side. Live client side updates always need ajax to get data. Replacing items in the DOM needs some form of JavaScript. Libraries like jquery make this a lot easier. Have a look at jquery ajax here.
I think you need to try this code.
Note here we need to keep ajax call for update the partial view
#using (Ajax.BeginForm("ActionName", "Controller", new { model = #Model.ID },
new AjaxOptions
{
OnSuccess = "onSuccessRefresh "
}))
{
<table>
<td>
</td>
<td> <input type="button" value="AddValue" /> </td>
</table>
}
Handle the code onsuccess event using jquery:-
function onSuccessRefresh {
// refersh your page or table
}
This is not the full code. but I think it will help to you
Related
I'm POSTing and trying to re-load a partial view with the new data using Ajax like this:
Index.cshtml
<div id="left-column">
#Html.Partial("~/Views/Project/_ProjectList.cshtml", Model.ProjectList)
</div>
~/Views/Project/_ProjectList.cshtml
#using (Ajax.BeginForm("Create", "Project", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "left-column"
}))
{
<h3>Create a new project</h3>
<div class="form-group">
<label for="new-project-name">Name</label>
<input type="text" class="form-control" id="new-project-name" name="Name" placeholder="Example" />
</div>
<button type="submit" class="btn btn-primary">Create Project</button>
Cancel
}
Then my Controller returns the PartialView after some db work:
[HttpPost]
public PartialViewResult Create(Project newProject)
{
db.Projects.Add(newProject);
db.SaveChanges();
var projectList = db.ProjectLists.SingleOrDefault(pl => pl.Id == 1);
return PartialView("~/Views/Project/_ProjectList.cshtml", projectList);
}
I would expect the _ProjectList partial view to load into the #left-column element with the new projectList passed in by the Controller, but instead, the entire View is being overwritten, so the entire body of the new HTML source looks basically like this:
<body>
<!-- all the stuff from the _ProjectList partial -->
</body>
It's worth noting that after the partial view returns, the URL reads /Project/Create, which I wouldn't expect.
I've included jquery-validate and jquery-validate-unobtrusive, and the console isn't showing any errors, so that shouldn't be the problem.
Any idea what's going on?
When using Ajax.BeginForm helper method to do ajax form posting, you need to include the jquery.unobtrusive-ajax.js file as well. This file has the code to handle the submit button click event and send the form asynchronously rather than doing the normal form submit.
If you do not include this file, the form submit will be normal. My guess is that you missed to include this file and hence missing the ajaxified form submit experience.
So make sure to load this file after jQuery
#Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Here is the link to nuget page if you want to add this file via nuget package manager.
Benjy got it in a comment above. It was a jQuery version issue. I'm running 3.1.0, and jquery.unobtrusive-ajax stopped working with jQuery version 1.9.
I have a Controller myCustomers with a View.
The controller has two useful ActionResults; namely loadDataTotbl and CreatePDF.
(Filestream with Itextsharp).
loadDataTotbl loads the View fine which is simply a db obj via LINQ.
The View has a table in a form with some elements and a create PDF button e.g.:
#using (Html.BeginForm("CreatePDF", "myCustomers", FormMethod.Post))
{
<form>
<table>
#foreach (var cn in Model)
{
<input type="text" value="#pn.CustomerName" name="cNameVal" />
}
<input type="submit" value="Download the PDF" />
</table>
</form>
}
It works fine. When I hit the button, PDF gets created.
How do I create the PDF but hide/bypass this view? Please note my View has to remain as I strip it's headers and values and use them in CreatePDF action to create and design my PDF.
Do I need partial view? How would it work here?
I don't think I can hide views if they have data I need.
How do I do this?
I am using ASP.NET MVC to post a strong typed view to a controller this way:
#using MyApp.Model
#model UserTest
#{
Layout = null;
}
#using (Html.BeginForm())
{
<div>
<p>Name: #Html.TextBoxFor(u => u.Data, new { Name = "txtName" })</p>
</div>
<div style="clear:left; padding-top: 15px">
<input type="submit" value="Create" id="btnSubmit" />
</div>
}
On the Controller:
[HttpPost]
public ActionResult Create(UserTest userdata)
{
}
When I post the form, the userdata received has its only property as a null value
But, if I remove the htmlAttribute that changes the name property of the textbox this way:
#using (Html.BeginForm())
{
<div>
<p>Name: #Html.TextBoxFor(u => u.Data)</p>
</div>
<div style="clear:left; padding-top: 15px">
<input type="submit" value="Create" id="btnSubmit" />
</div>
}
When I post the form, the userdata received has a valid property with a value that is correctly bind.
I wonder if I am missing something here because this looks like a bug. If this is the case, should I avoid changing the names of the generated HTML objects on the MVC helpers altogether?.
The version of MVC I have is 5.2.2.0 and the runtime version of the framework is: v4.0.30319
I appreciate the insight on this.
This is not a bug. This is expected behaviour.
Model binding works by binding the key/value pairs sent by the browser in a form post to model properties (or view data). A form input's name attribute is what is used as its key in the form data submitted in a POST request.
When you use HTML helpers to render form fields, the framework automatically generates the appropriate name attributes required to ensure that the field will bind properly to the property specified in the expression you pass to the helper.
If you change the name, you break the only connection between the form input and the property it binds to.
should I avoid changing the names of the generated HTML objects on the MVC helpers altogether?.
Yes. The input elements' names are what makes model binding work.
So no, not a bug. Don't change them.
You don't explain why you want to change them, but you may be able to use a different attribute to accomplish what you want.
I have a view with 3 partial views. The first partial view has a dropdown list. You select something from the dropdown then the 2nd partial view will load right under it on the same page.
Then I have a search form (html.BeginForm) in my second partial view and when I submit the form I want to open up the 3rd partial view under the 2nd one.
The 3rd partial view has a kendo ui grid that takes a model.
The problem right now is that the 3rd partial view is getting rendered on a different page.
View:
<section>
<div id="searchpanel">
#html.Partial("_1stPartial")
<div id="2ndPartialDiv"></div>
<div id="3rdPartialDiv"></div>
</div>
</section>
Partial View2:
<section>
<div id="searchblock">
<table>
<tr>
<td>
#using (Ajax.BeginForm("Search", "ControllerName", new AjaxOptions { updateTargetId = "3rdPartialDiv"}))
<fieldset>
<ol>
<li></li>
<li>
<input type="submit" value="Search" id="btnSearch"/>
</li>
</ol>
</fieldset>
</td>
</tr>
</table>
</div>
</section>
Controller:
public ActionResult Search(model)
{
//fill searchresults
return PartialView("_3rdPartial", searchresults);
}
Html.BeginForm will perform a full page post. I believe what you are after is Ajax.BeginForm.
http://msdn.microsoft.com/en-us/library/system.web.mvc.ajax.ajaxextensions.beginform(v=vs.118).aspx
Example:
#using (Ajax.BeginForm("TheActionResultYouWantToInvokeThatWillReturnTheThirdView", "YourController", null, new AjaxOptions { UpdateTargetId = "theIdOfTheDivForTheThirdView", OnSuccess = "doFunctionIfYouNeedTo", OnFailure = "ShowPopUpErrorIfYouWant" }))
{
}
Post code added edit:
This markup was invalid, and probably why UpdateTargetId is not finding the Div.
<section>
<div id="searchpanel">
#html.Partial("_1stPartial")
<div id="2ndPartialDiv"></div>
<div id="3rdPartialDiv"></div>
</div>
</section>
See closing speech marks on attributes.
What I understood from you question is that you're making a submit from the first PartialView and, if this was successfully, you'll show the 2nd one. Same for this one. If a successfully POST was made from the second PartialView, you want to show the 3rd one.
Why don't you do it with Ajax, from the client side?
$.ajax ({
type:'POST'
data: {},
success: function(response){
$('.specific_div_container_for_previous_partial').hide();
$('.specific_div_container_for_partial').html(response.Html);
$('.specific_div_container_for_partial').show();
},
error: function(){
// whatever
}
});
On the server side you'll return the rendered html with your PartialView. To render a PartialView in variable and send it the client side as a json object, please check out THIS
Update - How to serialize form in jquery :
Please follow THIS
If I am using an Ajax.ActionLink helper, and I need to pass a couple parameters to the controller action, how can I get the value of a TextArea that is not bound to a model?
For instance, I want the user to fill out a textarea, and then click Save, sending the textarea value to the controller action for further processing.
Do I use ViewBag? If so, how do I assign the value of a DOM element to ViewBag?
I've toyed with this problem before, and you can get around it by using Ajax.BeginForm.
Take this follow example:
I have a model Person that one string property for Name.
View
#model Application.Models.Person
<fieldset>
<legend>Form</legend>
#using (Ajax.BeginForm("SendUp", "Home", new AjaxOptions
{
HttpMethod = "POST",
OnComplete = "window.location.href = 'Index'"
}))
{
<p>
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
</p>
<p>
#Html.TextArea("ta")
</p>
<p>
<input type="submit" value="Submit" />
</p>
}
</fieldset>
Controller
[HttpPost]
public ActionResult SendUp(string Name, string ta)
{
string s = ta;
// Process stuff here
// Go to another action or whatever
return RedirectToAction("Index");
}
Using Ajax.BeginForm() allows you to send data up to the controller even if it not bound to a model on the page. You need to make sure that the name property of your Html element is the same name as the parameter that the controller needs.
So if you have the controller method of
public ActionResult SendUp(string Name, string ta)
You will need to have an Html element of with the name Name and ta inside of the Ajax.BeginForm().
To do this you can either write out the entire element:
<input type="text" id="Name" name="Name" />
Or you can use the #Html helpers.
#Html.Editor("Name")
When you provide the name for the #Html helper it will set that value to as the id property and to the name property as well.
ViewBag is a server-side concept. It does not exist once the page has been rendered.
There is no way that I know of to declaratively link a field on the page with an action parameter.
To do what you want you have two options:
- get rid of the Ajax.ActionLink helper, and write some Javascript (sorry, Ican't really help you there)
- Use to Ajax.BeginForm instead and put the relevant fields in the form, so that a click on the submit button will submit the form back to your action through ajax.