Display text array using UmbracoHelper - c#

I can't figure out how to display a text array in Umbraco. I'm trying to show values from a "Repeatable Text String" property in a razor view.
I have an Umbraco view set up which passes through a model like so:
#inherits Umbraco.Web.Mvc.UmbracoViewPage<MyModel>
This means that I can't access umbraco fields through Model.someVariable the normal way. Instead, I have been using UmbracoHelper to display text content like this:
#Umbraco.Field("mainColour")
But this doesn't work with the "repeatable text strings" property type, as .Field() converts it to an IHtmlString.
How can I display all the text strings on the page?

Is your model a ModelsBuilder model? If so, you should be able to do:
#Model.Content.GetPropertyValue("mainColour")
To turn the property into an array of strings, that syntax can be altered to:
#(Model.Content.GetPropertyValue<IEnumerable<string>>("mainColour"))
You may need to install the Core Property values converter to get that to work.

Here is the Hack-ish solution that I went with.
We use a controller (extending Umbraco.Web.Mvc.RenderMvcController) to render MyModel for the page.
I realized that, in the controller I can use CurrentPage to get the data, and place it in the ViewBag to display. So in order to display the array of tick points:
ViewBag.tickPoints = CurrentPage.GetPropertyValue<string[]>("tickPoints");

Related

MVC Dropdownlist not selecting value when passing SelectList instead of full-auto for Title property

I have a MVC 5 application using a lot of the standard features. I have a number of dropdownlists across the app that render properly, except for one.
In the Controller:
ViewBag.TitleLookup = new SelectList(db.TitleLookups, "Title", "Title", person.Title);
return View(person);
In the View:
#Html.DropDownList("Title",(SelectList)ViewBag.TitleLookup,string.Empty)
#Html.DropDownList("TitleLookup", string.Empty)
Both dropdown lists render the options properly, however, the first does not have the properly selected item. The second has the wrong Name so would not be submitted to the server on a post, however it did have the "valid" property indicating the validation was active.
I have stepped through the controller and the SelectListItems are getting built correctly along with the selected property on the proper Item getting set to True.
So to ask a concrete question: Why does the first dropdownlist not render the proper selected item? Is there indeed something crazy about having the property called "Title"?
I can change the datamodel if I absolutely have to, but feels like it should be able to work without doing that.
It looks like you have put in "Title" for the second and third parameters on the select list. Those parameters are for complex objects to select those properties, say Key and Value if you're binding to a dictionary (I'm assuming db.TitleLookups is a list of strings). Instead, try this:
new SelectList(db.TitleLookups, person.Title);
In addition, MVC might have issues with controls named after a ViewData/ViewBag property. See: ASP.NET MVC Html.DropDownList SelectedValue

MVC - Refresh View Model asynchronously via AJAX + Controller?

I've been working on filtering a list of log entries, and I'm getting close to being complete.
I'm wondering if it's possible to update the current View's model asynchronously via $.ajax().
I currently have the $.ajax() working, however it returns the entire page's HTML as opposed to a partial view, or a model itself.
Is anybody aware of a way to simply update the model on the current view?
You'd have to return the model in json format and use js templating
functionality to replace the server rendered html in the dom. –
WestDiscGolf
The above is the solution, so I'll keep it simple and use a more conventional method.
This concept doesn't really make sense. The model doesn't really exist any more once the page is rendered, until it is reinstantiated on the following POST (assuming it is reinstantiated, i.e. your controller action accepts an argument of the same type). In the meantime, it is just manifested as form fields with name properties that correspond to what were the model's properties.
You can, however, dynamically create form fields that will (if possible) be mapped back to model properties again when the form is posted.
Create a field, whose name property matches the name of your model property:
<input type="hidden" id="hdnMyProperty" name="MyProperty" />
Then use jQuery to populate the field's value:
var property = /* Your returned value here */;
$('#hdnMyProperty').val(property);
There are a couple of common ways of achieving this:
Make an AJAX request to a controller action that returns a JsonResult and dynamically create the form field(s) in your Javascript (potentially - as has been mentioned - utilizing something like Knockout).
Create a controller action that returns a PartialViewResult and dynamically insert the returned markup in the appropriate place.
When you issue the next post request, the model binder will try to map this to an appropriate property in the newly-instantiated model.
You could simply use Knockout. No need to re-invent the wheel in this case.

Unable to change value of a text box in ASP.NET MVC 3

I am having an issue changing the value of a text box in MVC 3.
I have a simple view that is returned by a controller and is typed to a custom view model. There is a text box on the view that is bound to a string property on the view model. If I populate this string on initial load then the text box value contains the value of the string. However, if I then post a form back to the same URL and change the view model string value and reload the view then the text box contains the value that was posted back, not the value that the controller supplied for the view model.
I created a simple test project to recreate the issue in the simplest way possible.
View Model:
http://www.codetunnel.com/content/images/textboxproblem/ViewModel.jpg
Controller:
http://www.codetunnel.com/content/images/textboxproblem/Controller.jpg
View:
http://www.codetunnel.com/content/images/textboxproblem/View.jpg
In the view I display the view model string value and I also bind the string property to a text box.
On initial load everything looks fine:
http://www.codetunnel.com/content/images/textboxproblem/InitialLoadTest.jpg
However, if I change the value of the text box and then press enter to POST the form things do not happen as I expected. The displayed value is the value the controller set in the action method, but the text box retains the value that was posted back:
http://www.codetunnel.com/content/images/textboxproblem/POSTTest.jpg
I'm not sure what the problem is.
That is (unfortunately) the correct behavior. When using TextBoxFor or other data-bound elements, the created element is first bound against the existing ModelState, before it is bound against the model.
The solution is to clear the ModelState in your [HttpPost] action, so that the elements in the View returned by the POST action will be bound against the model. In your POST action, add the following:
ModelState.Clear();
Personally, I think the design is incorrect, but clearing ModelState will give you the behavior you expected.
That is the expected behaviour of an MVC application.
When you make a post it stored the value in the ModelState and the Html helpers use that value instead of the Model value.
You can write you're own html helper or use a standard html <input/> to work around this if needed.

ASP.NET MVC UpdateModel binding with a Hierarchy of Collections

I have the following Model design.
Template contains a list of Categories.
Categories contains a List of Items.
Thus there is 3 layer hierarchy. Because the UI design requires that all 3 levels be created on 1 page, I have had to write some of my own code to get this working. It looks as follows:
I can get it to submit back to the Create Action Method and the FormCollection looks as follows.
The problem I am having is that the UpdateModel works for the Template and Category level but the Items are not populated for the Categories. The Html looks as follows. As you can see, I have used the Category[guid_value].Items[guid_value] syntax for id. Shouldn't it figure out the binding automagically based on that?
Is there something I am missing or have to do in order to get the binding to work?
if you want your html to bind correctly to your model you have to pay some attention to html you render. The problem that i can see with your html is
<input type='hidden' value = 'Items.Index' value= 'some_guid' autocomplete = 'off'/>
with this html model binder will try to bind Items as children of Template object where it will not find any property named Items and these values will not be bound to the model. you have to change your hidden field to
<input type='hidden' name = 'Categories[category's guid].Items.Index' value = 'some guid' autocomplete = 'off'/>
and you have to just call updatemodel in your action method like
UpdateModel(yourobject);
i have not tested this code but i am more than certain that changing your html this way will get you sorted.
#Mlchael Grassman you don't have to use integer based id's to bind collection anymore. plz read steve's post for more information. Actually you don't need GUID either but a random number that is unique in page's context provided that you put an extra hidden field with name index and value set to above mentioned random number. I have blogged about Master detail form in asp.net mvc using (and modifying) BeginCollectionItem method written by Steve. in part one of this blog series i simply showed how you can dynamically add fields of your detail record on client side without ajax call. In second part i brought the editor template of detail record to jquery templating engine and rendering it on client side as it would appear if rendered through ajax call.
By default MVC uses the following convention for naming.
Category[0].Items[0]
Category[0].Items[1]
Category[1].Items[0]
Category[1].Items[1]
You can include your own Update by using the following TryUpdateModel. This woud probably need some sort of loop but should get you started.
TryUpdateModel(Category[Guid].Items[Guid], "Category[Guid].Items[Guid]", null, new string[] { "ExcludedPropery1", "ExcludedPropery2", "ExcludedProperyN", });

Can I have multiple display templates for an object in ASP.NEt MVC 3?

Is it possible to have multiple display templates for the same object in asp.net mvc?
In my situation I have a Comment object. I would like to use DisplayFor to automatically loop throught an IEnumerable in my view and display the proper template for each item. This works great. Now say I have another view where I also need to display a list of comments in the same manner...But I wants these comments to be editable by the user.
So basically, Can I have 2 display templates, one for read-only display and one for editable display(or other similar scenarios)?
You are looking for EditorTemplate
You could also specify the templateName in the DisplayFor methods.

Categories