I've been using Editor-Templates in the past like this, by applying the following data annotation:
[UIHint("SomeTemplate")]
ViewModel:
public class MicroViewModel { public IEnumerable<LabMicro> Micros { get; set; } [UIHint("DateTime")] public DateTime Date { get; set; } public int CaseNo { get; set; } [UIHint("SampleTypes")] public int LabSampleTypeID { get; set; } [UIHint("SampleDetails")] public int LabSampleDetailID { get; set; } }
If I wanted to use a specific date picker control as opposed to the regular one, it can be implemented as follows.
Example:
@model DateTime? @Html.TextBox("", String.Format("{0:yyyy-MM-dd}", Model.HasValue ? Model : DateTime.Today), new { @class = "dp", style="width:100px" }) <script type="text/javascript"> $(document).ready(function () { $(".dp").datepicker({ changeMonth: true, changeYear: true, dateFormat: 'yy-mm-dd' }); }); </script>
For my ID fields, I'd like to make use of the jQuery auto-complete component.
Question:
How would I go about passing additional parameters to the UIHint
partial view for LabSampleTypeID
and LabSampleDetailID
? (As Id like to have an auto-complete Editor-Template that'll take a URL and property names for example)
What I think my auto-complete Editor-Template/Partial should look like:
$(".auto").autocomplete({ source: function(request, response) { $.ajax({ url: '[#URL_TO_USE]', dataType: "json", data: { filter: request.term }, success: function(data) { response($.map(eval(data), function(item) { return { label: item.[#PROPERTY_TO_USE] } })); } }) } });
You could use the AdditionalMetadata
attribute:
[UIHint("DateTime")] [AdditionalMetadata("foo", "bar")] public DateTime Date { get; set; }
and in the template:
@ViewData.ModelMetadata.AdditionalValues["foo"]
so if you wanted to pass an url:
[UIHint("DateTime")] [AdditionalMetadata("controller", "somecontroller")] [AdditionalMetadata("action", "someaction")] [AdditionalMetadata("property", "someproperty")] public DateTime Date { get; set; }
and in your template:
@{ var values = ViewData.ModelMetadata.AdditionalValues; } <script type="text/javascript"> $('.auto').autocomplete({ source: function (request, response) { $.ajax({ url: '@Url.Action((string)values["action"], (string)values["controller"])', dataType: "json", data: { filter: request.term }, success: function (data) { response( $.map(eval(data), function (item) { return { label: item['@values["property"]'] } }) ); } }); } }); </script>
You could use the UHint without AdditionalMetadata attribute, but some additional code is requred
[UIHint("DateTime", null, "key1", "value1", "key2", "value2")] public DateTime Date { get; set; }
override CreateMetadata:
public class CustomMetadataProvider : DataAnnotationsModelMetadataProvider { public const string UiHintControlParameters = "UiHintControlParameters"; protected override ModelMetadata CreateMetadata( IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) { ModelMetadata metadata = base.CreateMetadata( attributes, containerType, modelAccessor, modelType, propertyName); IEnumerable<UIHintAttribute> uiHintAttributes = attributes.OfType<UIHintAttribute>(); UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => string.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase)) ?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer)); if (uiHintAttribute != null) { metadata.AdditionalValues.Add(UiHintControlParameters, uiHintAttribute.ControlParameters); } return metadata; }
Register CustomMetadataProvider:
public static void Application_Start() { ModelMetadataProviders.Current = new CustomMetadataProvider(); }
and in your template:
@{ IDictionary<string, object> values = (IDictionary<string, object>) ViewData.ModelMetadata.AdditionalValues[CustomMetadataProvider.UiHintControlParameters]; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With