How to TryUpdateModel from outside of Controller in MVC3 - asp.net-mvc-3

My app has modules that can be turned on and off and these modules are contributing to a view via Html.Partial calls. When the page posts back to the controller I want to have the modules take care of their individual models using something like TryUpdateModel that the controller has. Problem is that TryUpdateModel is a protected method and not accessible from outside the controller.
How can I do something like Controller.TryUpdateModel from a class outside of the controller?

If I am reading this right, it sounds like you are wanting a partial view to update itself.
I have done something similar with some jQuery, by calling an action and returning a partial view inside of a partial view. Inception?
Simple Example. - really simple
_partialViewStart.cshtml
<div id="partialFillerResult">
</div>
<script type="text/javascript">
$(document).ready(function() {
loadPartialViewFiller();
});
function loadLatestTribes() {
$("#partialFillerResult").load("#Url.Action("PartialViewFiller", "Home")").fadeIn("slow");
setTimeout(loadPartialViewFiller, 5000);
}
</script>
HomeController.cs
public ActionResult PartialViewFiller()
{
var yourModel = new ExpandoObject();
if (yourModel == null) return PartialView("_empty");
return PartialView("_partialViewFiller", yourModel);
}
_partialViewFiller.cshtml
#model dynamic
<div class="objectWrapper">
<p>
#Model.Name
</p>
</div>

Related

Update the data in View with AJAX not working

I have diffrent <a> tags that normally pass a parameter to an action using asp-route="". Now i want to use AJAX t do this. each tag is supposed to pass an ID that comes from the model chats when the page loads up. (asp-route-ChatID="#Model.ID").
How can I achieve this in AJAX and pass that parameter? I tried using Data-ajax-update and Data-ajax-url but these option arent even available in Intellisense. Here is the method that i want to call
public IActionResult Chat(string ChatID)
{
Chats userchats=new Chats(); // a class that holds chats
//selecting data from the database......
return View(userchats);//returns view with the model
}
here is the <a> tag that gets clicked and it needs to pass a specific ID that comes from the model
<a > View Chat </a>
here is the <div> that needs to be updated depending on what <a> is clicked
<div id="UpdateThis"> <!--show data that comes from the method ajax calls--> </div>
How can I implement ajax here with tag helpers or any other way?
Use PartialView instead of view if you want to update div.
public IActionResult Chat(string ChatID)
{
Chats userchats=new Chats(); // a class that holds chats
//selecting data from the database......
return PartialView(userchats);//returns view with the model
}
View
<a id="btnView" data-id="1">View Chat</a>
<div id="UpdateThis"></div>
<script>
$("#btnView").click(function () {
$.post('#Url.Action("Chat")', { ChatID: $(this).data("id") }).done(function (e) {
$("#UpdateThis").html(e);
})
});
</script>

View with multiple partial views posting back

I'm new to MVC (MVC3) so not sure about the best way to implement this.
I want to create a single "main" view (not strongly-typed). This "main" view will contain multiple strongly-typed partial views that each contain a form. Each partial view will therefore post back to their own POST action that does whatever. The problem I see is that when a partial view posts back, it needs to only update the partial view itself and not affect the other partial views on the page.
When I postback from a partial view now, it just returns the partial view alone back, rather than the entire "main" page.
How can this functionality be achieved in MVC3? (from a high-level perspective)
Thanks
You can post data by AJAX.
In my example I use jQuery:
<div id="first-form" class="form-container">
#Html.Partial("FirstPartial")
</div>
<div id="second-form" class="form-container">
#Html.Partial("SecondPartial")
</div>
// and here go rest forms
Your partial view may be following:
#model YourModelClass
#using (Html.BeginForm())
{
// some fields go there
}
<input type="button" value="Save Form Data" class="save-button"/>
Js would be following:
$("input.save-button").on("click", function () {
var button = $(this);
var container = button.closest("div.form-container");
var url = container.find("form").attr("action");
container.busy($.post(url, function (response) {
container.html(response);
}));
return false;
});

My controller viewmodel isn't been populated with my dynamic views model

Im creating an application that allows me to record recipes. Im trying to create a view that allows me to add the basics of a recipe e.g. recipe name,date of recipe, temp cooked at & ingredients used.
I am creating a view that contains some jquery to load a partial view clientside.
On post im having a few troubles trying to get the values from the partial view that has been loaded using jquery.
A cut down version of my main view looks like (I initially want 1 partial view loaded)
<div id="ingredients">
#{ Html.RenderPartial("_AddIngredient", new IngredientViewModel()); }
</div>
<script type="text/javascript">
$(document).ready(function () {
var dest = $("#ingredients");
$("#add-ingredient").click(function () {
loadPartial();
});
function loadPartial() {
$.get("/Recipe/AddIngredient", {}, function (data) { $('#ingredients').append(data); }, "html");
};
});
</script>
My partial view looks like
<div class="ingredient-name">
#Html.LabelFor(x => Model.IngredientModel.IngredientName)
#Html.TextBoxFor(x => Model.IngredientModel.IngredientName)
</div>
<div class="ingredient-measurementamount">
#Html.LabelFor(x => Model.MeasurementAmount)
#Html.TextBoxFor(x => Model.MeasurementAmount)
</div>
<div class="ingredient-measurementtype">
#Html.LabelFor(x => Model.MeasurementType)
#Html.TextBoxFor(x => Model.MeasurementType)
</div>
Controller Post
[HttpPost]
public ActionResult Create(RecipeViewModel vm,IEnumerable<string>IngredientName, IEnumerable<string> MeasurementAmount, IEnumerable<string> MeasurementType)
{
Finally my viewmodel looks like
public class IngredientViewModel
{
public RecipeModel RecipeModel { get; set; }
public IEnumerable<IngredientModel> Ingredients { get; set; }
}
My controller is pretty ugly......im using Inumerble to get the values for MeasurementAmount & MeasurementType (IngredientName always returns null), Ideally I thought on the httppost Ingredients would be populated with all of the on I would be able Ingredients populated
What do I need to do to get the values from my partial view into my controller?
Why don't you take a look at the MVC Controlstoolkit
I think they would do what you want.
Without getting in too much detail. Can you change the public ActionResult Create to use FormCollection instead of a view model? This will allow you to see what data is coming through if any. It would help if you could post it then.
Your view model gets populated by using Binding - if you haven't read about it, it might be a good idea to do that. Finally I would consider wrapping your lists or enums into a single view model.
Possible Problem
The problem could lay with the fact that the new Partial you just rendered isn't correctly binded with your ViewModel that you post later on.
If you inspect the elements with firebug then the elements in the Partial should be named/Id'ed something like this: Ingredients[x].Property1,Ingredients[x].Property2 etc.
In your situation when you add a partial they are probably just called Property1,Property2.
Possible Solution
Give your properties in your partial the correct name that corresponds with your List of Ingredients. Something like this:
#Html.TextBox("Ingredients[x].Property1","")
Of, after rendering your partial just change all the names en ID's with jquery to the correct value.
It happens because fields' names from partial view do not fit in default ModelBinder convention. You should analyze what names fields have in your partial view.
Also you should implement correct way of binding collections to MVC controller. You could find example in Phil's Haack post
Assuming RecipeViewModel is the model being supplied to the partial view, try just accepting that back in your POST controller like this:
[HttpPost]
public ActionResult Create(RecipeViewModel vm)
{
//
}
You should get the model populated with all the values supplied in the form.

MVC3 is it possible to serve a view section from a controller action?

Suppose I have index.cshtml
#{
ViewBag.Title = "Index";
}
#model SomeModel
#section JS{
content1
content2
content3
}
<div> View Content </div>
Is there any way I could have a controller action that would serve ONLY the section JS for a request for index.js?
Such that navigating to http://somesite/index.js would return
content1
content2
content3
Edit: Some further thoughts on this. My goal would be along the lines say creating a layout page that requires a JS section programmatically, and then composing the View to that layout page and then returning the results of this.
Psuedo code example:
var layout = new LayoutPage();
layout.DefineSection("JS", required: true);
layout.Compose(View("index"))
return layout;
I'm not set on achieving that with what I described but I feel that might offer some more insight on what I'd like to achieve.
You can do something like this (but you'd have to write your own controller action to do it properly)
Index.cshml
#model MvcApplication1.Models.TestModel
#{
ViewBag.Title = "Home Page";
}
<h2>#ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit http://asp.net/mvc.
</p>
#section JS {
blahblahblah
}
JSLayout:
#RenderSection("JS")
Your controller Action
public ActionResult Index() {
return View("Index", "_JSLayout", yourModel);
}
This will output only the JS section. If you want to do it programatically then it will take a bit.
The only way to do it would be to make the content of that section into a partial view, and return the partial view from the controller action.

Populate a partialview

I feel stupid asking this but I cant seem to get a partial view rendering in a page.
I have created a partial view that im trying to load into my index page. I have called my pv _BusinessDetails basically its a view that returns some customer data.
My pv looks like
#model MyMVC.Models.BusinessModel
<div class="grid">
<div class="grid-header">
<div class="gh-l"></div>
<div class="gh-m">Business Details</div>
<div class="gh-r"></div>
</div>
<div class="grid-row">
<label class="labelBold">Busines Name</label>
<label>#Model.BusinesName</label>
</div>
</div>
From my index page I am trying to call the pv using
#Html.Partial("_BusinessDetails")
which fails so if I add
#Html.Partial("_BusinessDetails",new MyMVC.Models.BusinessModel())
The partial view is loaded however with no data as the controller isn't been hit. In my controller I have tried
public ActionResult _BusinessDetails()
{
return PartialView("_BusinessDetails");
}
public PartialViewResult _BusinessDetails()
{
return PartialView("_BusinessDetails");
}
However neither of them are hit. What have I done wrong?
When rendering a partial view and passing a view model, that view model should already be populated. No controllers/action methods are invoked when using #Html.Partial().
Since you are using this strongly-typed partial view on your home page, consider building its view model in your HomeController's Index() method. Is your index page strongly-typed as well? If so, you can add your partial view's view model as a property of your index page's view model, and pass that when calling #Html.Partial().
On your index page, it would look something like:
#model MyMVC.Models.IndexViewModel
<!-- some HTML here -->
#Html.RenderPartial("_BusinessDetails", Model.BusinessModel)
If your index page is not strongly-typed, you can use the ViewBag object or you can strongly-type it to MyMVC.Models.BusinessModel and use #Html.RenderPartial("_BusinessDetails", Model) (which, while simple, could cause confusion).
Rachel Appel has a nice blog post, as does Mike Brind, if you would like more information.
It's tricky. I've had success with using a model on the main view as a container object:
class MainPageModel {
public BusinessDetailModel BusinessDetails { get; set; }
// ...
}
and then just passing the whole model like #Html.Partial("_BusinessDetails", Model) to my partial views.
When you wrote this,
#Html.Partial("_BusinessDetails",new MyMVC.Models.BusinessModel())
The data is not loaded as your model is empty, so before passing model BusinessModel,fill it before.

Resources