Cannot Display Content In Kendo UI Editor - asp.net-mvc-4

I have a simple class below that I am trying to use to display the Content string in the Editor Kendo Control. I am having issues binding the Property to the Editor. How can I bind the Content String to the Kendo UI Web/MVC Editor using Razor?
public class Details
{
public int TextId { get; set; }
public string Content { get; set; }
}
public List<Details> TextDetails
{
get
{
return mDetails;
}
}
#model MyApp.MyModels.ContentModel
#{
ViewBag.Title = "EditorContent";
}
<h2>Stuff To Display</h2>
#(Html.Kendo().Editor()
.Name("editor")
.Value(Model.TextDetails.Content)
//I thought I could just bind to the property.... How can I show the Content in the Editor?
)

You should do: Model.TextDetails.First().Content, Otherwise everything is fine. As you know Value() requires just a string value and renders as html content, providing appropriate model property (string) shouldn't hurt the editor.

Related

How to bind nullable decimal values

I'm having problems with ASP.NET Core MVC and decimal? value.
I have the following view model:
public class BlobViewModel
{
public int Id { get; set; }
public int? IntegerValue { get; set; }
public string StringValue { get; set; }
[DataType(DataType.Date)]
public DateTime? DateValue { get; set; }
public decimal? DecimalValue { get; set; }
}
And the following input element in my view
<input asp-for="DecimalValue" class="form-control" />
When I enter a decimal value, e.g. "68.5" or "68,5" and tab out of the input element, I get the following error:
The value '68.5' is not valid for DecimalValue.
I have tried with the [DataType(DataType.Currency)] attribute above the property, but I can't seem to get the binding to work. The other properties binds as expected.
Does anyone have an idea for how I accomplish this?
The error you get occurs if you local Windows settings isn't set to US localization and you are using the default asp.net template jquery validation to validate decimal values. The errors should occur irrespective if your decimals are nullable or not
In ASP.NET Core I don't think you can force the localization to US in the web.config as you get in this answer in the same way you can for ASP.NET MVC5 and earlier, so you will have to add javascript to override the jquery.validate.js as mentioned as an answer to the same question.
create a js file called validationlocalization and put it in your wwwroot\js folder with the following contents
$.validator.methods.range = function (value, element, param) {
var globalizedValue = value.replace(",", ".");
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}
$.validator.methods.number = function (value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
}
In the cshtml pages that require decimal validation add a reference to the javascript file to your scripts section. Make sure it is added after an reference to the existing _ValidationScriptsPartial.
#section Scripts {
...
<script src="~/js/validationlocalization.js"></script>
More detail on this workaround

MVC4 - Partial View Model binding during Submit

I have view model which has another child model to render the partial view (below).
public class ExamResultsFormViewModel
{
public PreliminaryInformationViewModel PreliminaryInformation { get; set; }
public string MemberID { get; set; }
public string MemberName { get; set; }
public int PatientID { get; set; }
public string ConfirmationID { get; set; }
public bool IsEditable { get; set; }
#region Select Lists
public SelectList ProviderOptions { get; set; }
#endregion
}
public class PreliminaryInformationViewModel
{
public string ProviderName { get; set; }
public string ProviderID { get; set; }
public string ServiceLocation { get; set; }
}
This PreliminaryInformationViewModel view model also used as a child models in another view model since this preliminary information can be updated at different pages.
So I created this preliminary information as a separate partial and to include in other pages.
#{Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);}
Inside the partial
#model Web.Models.Preliminary.PreliminaryInformationViewModel
<div>
#Html.TextBoxFor(x => x.DateOfService })
</div>
But the problem is during submit this preliminary model is always null due to the reason HTML name attribute is always is rendered as
but when I pass the parent model to the partial as below.
#model Web.Models.Exam.ExamResultsFormViewModel
<div>
#Html.TextBoxFor(x => x.PreliminaryInformation.DateOfService })
</div>
Now the HTML element is generated as
<input type = 'text' name='PreliminaryInformation.DateOfService.DateOfService' id='PreliminaryInformation.DateOfService'>
and it binds properly during the submit.
I understand MVC bind the element value based on the name attribute value, but the second implementation would need me to create a multiple partial for each page, which I don't like.
So far I couldn't find a solution to work with the first implementation, is there way I can make preliminary information model value bind during submit with the first implementation.
I know its a bit late but it might help to someone
If you have complex model, you can still pass it into partial using:
#Html.Partial("_YourPartialName", Model.Contact, new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "Contact"
}
})
where I have defined model with property "Contact". Now what HtmlFieldPrefix do is add the property binding for each model "so the model binder can find the parent model"
There is a blog post about it: http://www.cpodesign.com/blog/bind-partial-view-model-binding-during-submit/
.NET Core 2 binding
In .NET Core 2 and MVC the answer above will not work, the property is no longer settable.
How ever the solution is very similar.
#{ Html.ViewData.TemplateInfo.HtmlFieldPrefix = "Contact"; }
#await Html.PartialAsync("_YourPartialName", Model.Contact)
after you can submit your model, it will bind again.
Hope that helps
You can add the HtmlFieldPrefix to the top of your partial view:
#{
ViewData.TemplateInfo.HtmlFieldPrefix = "Contact";
}
This is the same approach as that described by #cpoDesign but it means you can keep the prefix in your partial view if you need to do that.
You need to create an editor template for PreliminaryInformationViewModel to replace the partial view, then call with Html.EditorFor( m => m.PreliminaryInformation ). Reference this solution. Creating the template should be as simple as moving your partial view to the Views/Shared/EditorTemplates directory. Html.EditorFor(...) will automatically use this template based on the type you're passing in as the model (in this case, PreliminaryInformationViewModel)
I also ran into this problem. I will explain my solution using your code. I started with this:
#{
Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);
}
The action corresponding to the http post was looking for the parent model. The http post was submitting the form correctly but there was no reference in the child partial to the parent partial. The submitted values from the child partial were ignored and the corresponding child property remained null.
I created an interface, IPreliminaryInfoCapable, which contained a definition for the child type, like so:
public interface IPreliminaryInfoCapable
{
PreliminaryInformationViewModel PreliminaryInformation { get; set; }
}
I made my parent model implement this interface. My partial view then uses the interface at the top as the model:
#model IPreliminaryInfoCapable
Finally, my parent view can use the following code to pass itself to the child partial:
#{
Html.RenderPartial("ChildPartial", Model);
}
Then the child partial can use the child object, like so:
#model IPreliminaryInfoCapable
...
#Html.LabelFor(m => m.PreliminaryInformation.ProviderName)
etc.
All of this properly fills the parent model upon http post to the corresponding action.
Quick Tip: when calling your EditorFor method, you can set the name of the template as a parameter of the Html.EditorFor method. Alternatively, naming conventions can be your friend; just make sure your editor template filename is exactly the same name as the model property type
i.e. model property type 'CustomerViewModel' => 'CustomerViewModel.cshtml' editor template.
Please make the below changes to your partial page. so it will come with your Parent model
//Parent Page
#{Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);}
//Partial Page
#model Web.Models.Preliminary.PreliminaryInformationViewModel
#using (Html.BeginCollectionItem("PreliminaryInformation", item.RowId, true))
{
<div>
#Html.TextBoxFor(x => x.DateOfService })
</div>
}
For .net core 2 and mvc, use do like below:
#{
Html.ViewData.TemplateInfo.HtmlFieldPrefix = "Contact";
}
#await Html.PartialAsync("_YourPartialViewName", Model.Contact)

editorfor picks string template instead of double

I'm having some issues with a view model in my project that contains an number of doubles in them
ie.
public class MyViewModel
{
public double Left { get; set; }
public double Right { get; set; }
public double Top { get; set; }
public double Bottom { get; set; }
}
In my view I have
#Html.EditorForModel
If there is no other custom templates in my project this renders correctly and I get a textbox with a double on in it.
As soon as I put a string template in View/Shared/EditorTemplate and put anything inside of it whatever is in that template gets rendered instead of the double template.
I would have thought that even though I have overriden the string template the order for selecting templates would remain the same, and the double template would be choosen as it was originally before the string template existed.
The string template consisted of only (no #model )
<h2>String</h2>
Am I missing something here, why is the string template choosen here?
I've determined I can put a double template in the views shared folder and it will render that instead but it seems like I shouldn't have to do that.
EDIT:
As per Darin's answer I created my own double editortemplate based on the decimal template.
#using System.Globalization
#functions {
private object FormattedValue
{
get
{
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model)
{
return String.Format(CultureInfo.CurrentCulture, "{0:0.00}", ViewData.ModelMetadata.Model);
}
return ViewData.TemplateInfo.FormattedModelValue;
}
}
}
#Html.TextBox("", FormattedValue, new {#class = "text-box single-line"})
Am I missing something here, why is the string template choosen here?
In both cases it's the String template being chosen. There's no default template for the double type. Here's how the default string template looks like:
#Html.TextBox(
"",
ViewData.TemplateInfo.FormattedModelValue,
new { #class = "text-box single-line" }
)
I've determined I can put a double template in the views shared folder
and it will render that instead but it seems like I shouldn't have to
do that.
Well, if you are not satisfied with the default template for the double type (which is string.cshtml) you could always write a custom template for it.

Kendo UI Grid displays [object Object]

I have a class
public class LookupClass {
public int Id { get; set; }
public string Name { get; set; }
}
That I have referenced in another class
public class Sampleclass {
public int Id { get; set; }
public LookupClass LookupEntry { get; set; }
}
which is is displayed in a KendoUI Grid
#(Html.Kendo().Grid<SampleClass>()
.Name("SomeGrid")
.Columns(cols => {
cols.Bound(o => o.LookupEntry).Title("Lookup Column") // Displays [object Object]
cols.Bound(o => o.LookupEntry.Name) // displays name correctly
}
.DataSource(datasource =>
// leaving this out since the data is seems to be loading correctly.
)
)
When displaying the grid it just displays [object Object] for the value in the cells in the "Lookup Column" column. I have gotten the editor template working (leaving out code since not necessary, basically copied from here) and saving/loading works (left out for simplicity), but I can't seem to figure out how to display the Name property from the Lookup class.
Found a KendoUI example that shows how to do this (http://demos.kendoui.com/web/grid/editing-custom.html)
Basically you have to use a ClientTemplate to display the property you want to display
#(Html.Kendo().Grid<SampleClass>()
.Name("SomeGrid")
.Columns(cols => {
cols.Bound(o => o.LookupEntry).ClientTemplate("#=LookupEntry.Name#").Title("Lookup Column")
}
)
On a side note, if you try to create a new record, it will produce an error about not finding LookupEntry (don't remember exact message). In the example listed, there is also a bit in the model section that shows how to set a default object.

Can I get a SelectList in my view model to render using EditorForModel?

I would like have a listbox of states render using the EditorForModel Html helper.
My view model:
public class MyViewModel
{
public MyewModel()
{
States = new SelectList(MyModel.RegionsToSelectList,"Value","Text");
}
[DataType(DataType.Text)]
public string City { get; set; }
[Display(Name = "States")]
public SelectList States { get; private set; }
}
In my view I have #Html.EditorForModel()
The City renders properly but the States do not render into any sort of list (dropdown or listbox)
If I use #Html.DropDownList("mylistname", Model.States) it renders properly.
I would really like to have it render in the ForModel process.
Can this be done?
You need to use the Html.DropdownListFor helper if you want to generate a drop down list. The fact that you have used SelectList as type to some of your properties doesn't mean that the default editor template will render a box. So you will have to write a custom editor template.
You may take a look at the following blog post to see how those default templates are implemented.