public static IHtmlContent oTextBoxFor <TModel, TProperty>(this HtmlHelper <TModel> html, Expression <Func <TModel, TProperty> > expression, IDictionary <string, object> htmlAttributes = null, bool readOnly = false, bool sublist = false, bool inputGroup = false, bool isGuide = false, string guideUrl = "") { var outerDiv = new TagBuilder("div"); var label = new TagBuilder("label"); var labelAttributes = new Dictionary <string, object>(); outerDiv.AddCssClass("form-group"); labelAttributes.Add("class", "control-label col-xs-12"); if (!sublist) { labelAttributes.Add("class", "control-label col-xs-12 col-sm-4 col-md-4 col-lg-3"); } var labelText = html.LabelFor(expression, labelAttributes).ToString(); label.InnerHtml.AppendHtml(labelText); var innerDiv = new TagBuilder("div"); innerDiv.AddCssClass("col-xs-12"); if (!sublist) { innerDiv.AddCssClass("col-xs-12 col-sm-8 col-md-8 col-lg-9"); } var summaryDiv = new TagBuilder("div"); var small = new TagBuilder("small"); var span = new TagBuilder("span"); summaryDiv.AddCssClass("error-summary"); summaryDiv.InnerHtml.AppendHtml(small.InnerHtml); summaryDiv.InnerHtml.AppendHtml(summaryDiv.ToString()); span.AddCssClass("field-validation-valid"); span.InnerHtml.AppendHtml(html.ValidationMessageFor(expression).ToString()); small.InnerHtml.AppendHtml(span.InnerHtml); small.InnerHtml.AppendHtml(small.ToString()); if (htmlAttributes == null) { htmlAttributes = new Dictionary <string, object>(); } var oMetaData = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider); if (oMetaData == null) { if (readOnly) { if (!htmlAttributes.ContainsKey("readonly")) { htmlAttributes.Add("readonly", "read-only"); } } } else { if (!htmlAttributes.ContainsKey("placeholder")) { var fieldName = ExpressionHelper.GetExpressionText(expression); var placeholder = oMetaData.Metadata.DisplayName ?? oMetaData.Metadata.PropertyName ?? fieldName.Split('.').Last(); if (!string.IsNullOrWhiteSpace(placeholder)) { htmlAttributes.Add("placeholder", placeholder); } if (readOnly || oMetaData.Metadata.IsReadOnly) { if (!htmlAttributes.ContainsKey("readonly")) { htmlAttributes.Add("readonly", "read-only"); } } } } var oExpression = expression.Body as MemberExpression; if (oExpression != null) { var strLengthAttribute = oExpression.Member .GetCustomAttributes(typeof(StringLengthAttribute), false) .FirstOrDefault() as StringLengthAttribute; if (strLengthAttribute != null) { if (!htmlAttributes.ContainsKey("maxlength")) { htmlAttributes.Add("maxlength", strLengthAttribute.MaximumLength); } } } if (htmlAttributes.ContainsKey("date")) { var inputGroupDiv = new TagBuilder("div"); inputGroupDiv.AddCssClass("input-group date"); var spanDate = new TagBuilder("span"); spanDate.AddCssClass("input-group-addon input-pe-disabled"); var spanIcon = new TagBuilder("span"); spanIcon.AddCssClass("fa fa-calendar input-pe-disabled"); spanIcon.InnerHtml.AppendHtml(spanIcon.ToString()); spanDate.InnerHtml.AppendHtml(spanIcon.InnerHtml); spanDate.InnerHtml.AppendHtml(spanDate.ToString()); inputGroupDiv.InnerHtml.AppendHtml(spanDate.InnerHtml + (html.TextBoxFor(expression, htmlAttributes)).ToString()); innerDiv.InnerHtml.AppendHtml(inputGroupDiv.ToString() + summaryDiv.InnerHtml); outerDiv.InnerHtml.AppendHtml(labelText + innerDiv.ToString()); } else { var sp = expression.Body.ToString().Split('.'); var id = string.Empty; for (int i = 0; i < sp.Length; i++) { if (i > 0) { id += sp[i]; if (i < sp.Length - 1) { id += "_"; } } } innerDiv.InnerHtml.AppendHtml((inputGroup ? "<div class='input-group'>" : "") + html.TextBoxFor(expression, htmlAttributes) + (inputGroup ? "<span class='input-group-btn'><button class='btn btn-primary" + (isGuide ? " openGuide" : "") + "' type='button' " + (isGuide ? " data-href='" + guideUrl + "'" : "") + " id='groupBtn_" + id + "'><i class='fa fa-search'></i></button></span></div>" : "") + summaryDiv.InnerHtml); outerDiv.InnerHtml.AppendHtml(labelText + innerDiv.ToString()); } return(outerDiv); }
public static HtmlString ngTextBoxFor <TModel, TProperty>(this IHtmlHelper <TModel> html, Expression <Func <TModel, TProperty> > expression, IDictionary <string, object> htmlAttributes) { var helper = html as AngularHtmlHelper <TModel>; if (helper == null) { throw new InvalidOperationException("You need to configure the services container to return AngularHtmlHelper<T> for IHtmlHelper<T>."); } var expressionText = ExpressionHelper.GetExpressionText(expression); var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, helper.ViewData, helper.ModelMetadataProvider); var ngAttributes = new Dictionary <string, object>(); // Angular binding to client-side model (scope). This is required for Angular validation to work. ngAttributes["ng-model"] = html.ViewData.TemplateInfo.GetFullHtmlFieldName(expressionText); // Set input type if (string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.EmailAddress), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "email"; } else if (metadata.ModelType == typeof(Uri) || string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.Url), StringComparison.OrdinalIgnoreCase) || string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.ImageUrl), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "url"; } else if (IsNumberType(metadata.ModelType)) { ngAttributes["type"] = "number"; if (IsIntegerType(metadata.ModelType)) { ngAttributes["step"] = "1"; } else { ngAttributes["step"] = "any"; } } else if (metadata.ModelType == typeof(DateTime)) { if (string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.Date), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "date"; } else if (string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.DateTime), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "datetime"; } } // Add attributes for Angular validation //var clientValidators = metadata.GetValidators(html.ViewContext.Controller.ControllerContext) // .SelectMany(v => v.GetClientValidationRules()); var clientValidators = helper.GetClientValidators(null, metadata); foreach (var validator in clientValidators) { if (string.Equals(validator.ValidationType, "length")) { if (validator.ValidationParameters.ContainsKey("min")) { ngAttributes["ng-minlength"] = validator.ValidationParameters["min"]; } if (validator.ValidationParameters.ContainsKey("max")) { ngAttributes["ng-maxlength"] = validator.ValidationParameters["max"]; } } else if (string.Equals(validator.ValidationType, "required")) { ngAttributes["required"] = null; } else if (string.Equals(validator.ValidationType, "range")) { if (validator.ValidationParameters.ContainsKey("min")) { ngAttributes["min"] = validator.ValidationParameters["min"]; } if (validator.ValidationParameters.ContainsKey("max")) { ngAttributes["max"] = validator.ValidationParameters["max"]; } } else if (string.Equals(validator.ValidationType, "equalto")) { // CompareAttribute validator var fieldToCompare = validator.ValidationParameters["other"]; // e.g. *.NewPassword var other = validator.ValidationParameters["other"].ToString(); if (other.StartsWith("*.")) { // The built-in CompareAttributeAdapter prepends *. to the property name so we strip it off here other = other.Substring("*.".Length); } ngAttributes["app-equal-to"] = other; // TODO: Actually write the Angular directive to use this } // TODO: Regex, Phone(regex) } // Render! return(html.TextBoxFor(expression, null, MergeAttributes(ngAttributes, htmlAttributes))); }
private static IDictionary <string, object> getDefaultAttributes <TModel, TResult>(IHtmlHelper <TModel> htmlHelper, Expression <Func <TModel, TResult> > expression) { ModelExplorer modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, htmlHelper.ViewData, htmlHelper.MetadataProvider); return(getDefaultAttributes <TModel, TResult>(htmlHelper, modelExplorer.Metadata.IsRequired)); }
/// <inheritdoc /> public string DisplayText(string expression) { var modelExplorer = ExpressionMetadataProvider.FromStringExpression(expression, ViewData, MetadataProvider); return(GenerateDisplayText(modelExplorer)); }
public static HtmlString ComboBoxFor <TModel, TValue>(this IHtmlHelper <TModel> html, Expression <Func <TModel, TValue> > expression, IEnumerable <SelectListItem> items = null, string optionLabel = null, object htmlAttributes = null, string dataUrl = null) { var select = new TagBuilder("select"); if (!dataUrl.IsEmpty()) { select.Attributes.Add("data-url", dataUrl); } if (htmlAttributes != null) { select.MergeAttributes(new RouteValueDictionary(htmlAttributes)); } var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider); var htmlFieldName = ExpressionHelper.GetExpressionText(expression); var labelText = metadata.Metadata.DisplayName ?? metadata.Metadata.PropertyName ?? htmlFieldName.Split('.').Last(); if (items == null) { var comboDataInfo = GetComboBoxDataSource(metadata); items = comboDataInfo.ListItems; if (comboDataInfo.CanSelect) { optionLabel = "SELECT"; } else { optionLabel = null; } } select.Attributes.Add("name", htmlFieldName); select.Attributes.Add("class", "form-control input-sm"); select.GenerateId(htmlFieldName, "_"); var sb = new StringBuilder(); if (!optionLabel.IsEmpty()) { sb.AppendLine(string.Concat("<option value=\"\">", optionLabel, "</option>")); } if (items != null) { foreach (var item in items) { var option = new TagBuilder("option"); option.Attributes.Add("value", html.Encode(item.Value)); if (item.Selected) { option.Attributes.Add("selected", "selected"); } option.InnerHtml.SetHtmlContent(item.Text); sb.AppendLine(option.GetString()); } } select.InnerHtml.SetHtmlContent(sb.ToString()); return(new HtmlString(string.Format(@"<div class=""form-group""> <label class=""col-sm-3 control-label"">{0}</label> <div class=""col-sm-8""> {1} </div> </div>", labelText, select.GetString()))); }
public static IHtmlContent RequiredCheckbox <TModel>(this IHtmlHelper <TModel> html, Expression <Func <TModel, bool> > expression) { var fieldName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression)); var hasErrors = html.ViewData.ModelState[fieldName]?.Errors != null && html.ViewData.ModelState[fieldName].Errors.Any(); var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider).Metadata; //var label = new TagBuilder("span"); //label.AddCssClass("body-text"); //label.InnerHtml = metadata.Description; return(new HtmlContentBuilder() .AppendHtml(hasErrors ? "<div class='form-group form-group-error'>" : "<div class='form-group'>") .AppendHtml("<fieldset>") .AppendHtml($"<legend id='{GenerateLegendId(html, expression)}'>") .AppendHtml("<span class=\'error-message\'>") .AppendHtml(html.ValidationMessageFor(expression)) .AppendHtml("</span>") .AppendHtml("</legend>") .AppendHtml("<div class=\'multiple-choice\'>") .AppendHtml(html.CheckBoxFor(expression)) .AppendHtml(html.LabelFor(expression, metadata.Description, new { })) .AppendHtml("</div>") .AppendHtml("</fieldset>") .AppendHtml("</div>")); //var errorMsg = new TagBuilder("span"); //errorMsg.AddCssClass("error-message"); //errorMsg.InnerHtml.Append(.ToString()); //var legend = new TagBuilder("legend"); //legend.Attributes.Add("id", GenerateLegendId(html, expression)); //legend.InnerHtml.Append($"{errorMsg}"); //var checkbox = html.CheckBoxFor(expression); //var cbx = html.CheckBoxFor(expression); //var lbl = ; //var div = new TagBuilder("div"); //div.AddCssClass("multiple-choice"); //div.InnerHtml.Append($"{lbl}{cbx}"); //var fieldset = new TagBuilder("fieldset"); //fieldset.InnerHtml.Append($"{legend}{div}"); //var parent = new TagBuilder("div"); //parent.AddCssClass("form-group"); //parent.InnerHtml.Append(fieldset.ToString()); //if (hasErrors) //{ // parent.AddCssClass("form-group-error"); //} //return new HtmlString(parent.ToString()); }
/// <inheritdoc /> public string DisplayName(string expression) { var metadata = ExpressionMetadataProvider.FromStringExpression(expression, ViewData, MetadataProvider); return(GenerateDisplayName(metadata, expression)); }
public IHtmlContent FormGroupFor <TProp>(Expression <Func <TModel, TProp> > property, bool showLabel = true, int xs = 0, int sm = 0, int md = 0, int lg = 0, int xl = 0, string dependentBinding = null, string typeAhead = null) { var metadata = ExpressionMetadataProvider.FromLambdaExpression(property, new ViewDataDictionary <TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()), Helper.MetadataProvider); Type propertyType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType; var name = Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ExpressionHelper.GetExpressionText(property); var expression = ExpressionForInternal(property); var touched = ExpressionForFormFieldTouched(property); var valid = ExpressionForFormFieldTouched(property); var submitted = ExpressionForFormSubmitted(); var formGroup = CommonFormGroupFor(property, showLabel, xs, sm, md, lg, xl, dependentBinding); var labelText = metadata.Metadata.DisplayName; if (propertyType.IsEnum && !showLabel) { IEnumerable <Object> enumValues = Enum.GetValues(propertyType).Cast <Object>(); IEnumerable <SelectListItem> items = from enumValue in enumValues select new SelectListItem { Text = GetText(enumValue), Value = ((Int32)enumValue).ToString(), Selected = enumValue.Equals(metadata.Model) }; int i = 0; foreach (SelectListItem item in items) { var radioLabel = new HtmlTag("label") .AddClass("form-check-inline"); var input = new HtmlTag("input") .AddClasses("form-check-input") .Attr("ng-model", expression) .Attr("name", name) .Attr("value", item.Value) .Attr("type", "radio"); radioLabel.Append(input).AppendHtml(" " + item.Text); formGroup.Append(radioLabel); i++; } } else if (propertyType.IsEnum && showLabel) { var select = new HtmlTag("select").AddClass("form-control") .Attr("ng-model", expression) .Attr("name", name); formGroup.Append(select); IEnumerable <Object> enumValues = Enum.GetValues(propertyType).Cast <Object>(); IEnumerable <SelectListItem> items = from enumValue in enumValues select new SelectListItem { Text = GetText(enumValue), Value = ((Int32)enumValue).ToString(), Selected = (metadata.Model != null && enumValue.Equals(metadata.Model)) }; int i = 0; foreach (SelectListItem item in items) { var option = new HtmlTag("option") .Attr("value", item.Value) .AppendHtml(item.Text); if (i == 0) { option.Attr("selected"); } select.Append(option); i++; } } else if (metadata.ModelType == typeof(Boolean)) { var checkLabel = new HtmlTag("label") .AddClass("form-check-inline"); var input = new HtmlTag("input") .AddClasses("form-check-input") .Attr("ng-model", expression) .Attr("name", name) .Attr("value", false) .Attr("type", "checkbox"); checkLabel.Append(input).AppendHtml(" " + labelText); formGroup.Append(checkLabel); } else { formGroup .Attr("form-group-validation", name); string tagName = "input"; switch (metadata.Metadata.DataTypeName) { case "MultilineText": case "Html": tagName = "textarea"; break; } var placeholder = metadata.Metadata.Placeholder ?? ((metadata.Metadata.DisplayName) + "..."); //Creates <input ng-model="expression" // class="form-control" name="Name" type="text" > var input = new HtmlTag(tagName) .AddClasses("form-control", "form-control-success", "form-control-danger") .Attr("ng-model", expression) .Attr("name", name) .Attr("type", "text") .Attr("placeholder", placeholder); if (typeAhead != null) { input.Attr("typeahead", typeAhead); input.Attr("ng-model-options", "{debounce: {default: 500, blur: 250 }, getterSetter: true}"); input.Attr("typeahead-editable", "false"); input.Attr("typeahead-min-length", "0"); input.Attr("autocomplete", "off"); } ApplyValidationToInput(input, metadata.Metadata, name, submitted, touched, valid); formGroup .Append(input); } ApplyHelpToFormGroup(formGroup, metadata.Metadata); return(formGroup); }
private HtmlTag CommonFormGroupFor <TProp>(Expression <Func <TModel, TProp> > property, bool showLabel = true, int xs = 0, int sm = 0, int md = 0, int lg = 0, int xl = 0, string dependentBinding = null) { var metadata = ExpressionMetadataProvider.FromLambdaExpression(property, new ViewDataDictionary <TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()), Helper.MetadataProvider); Type propertyType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType; var name = Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ExpressionHelper.GetExpressionText(property); var expression = ExpressionForInternal(property); var touched = ExpressionForFormFieldTouched(property); var valid = ExpressionForFormFieldTouched(property); var submitted = ExpressionForFormSubmitted(); //Creates <div class="form-group has-feedback" // form-group-validation="Name"> var formGroup = new HtmlTag("div") .AddClasses("form-group"); if (xs != 0) { formGroup.AddClass("col-" + xs.ToString()); } else { formGroup.AddClass("hidden-xs-down"); } if (sm != 0) { formGroup.AddClass("col-sm-" + sm.ToString()); } else { formGroup.AddClass("hidden-sm-down"); } if (md != 0) { formGroup.AddClass("col-md-" + md.ToString()); } else { formGroup.AddClass("hidden-md-down"); } if (lg != 0) { formGroup.AddClass("col-lg-" + lg.ToString()); } else { formGroup.AddClass("hidden-lg-down"); } if (xl != 0) { formGroup.AddClass("col-xl-" + xl.ToString()); } else { formGroup.AddClass("hidden-xl-down"); } if (dependentBinding != null) { formGroup.Attr("ng-hide", "!" + dependentBinding); } var labelText = metadata.Metadata.DisplayName; //Creates <label class="form-control-label" for="Name">Name</label> var label = new HtmlTag("label") .AddClass("col-form-label") .Attr("for", name) .Text(labelText); if (!showLabel) { label.AddClass("sr-only"); } formGroup .Append(label); return(formGroup); }
/// <summary> /// Generates the html for a grid of checkboxes /// </summary> /// <typeparam name="TModel">The type of the model</typeparam> /// <typeparam name="T">The type enumerations. the of simple value types is recommended</typeparam> /// <param name="htmlHelper"></param> /// <param name="expression">The lambda expression resunting in an enumeration of Ts</param> /// <param name="items">The list of available options</param> /// <param name="htmlAttributes">A object whose properties will become attibutes of the resulting html container element</param> /// <param name="cols">The number of columns to generate. Accepts values between 1 and 12.</param> /// <returns></returns> public static HtmlString MultiSelect <TModel, T> ( this IHtmlHelper <TModel> htmlHelper, Expression <Func <TModel, IEnumerable <T> > > expression, IEnumerable <SelectListItem> items, object htmlAttributes, int cols = 1) { cols = (cols < 1 || cols > 12) ? 1 : cols; ModelExplorer modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, htmlHelper.ViewData, htmlHelper.MetadataProvider); StringBuilder strBuilder = new StringBuilder(modelExplorer.Metadata.Name); while (modelExplorer.Container.Metadata.Name != null) { modelExplorer = modelExplorer.Container; strBuilder.Insert(0, "."); strBuilder.Insert(0, modelExplorer.Metadata.Name); } string cboxName = strBuilder.ToString(); TagBuilder mainContainer = new TagBuilder("div"); if (htmlAttributes != null) { foreach (PropertyInfo prop in htmlAttributes.GetType().GetProperties()) { mainContainer.Attributes.Add(prop.Name, prop.GetValue(htmlAttributes).ToString()); } } int totalRows = items.Count() % cols == 0 ? items.Count() / cols : items.Count() / cols + 1; TagBuilder grid = new TagBuilder("div"); grid.Attributes.Add("style", $"display: grid; grid-template-columns: {cols}; grid-template-rows: {totalRows}"); int index = 0; foreach (SelectListItem item in items) { int currentCol = index % cols + 1; int currentRow = index / cols + 1; TagBuilder cell = new TagBuilder("div"); cell.Attributes.Add("style", $"grid-column-start: {currentCol}; grid-row-start: {currentRow}"); TagBuilder checkbox = new TagBuilder("input"); Dictionary <string, string> attributes = new Dictionary <string, string>() { { "type", "checkbox" }, { "name", cboxName }, { "value", item.Value } }; //if(results.Any(r => r.ToString().Equals(item.Value))) { // attributes.Add("checked", "checked"); //} if (item.Selected) { attributes.Add("checked", "checked"); } checkbox.GenerateId($"{cboxName}_{item.Value}", "_"); foreach (string key in attributes.Keys) { checkbox.Attributes.Add(key, attributes[key]); } TagBuilder label = new TagBuilder("label"); label.Attributes.Add("for", checkbox.Attributes["id"]); label.InnerHtml.Append(item.Text); cell.InnerHtml.AppendLine(checkbox.RenderSelfClosingTag()); cell.InnerHtml.AppendHtml(label.RenderStartTag()); cell.InnerHtml.AppendHtml(label.RenderBody()); cell.InnerHtml.AppendLine(label.RenderEndTag()); grid.InnerHtml.AppendHtml(cell.RenderStartTag()); grid.InnerHtml.AppendHtml(cell.RenderBody()); grid.InnerHtml.AppendLine(cell.RenderEndTag()); index++; } mainContainer.InnerHtml.AppendHtml(grid.RenderStartTag()); mainContainer.InnerHtml.AppendHtml(grid.RenderBody()); mainContainer.InnerHtml.AppendLine(grid.RenderEndTag()); string result; using (TextWriter textWriter = new StringWriter()) { mainContainer.WriteTo(textWriter, HtmlEncoder.Default); result = textWriter.ToString(); } return(new HtmlString(result)); }
public IHtmlContent EnumRadioButtonListFor <TProp>(Expression <Func <TModel, TProp> > property, Boolean inline, int xs = 0, int sm = 0, int md = 0, int lg = 0, int xl = 0) { var metadata = ExpressionMetadataProvider.FromLambdaExpression(property, new ViewDataDictionary <TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()), Helper.MetadataProvider); Type propertyType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType; PropertyInfo propertyInfo = metadata.Metadata.ContainerType.GetProperty(metadata.Metadata.PropertyName); EnumDatasourceAttribute[] enumAttributes = propertyInfo.GetCustomAttributes(typeof(EnumDatasourceAttribute), false) as EnumDatasourceAttribute[]; var name = Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ExpressionHelper.GetExpressionText(property); Boolean valueAsString = false; if (enumAttributes.Length > 0) { propertyType = enumAttributes[0].Datasource; valueAsString = true; } var expression = ExpressionForInternal(property); var formGroup = CommonFormGroupFor(property, false, xs, sm, md, lg, xl); IEnumerable <Object> enumValues = Enum.GetValues(propertyType).Cast <Object>(); IEnumerable <SelectListItem> items = from enumValue in enumValues select new SelectListItem { Text = GetText(enumValue), Value = valueAsString ? enumValue.ToString() : ((Int32)enumValue).ToString(), Selected = (metadata.Model != null && enumValue.Equals(metadata.Model)) }; int i = 0; foreach (SelectListItem item in items) { var div = new HtmlTag("div").AddClass("form-check"); var radioLabel = new HtmlTag("label"); if (inline) { radioLabel.AddClass("form-check-inline"); } else { radioLabel.AddClass("form-check-label"); } var input = new HtmlTag("input") .AddClasses("form-check-input") .Attr("ng-model", expression) .Attr("name", name) .Attr("value", item.Value) .Attr("type", "radio"); radioLabel.Append(input).AppendHtml(" " + item.Text); div.Append(radioLabel); if (inline) { formGroup.Append(radioLabel); } else { formGroup.Append(div); } i++; } ApplyHelpToFormGroup(formGroup, metadata.Metadata); return(formGroup); }
public static IHtmlContent ngTextBoxFor <TModel, TProperty>(this IHtmlHelper <TModel> html, Expression <Func <TModel, TProperty> > expression, IDictionary <string, object> htmlAttributes) { var expressionText = ExpressionHelper.GetExpressionText(expression); var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider); var ngAttributes = new Dictionary <string, object>(); ngAttributes["type"] = "text"; // Angular binding to client-side model (scope). This is required for Angular validation to work. var valueFieldName = html.ViewData.TemplateInfo.GetFullHtmlFieldName(expressionText); ngAttributes["name"] = valueFieldName; ngAttributes["ng-model"] = valueFieldName; // Set input type if (string.Equals(modelExplorer.Metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.EmailAddress), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "email"; } else if (modelExplorer.ModelType == typeof(Uri) || string.Equals(modelExplorer.Metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.Url), StringComparison.OrdinalIgnoreCase) || string.Equals(modelExplorer.Metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.ImageUrl), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "url"; } else if (IsNumberType(modelExplorer.ModelType)) { ngAttributes["type"] = "number"; if (IsIntegerType(modelExplorer.ModelType)) { ngAttributes["step"] = "1"; } else { ngAttributes["step"] = "any"; } } else if (modelExplorer.ModelType == typeof(DateTime)) { if (string.Equals(modelExplorer.Metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.Date), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "date"; } else if (string.Equals(modelExplorer.Metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.DateTime), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "datetime"; } } // Add attributes for Angular validation foreach (var validator in modelExplorer.Metadata.ValidatorMetadata.OfType <ValidationAttribute>()) { if (validator is StringLengthAttribute) { var lengthValidator = (StringLengthAttribute)validator; if (lengthValidator.MinimumLength != 0) { ngAttributes["ng-minlength"] = lengthValidator.MinimumLength; } if (lengthValidator.MaximumLength != int.MaxValue) { ngAttributes["ng-maxlength"] = lengthValidator.MaximumLength; } } else if (validator is RequiredAttribute) { ngAttributes["required"] = null; } else if (validator is RangeAttribute) { var rangeValidator = (RangeAttribute)validator; ngAttributes["min"] = rangeValidator.Minimum; ngAttributes["max"] = rangeValidator.Maximum; } else if (validator is CompareAttribute) { // CompareAttribute validator var compareValidator = (CompareAttribute)validator; ngAttributes["app-equal-to"] = compareValidator.OtherProperty; // TODO: Actually write the Angular directive to use this } // TODO: Regex, Phone(regex) } // Render! if (modelExplorer.Model != null) { ngAttributes.Add("value", modelExplorer.Model.ToString()); } var tag = new TagBuilder("input"); tag.MergeAttributes(MergeAttributes(ngAttributes, htmlAttributes)); tag.TagRenderMode = TagRenderMode.SelfClosing; return(tag); }
/// <inheritdoc /> public virtual IReadOnlyCollection <string> GetCurrentValues( [NotNull] ViewContext viewContext, ModelExplorer modelExplorer, string expression, bool allowMultiple) { var fullName = GetFullHtmlFieldName(viewContext, expression); if (string.IsNullOrEmpty(fullName)) { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(expression)); } var type = allowMultiple ? typeof(string[]) : typeof(string); var rawValue = GetModelStateValue(viewContext, fullName, type); // If ModelState did not contain a current value, fall back to ViewData- or ModelExplorer-supplied value. if (rawValue == null) { if (modelExplorer == null) { // Html.DropDownList() and Html.ListBox() helper case. rawValue = viewContext.ViewData.Eval(expression); if (rawValue is IEnumerable <SelectListItem> ) { // This ViewData item contains the fallback selectList collection for GenerateSelect(). // Do not try to use this collection. rawValue = null; } } else { // <select/>, Html.DropDownListFor() and Html.ListBoxFor() helper case. Do not use ViewData. rawValue = modelExplorer.Model; } if (rawValue == null) { return(null); } } // Convert raw value to a collection. IEnumerable rawValues; if (allowMultiple) { rawValues = rawValue as IEnumerable; if (rawValues == null || rawValues is string) { throw new InvalidOperationException( Resources.FormatHtmlHelper_SelectExpressionNotEnumerable(nameof(expression))); } } else { rawValues = new[] { rawValue }; } modelExplorer = modelExplorer ?? ExpressionMetadataProvider.FromStringExpression(expression, viewContext.ViewData, _metadataProvider); var enumNames = modelExplorer.Metadata.EnumNamesAndValues; var isTargetEnum = modelExplorer.Metadata.IsEnum; var innerType = Nullable.GetUnderlyingType(modelExplorer.Metadata.ModelType) ?? modelExplorer.Metadata.ModelType; // Convert raw value collection to strings. var currentValues = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var value in rawValues) { // Add original or converted string. var stringValue = (value as string) ?? Convert.ToString(value, CultureInfo.CurrentCulture); // Do not add simple names of enum properties here because whitespace isn't relevant for their binding. // Will add matching names just below. if (enumNames == null || !enumNames.ContainsKey(stringValue.Trim())) { currentValues.Add(stringValue); } // Remainder handles isEnum cases. Convert.ToString() returns field names for enum values but select // list may (well, should) contain integer values. var enumValue = value as Enum; if (isTargetEnum && enumValue == null && value != null) { var valueType = value.GetType(); if (typeof(long).IsAssignableFrom(valueType) || typeof(ulong).IsAssignableFrom(valueType)) { // E.g. user added an int to a ViewData entry and called a string-based HTML helper. enumValue = ConvertEnumFromInteger(value, innerType); } else if (!string.IsNullOrEmpty(stringValue)) { // E.g. got a string from ModelState. var methodInfo = ConvertEnumFromStringMethod.MakeGenericMethod(innerType); enumValue = (Enum)methodInfo.Invoke(obj: null, parameters: new[] { stringValue }); } } if (enumValue != null) { // Add integer value. var integerString = enumValue.ToString("d"); currentValues.Add(integerString); // Add all simple names for this value. var matchingNames = enumNames .Where(kvp => string.Equals(integerString, kvp.Value, StringComparison.Ordinal)) .Select(kvp => kvp.Key); foreach (var name in matchingNames) { currentValues.Add(name); } } } return((IReadOnlyCollection <string>)currentValues); }
/// <inheritdoc /> public virtual TagBuilder GenerateSelect( [NotNull] ViewContext viewContext, ModelExplorer modelExplorer, string optionLabel, string expression, IEnumerable <SelectListItem> selectList, IReadOnlyCollection <string> currentValues, bool allowMultiple, object htmlAttributes) { var fullName = GetFullHtmlFieldName(viewContext, expression); if (string.IsNullOrEmpty(fullName)) { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(expression)); } // If we got a null selectList, try to use ViewData to get the list of items. if (selectList == null) { if (string.IsNullOrEmpty(expression)) { // Do not call ViewData.Eval(); that would return ViewData.Model, which is not correct here. // Note this case has a simple workaround: users must pass a non-null selectList to use // DropDownList() or ListBox() in a template, where a null or empty name has meaning. throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(expression)); } selectList = GetSelectListItems(viewContext, expression); } modelExplorer = modelExplorer ?? ExpressionMetadataProvider.FromStringExpression(expression, viewContext.ViewData, _metadataProvider); if (currentValues != null) { selectList = UpdateSelectListItemsWithDefaultValue(modelExplorer, selectList, currentValues); } // Convert each ListItem to an <option> tag and wrap them with <optgroup> if requested. var listItemBuilder = GenerateGroupsAndOptions(optionLabel, selectList); var tagBuilder = new TagBuilder("select", _htmlEncoder) { InnerHtml = listItemBuilder.ToString() }; tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes)); tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */); tagBuilder.GenerateId(fullName, IdAttributeDotReplacement); if (allowMultiple) { tagBuilder.MergeAttribute("multiple", "multiple"); } // If there are any errors for a named field, we add the css attribute. ModelState modelState; if (viewContext.ViewData.ModelState.TryGetValue(fullName, out modelState)) { if (modelState.Errors.Count > 0) { tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); } } tagBuilder.MergeAttributes(GetValidationAttributes(viewContext, modelExplorer, expression)); return(tagBuilder); }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } if (output.TagName == "cms-display") { output.TagName = null; } ModelExplorer fieldEditor = null; ModelExplorer expression = null; var viewData = ViewContext.ViewData; DisableEditing = DisableEditing || !ViewContext.HttpContext.IsInCmsMode(); if (For != null) { if (!DisableEditing) { var memExpression = For.Body as MemberExpression; if (memExpression != null) { var target = Expression.Lambda(memExpression.Expression).Compile().DynamicInvoke(); if (target != null) { viewData = new ViewDataDictionary(_modelMetadataProvider, new ModelStateDictionary()) { Model = target }; fieldEditor = DisableEditing ? null : ExpressionMetadataProvider.FromStringExpression("FieldEditors", viewData, _modelMetadataProvider); if (fieldEditor?.Model != null) { viewData = new ViewDataDictionary(_modelMetadataProvider, new ModelStateDictionary()) { Model = fieldEditor.Model }; expression = ExpressionMetadataProvider.FromStringExpression(memExpression.Member.Name, viewData, _modelMetadataProvider); } if (expression?.Model != null) { expression = ExpressionMetadataProvider.FromStringExpression(memExpression.Member.Name, viewData, _modelMetadataProvider); } } } } if (expression?.Model != null) { AsHtml = true; } else { expression = ExpressionMetadataProvider.FromLambdaExpression <object, object>(For, new ViewDataDictionary <object>(ViewContext.ViewData), _modelMetadataProvider); viewData = ViewContext.ViewData; } } else { fieldEditor = DisableEditing ? null : ExpressionMetadataProvider.FromStringExpression("FieldEditors", viewData, _modelMetadataProvider); if (fieldEditor != null && fieldEditor.Model != null) { viewData = new ViewDataDictionary(_modelMetadataProvider, new ModelStateDictionary()) { Model = fieldEditor.Model }; expression = ExpressionMetadataProvider.FromStringExpression(ForPropertyName, viewData, _modelMetadataProvider); } if (expression?.Model != null) { AsHtml = true; } else { expression = ExpressionMetadataProvider.FromStringExpression(ForPropertyName, ViewContext.ViewData, _modelMetadataProvider); viewData = ViewContext.ViewData; } } IHtmlContent content = null; if (expression != null && expression.Model != null) { content = new TemplateBuilder( _viewEngine, _viewBufferScope, this.ViewContext, viewData, expression, null, //ForPropertyName ?? ExpressionHelper.GetExpressionText((LambdaExpression)For), null, true, null).Build(); if (content is ViewBuffer) //displaytemplate { AsHtml = true; } } if (content == null && output.TagName != null) { var childContent = await output.GetChildContentAsync(); if (string.IsNullOrEmpty(childContent?.GetContent())) { output.TagName = null; output.SuppressOutput(); } return; } output.TagMode = TagMode.StartTagAndEndTag; if (content == null) { return; } if (AsHtml) { output.PreContent.SetHtmlContent(content); } else { using (var writer = new System.IO.StringWriter()) { content.WriteTo(writer, HtmlEncoder.Default); output.PreContent.SetContent(writer.ToString()); } } }
public static IList <SelectListItem> GetSelectListFromDatabase <TDbContext>(this IHtmlHelper <dynamic> htmlHelper, string propertyName, bool selectedOnly = false) where TDbContext : DbContext { var modelExplorer = ExpressionMetadataProvider.FromStringExpression(propertyName, htmlHelper.ViewData, htmlHelper.MetadataProvider); Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata = modelExplorer.Metadata; var dropdownModelType = ((Type)metadata.AdditionalValues["DropdownModelType"]); var keyProperty = ((string)metadata.AdditionalValues["KeyProperty"]); var valueProperty = ((string)metadata.AdditionalValues["DisplayExpression"]); var bindingProperty = ((string)metadata.AdditionalValues["BindingProperty"]); var orderByProperty = ((string)metadata.AdditionalValues["OrderByProperty"]); var orderByType = ((string)metadata.AdditionalValues["OrderByType"]); var physicalFilePath = ((string)metadata.AdditionalValues["PhysicalFilePath"]); var fileFolderId = ((string)metadata.AdditionalValues["FileFolderId"]); if (!string.IsNullOrEmpty(fileFolderId)) { physicalFilePath = Server.GetWwwFolderPhysicalPathById(fileFolderId); } var physicalFolderPath = ((string)metadata.AdditionalValues["PhysicalFolderPath"]); var folderFolderId = ((string)metadata.AdditionalValues["FolderFolderId"]); if (!string.IsNullOrEmpty(folderFolderId)) { physicalFolderPath = Server.GetWwwFolderPhysicalPathById(folderFolderId); } var nullable = ((bool)metadata.AdditionalValues["Nullable"]); var options = ((IEnumerable <string>)metadata.AdditionalValues["Options"]); Type propertyType = GetNonNullableModelType(metadata); List <SelectListItem> items = new List <SelectListItem>(); List <string> ids = new List <string>(); if (propertyType != typeof(string) && (propertyType.GetInterfaces().Contains(typeof(IEnumerable)))) { if (modelExplorer.Model != null) { foreach (var val in (IEnumerable)modelExplorer.Model) { if (val != null) { if (!string.IsNullOrWhiteSpace(bindingProperty)) { ids.Add(val.GetPropValue(bindingProperty).ToString()); } else { ids.Add(val.ToString()); } } } } } else { if (modelExplorer.Model != null) { if (!string.IsNullOrWhiteSpace(bindingProperty)) { ids.Add(modelExplorer.Model.GetPropValue(bindingProperty).ToString()); } else { ids.Add(modelExplorer.Model.ToString()); } } } if (!string.IsNullOrEmpty(physicalFolderPath)) { var repository = htmlHelper.FileSystemGenericRepositoryFactory().CreateFolderRepositoryReadOnly(default(CancellationToken), physicalFolderPath, true); var data = repository.GetAll(LamdaHelper.GetOrderByFunc <DirectoryInfo>(orderByProperty, orderByType), null, null); keyProperty = nameof(DirectoryInfo.FullName); data.ToList().ForEach(item => items.Add(new SelectListItem() { Text = GetDisplayString(htmlHelper, item, valueProperty).Replace(physicalFolderPath, ""), Value = item.GetPropValue(nameof(DirectoryInfo.FullName)) != null ? item.GetPropValue(nameof(DirectoryInfo.FullName)).ToString().Replace(physicalFolderPath, "") : "", Selected = item.GetPropValue(keyProperty) != null && ids.Contains(item.GetPropValue(keyProperty).ToString().Replace(physicalFolderPath, "")) })); } else if (!string.IsNullOrEmpty(physicalFilePath)) { var repository = htmlHelper.FileSystemGenericRepositoryFactory().CreateFileRepositoryReadOnly(default(CancellationToken), physicalFilePath, true); var data = repository.GetAll(LamdaHelper.GetOrderByFunc <FileInfo>(orderByProperty, orderByType), null, null); keyProperty = nameof(FileInfo.FullName); data.ToList().ForEach(item => items.Add(new SelectListItem() { Text = GetDisplayString(htmlHelper, item, valueProperty), Value = item.GetPropValue(keyProperty) != null ? item.GetPropValue(keyProperty).ToString().Replace(physicalFilePath, "") : "", Selected = item.GetPropValue(keyProperty) != null && ids.Contains(item.GetPropValue(keyProperty).ToString().Replace(physicalFilePath, "")) })); } else if (metadata.DataTypeName == "ModelRepeater") { foreach (var item in htmlHelper.ViewData.Model) { var itemObject = (Object)item; items.Add(new SelectListItem() { Text = GetDisplayString(htmlHelper, item, valueProperty), Value = itemObject.GetPropValue(keyProperty) != null ? itemObject.GetPropValue(keyProperty).ToString() : "", Selected = itemObject.GetPropValue(keyProperty) != null && ids.Contains(itemObject.GetPropValue(keyProperty).ToString()) }); } } else { //db if (options == null) { using (var db = htmlHelper.DatabaseByEntityType(dropdownModelType)) { var pi = dropdownModelType.GetProperty(orderByProperty); Type iQueryableType = typeof(IQueryable <>).MakeGenericType(new[] { dropdownModelType }); IQueryable query = db.Queryable(dropdownModelType); if (selectedOnly) { var whereClause = LamdaHelper.SearchForEntityByIds(dropdownModelType, ids.Cast <Object>()); query = (IQueryable)typeof(LamdaHelper).GetMethod(nameof(LamdaHelper.Where)).MakeGenericMethod(dropdownModelType).Invoke(null, new object[] { query, whereClause }); } else { if (metadata.AdditionalValues.ContainsKey("WhereClauseEqualsDictionary")) { var whereClauseEqualsDictionary = (Dictionary <string, List <object> >)metadata.AdditionalValues["WhereClauseEqualsDictionary"]; foreach (var where in whereClauseEqualsDictionary) { var whereClause = LamdaHelper.SearchForEntityByProperty(dropdownModelType, where.Key, where.Value); query = (IQueryable)typeof(LamdaHelper).GetMethod(nameof(LamdaHelper.Where)).MakeGenericMethod(dropdownModelType).Invoke(null, new object[] { query, whereClause }); } } if (!string.IsNullOrWhiteSpace(orderByProperty)) { if (orderByType == "asc") { query = (IQueryable)typeof(Utilities).GetMethod(nameof(Utilities.QueryableOrderBy)).MakeGenericMethod(dropdownModelType).Invoke(null, new object[] { query, orderByProperty, true }); } else { query = (IQueryable)typeof(Utilities).GetMethod(nameof(Utilities.QueryableOrderBy)).MakeGenericMethod(dropdownModelType).Invoke(null, new object[] { query, orderByProperty, false }); } } } IEnumerable results = query.ToList(dropdownModelType); foreach (var item in results) { items.Add(new SelectListItem() { Text = GetDisplayString(htmlHelper, item, valueProperty), //Value = item.GetPropValue(keyProperty) != null ? item.GetPropValue(keyProperty).ToString() : "", //Selected = item.GetPropValue(keyProperty) != null && ids.Contains(item.GetPropValue(keyProperty).ToString()) Value = GetDisplayString(htmlHelper, item, keyProperty), Selected = ids.Contains(GetDisplayString(htmlHelper, item, keyProperty)) }); } } } else { options.ToList().ForEach(item => items.Add(new SelectListItem() { Text = item, Value = item, Selected = ids.Contains(item) })); } } if (metadata.IsNullableValueType || nullable) { items.Insert(0, new SelectListItem { Text = "", Value = "" }); } return(items); }
public static IList <SelectListItem> GetSelectList(this IHtmlHelper <dynamic> htmlHelper, string propertyName, bool selectedOnly = false) { var modelExplorer = ExpressionMetadataProvider.FromStringExpression(propertyName, htmlHelper.ViewData, htmlHelper.MetadataProvider); Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata = modelExplorer.Metadata; var dropdownModelType = ((Type)metadata.AdditionalValues["DropdownModelType"]); var keyProperty = ((string)metadata.AdditionalValues["KeyProperty"]); var valueProperty = ((string)metadata.AdditionalValues["DisplayExpression"]); var bindingProperty = ((string)metadata.AdditionalValues["BindingProperty"]); var orderByProperty = ((string)metadata.AdditionalValues["OrderByProperty"]); var orderByType = ((string)metadata.AdditionalValues["OrderByType"]); var physicalFilePath = ((string)metadata.AdditionalValues["PhysicalFilePath"]); var physicalFolderPath = ((string)metadata.AdditionalValues["PhysicalFolderPath"]); var nullable = ((bool)metadata.AdditionalValues["Nullable"]); var options = ((IEnumerable <string>)metadata.AdditionalValues["Options"]); Type propertyType = GetNonNullableModelType(metadata); List <SelectListItem> items = new List <SelectListItem>(); List <string> ids = new List <string>(); if (propertyType != typeof(string) && (propertyType.GetInterfaces().Contains(typeof(IEnumerable)))) { if (modelExplorer.Model != null) { foreach (var val in (IEnumerable)modelExplorer.Model) { if (val != null) { if (!string.IsNullOrWhiteSpace(bindingProperty)) { ids.Add(val.GetPropValue(bindingProperty).ToString()); } else { ids.Add(val.ToString()); } } } } } else { if (modelExplorer.Model != null) { if (!string.IsNullOrWhiteSpace(bindingProperty)) { ids.Add(modelExplorer.Model.GetPropValue(bindingProperty).ToString()); } else { ids.Add(modelExplorer.Model.ToString()); } } } if (metadata.DataTypeName == "ModelRepeater") { foreach (var item in htmlHelper.ViewData.Model) { var itemObject = (Object)item; items.Add(new SelectListItem() { Text = GetDisplayString(htmlHelper, item, valueProperty), Value = itemObject.GetPropValue(keyProperty) != null ? itemObject.GetPropValue(keyProperty).ToString() : "", Selected = itemObject.GetPropValue(keyProperty) != null && ids.Contains(itemObject.GetPropValue(keyProperty).ToString()) }); } } else { //db if (options == null) { } else { options.ToList().ForEach(item => items.Add(new SelectListItem() { Text = item, Value = item, Selected = ids.Contains(item) })); } } if (metadata.IsNullableValueType || nullable) { items.Insert(0, new SelectListItem { Text = "", Value = "" }); } return(items); }
public static IHtmlContent RPCSAutocompleteEnumDropDownList <TModel, TEnum, TProperty>( this IHtmlHelper <TModel> html, Expression <Func <TModel, TEnum> > expression, Expression <Func <TModel, TProperty> > displayExpression, string lableClassAttribute, bool validationAttribute, OperationSet editRights, OperationSet displayRights) { var appUserSvc = _serviceProvider.GetRequiredService <IApplicationUserService>(); if (expression == null) { throw new ArgumentNullException("expression"); } if (!typeof(TEnum).IsEnum) { throw new ArgumentException("TEnum"); } //ApplicationUser user = UsersFactory.Instance.GetUser(HttpContext.Current.User); var label = html.LabelFor(expression, new { @class = "control-label " + lableClassAttribute }); if (appUserSvc.HasAccess(editRights)) { string controlName = GetExpressionParam <TModel, TEnum>(expression); string initScript = string.Format("<script>$(document).ready(function () {{ $('#{0}').combobox(); }});</script>", controlName); var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider); IList <SelectListItem> selectList = Enum.GetValues(typeof(TEnum)).Cast <TEnum>() .Select(x => new SelectListItem { Text = ((Enum)(object)x).GetAttributeOfType <DisplayAttribute>().Name, Value = Convert.ToUInt64(x).ToString() }).ToList(); var contents = html.DropDownListFor(expression, selectList, new { @class = "form-control" }); string result = string.Empty; if (validationAttribute) { result = String.Concat("<div class=\"form-group\">", GetString(label), "<div class=\"col-md-8\">", GetString(contents), html.ValidationMessageFor(expression, "", new { @class = "text-danger" }), "</div>", "</div>"); } else { result = String.Concat("<div class=\"form-group\">", GetString(label), "<div class=\"col-md-8\">", GetString(contents), "</div>", "</div>"); } return(new HtmlString(result)); } string l = GetString(html.HiddenFor(expression)); if (appUserSvc.HasAccess(displayRights)) { var contents = html.DisplayFor(displayExpression); string result = String.Concat("<div class=\"form-group\">", GetString(label), "<div class=\"col-md-8\" style=\"padding:8px 12px\" >", GetString(contents), "</div>", "</div>"); return(new HtmlString(result + l)); } return(new HtmlString(l)); }
public static IHtmlContent TableListFor <TModel, TProperty>(this IHtmlHelper <TModel> html, Expression <Func <TModel, TProperty> > expression, IDictionary <string, object> htmlAttributes, bool showHeader = false, bool allowAdd = true) { var fieldName = ExpressionHelper.GetExpressionText(expression); //var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName); //var fieldId = TagBuilder.CreateSanitizedId(fullBindingName); var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider); dynamic model = metadata.Model; Type baseType = metadata.ModelType.GetGenericArguments().Single(); var properties = baseType.GetProperties().ToList(); var typeMetadata = html.MetadataProvider.GetMetadataForType(baseType); var propertyAttributes = new Dictionary <string, IDictionary <string, object> >(); var formattingAttributes = new Dictionary <string, IDictionary <string, string> >(); foreach (var prop in properties) { var propType = GetPropertyType(prop); var propertyData = typeMetadata.Properties.Where(x => x.PropertyName == prop.Name).FirstOrDefault(); var attrs = GetUnobtrusiveValidationAttributes(prop, propertyData, html.MetadataProvider); //attrs.Add("class", "form-control"); attrs.Add("class", ""); attrs.Add("placeholder", propertyData.DisplayName ?? prop.Name); if (propertyData.IsReadOnly) { attrs.Add("readonly", "readonly"); } if (propType == typeof(DateTime)) { attrs["class"] += " date-picker"; } if (propType == typeof(bool) && Attribute.IsDefined(prop, typeof(TableListRadioButton))) { attrs.Add("data-group", "group" + prop.Name); } propertyAttributes.Add(prop.Name, attrs); var fAttrs = new Dictionary <string, string>(); fAttrs.Add(nameof(propertyData.DisplayName), propertyData.DisplayName); fAttrs.Add(nameof(propertyData.DisplayFormatString), propertyData.DisplayFormatString); formattingAttributes.Add(prop.Name, fAttrs); } var table = new TagBuilder("table"); if (showHeader) { AppendHead(table, properties, formattingAttributes); } var tbody = new TagBuilder("tbody"); if (model != null && model.Count > 0) { AppendRows(html, tbody, properties, model, fieldName, propertyAttributes, formattingAttributes); } if (allowAdd) { AppendLastRow(html, tbody, properties, fieldName, propertyAttributes, formattingAttributes, model != null ? model.Count : 0); } if (htmlAttributes != null) { table.MergeAttributes(htmlAttributes); } if (table.Attributes.ContainsKey("class")) { table.Attributes["class"] += " table-list-mvc"; } else { table.Attributes.Add("class", "table-list-mvc"); } table.InnerHtml.AppendHtml(tbody); return(new HtmlString(TagBuilderToString(table))); }
public ModelExplorer GetModelExplorer(string expr, ViewDataDictionary viewData) { return(ExpressionMetadataProvider.FromStringExpression(expr, viewData, MetadataProvider)); }
/// <inheritdoc /> public string DisplayText(string name) { var metadata = ExpressionMetadataProvider.FromStringExpression(name, ViewData, MetadataProvider); return(GenerateDisplayText(metadata)); }
public ModelExplorer GetModelExplorer <M, P>(Expression <Func <M, P> > expr, ViewDataDictionary <M> viewData) { return(ExpressionMetadataProvider.FromLambdaExpression(expr, viewData, MetadataProvider)); }
public static HtmlString ngTextBoxFor <TModel, TProperty>(this IHtmlHelper <TModel> html, Expression <Func <TModel, TProperty> > expression, IDictionary <string, object> htmlAttributes) { var expressionText = ExpressionHelper.GetExpressionText(expression); var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider); var ngAttributes = new Dictionary <string, object>(); ngAttributes["type"] = "text"; // Angular binding to client-side model (scope). This is required for Angular validation to work. var valueFieldName = html.ViewData.TemplateInfo.GetFullHtmlFieldName(expressionText); ngAttributes["name"] = valueFieldName; ngAttributes["ng-model"] = valueFieldName; // Set input type if (string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.EmailAddress), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "email"; } else if (metadata.ModelType == typeof(Uri) || string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.Url), StringComparison.OrdinalIgnoreCase) || string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.ImageUrl), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "url"; } else if (IsNumberType(metadata.ModelType)) { ngAttributes["type"] = "number"; if (IsIntegerType(metadata.ModelType)) { ngAttributes["step"] = "1"; } else { ngAttributes["step"] = "any"; } } else if (metadata.ModelType == typeof(DateTime)) { if (string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.Date), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "date"; } else if (string.Equals(metadata.DataTypeName, Enum.GetName(typeof(DataType), DataType.DateTime), StringComparison.OrdinalIgnoreCase)) { ngAttributes["type"] = "datetime"; } } // Add attributes for Angular validation var clientValidators = html.GetClientValidationRules(metadata, null); foreach (var validator in clientValidators) { if (string.Equals(validator.ValidationType, "length")) { if (validator.ValidationParameters.ContainsKey("min")) { ngAttributes["ng-minlength"] = validator.ValidationParameters["min"]; } if (validator.ValidationParameters.ContainsKey("max")) { ngAttributes["ng-maxlength"] = validator.ValidationParameters["max"]; } } else if (string.Equals(validator.ValidationType, "required")) { ngAttributes["required"] = null; } else if (string.Equals(validator.ValidationType, "range")) { if (validator.ValidationParameters.ContainsKey("min")) { ngAttributes["min"] = validator.ValidationParameters["min"]; } if (validator.ValidationParameters.ContainsKey("max")) { ngAttributes["max"] = validator.ValidationParameters["max"]; } } else if (string.Equals(validator.ValidationType, "equalto")) { // CompareAttribute validator var fieldToCompare = validator.ValidationParameters["other"]; // e.g. *.NewPassword var other = validator.ValidationParameters["other"].ToString(); if (other.StartsWith("*.")) { // The built-in CompareAttributeAdapter prepends *. to the property name so we strip it off here other = other.Substring("*.".Length); } ngAttributes["app-equal-to"] = other; // TODO: Actually write the Angular directive to use this } // TODO: Regex, Phone(regex) } // Render! if (metadata.Model != null) { ngAttributes.Add("value", metadata.Model.ToString()); } var tag = new TagBuilder("input"); tag.MergeAttributes(MergeAttributes(ngAttributes, htmlAttributes)); return(tag.ToHtmlString(TagRenderMode.SelfClosing)); }
public static HtmlString Select2DropDownListFor <TModel, TValue>(this IHtmlHelper <TModel> html, Expression <Func <TModel, TValue> > expression, IEnumerable <SelectListItem> items = null, string placeHolder = null, object htmlAttributes = null, bool multiSelect = false, bool canClearSelect = false) { var select = new TagBuilder("select"); if (htmlAttributes != null) { select.MergeAttributes(new RouteValueDictionary(htmlAttributes)); } var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider); var htmlFieldName = metadata.Metadata.PropertyName; var labelText = metadata.Metadata.DisplayName ?? metadata.Metadata.PropertyName ?? htmlFieldName.Split('.').Last(); select.Attributes.Add("name", htmlFieldName); select.Attributes.Add("id", htmlFieldName); select.Attributes.Add("class", "form-control input-sm"); if (multiSelect) { select.Attributes.Add("multiple", "multiple"); } var sb = new StringBuilder(); if (items != null) { foreach (var item in items) { var option = new TagBuilder("option"); option.Attributes.Add("value", html.Encode(item.Value)); if (item.Selected) { option.Attributes.Add("selected", "selected"); } option.InnerHtml.SetHtmlContent(item.Text); sb.AppendLine(option.GetString()); } } select.InnerHtml.SetHtmlContent(sb.ToString()); var div = string.Format(@"<div class=""form-group""> <label class=""col-sm-3 control-label"">{0}</label> <div class=""col-sm-8""> {1} </div> </div>", labelText, select.GetString()); string js = string.Format(@"<script type=""text/javascript""> $(function () {{ $(""#{0}"").select2({{ placeholder: ""{1}"", {2} }}); }}); </script>", htmlFieldName, placeHolder.IsEmpty() ? "" : placeHolder, canClearSelect ? "allowClear: true" : ""); return(new HtmlString(div + js)); }