/// <summary> /// /// </summary> /// <typeparam name="TModel">Type of the Model object</typeparam> /// <typeparam name="TValue">Value of the Model object</typeparam> /// <param name="html">class this method extends</param> /// <param name="modelProperty">An modelProperty (linq) that identifies the Model</param> /// <param name="htmlAttributes">dictionary of html attributes for the Model in the modelProperty</param> /// <param name="includeLabel"></param> /// <returns></returns> private static MvcHtmlString FoundationTextAreaFor <TModel, TValue>(this HtmlHelper <TModel> html, Expression <Func <TModel, TValue> > modelProperty, IDictionary <string, object> htmlAttributes, bool includeLabel = true) { // Returns the modelPropertyMetaData from the Expression parameter for the model var modelPropertyMetaData = ModelMetadata.FromLambdaExpression(modelProperty, html.ViewData); // Value of the "name" attribute var htmlFieldName = ExpressionHelper.GetExpressionText(modelProperty); // used to retrieve RequiredAttribute from Model/Property if there is one var modelPropertyMemberExpression = (modelProperty.Body as MemberExpression); DataTypeAttribute dataTypeAttribute = null; string requiredMessage = null; FoundationAbidePatternAttribute abidePatternAttribute = null; var requiredAttribute = FoundationInputModelRequiredAttributeReader(ref htmlAttributes, modelPropertyMemberExpression, ref requiredMessage, ref dataTypeAttribute, ref abidePatternAttribute); // retrieve the text used for the label: use the DisplayNameAttribute, then the Property's name, then the html name attribute string var labelText = html.Encode(modelPropertyMetaData.DisplayName ?? modelPropertyMetaData.PropertyName ?? htmlFieldName.Split('.').Last()); // create label var label = FoundationInputLabelBuilder(includeLabel, labelText, htmlFieldName, requiredAttribute); // add maxlength property to input to prevent adding too many characters to input field if (abidePatternAttribute != null) { var pattern = abidePatternAttribute.AbidePattern.Split('_'); if (pattern.Length > 0) { if (pattern[0] == "length") { htmlAttributes.Add(new KeyValuePair <string, object>("maxlength", pattern[1])); } } } // create text box input var textAreaFor = html.TextAreaFor(modelProperty, htmlAttributes); if (requiredAttribute == null) { // place the input inside the <label> tag after the label text label.InnerHtml += textAreaFor.ToHtmlString(); return(includeLabel ? new MvcHtmlString(label.ToString()) : new MvcHtmlString(textAreaFor.ToHtmlString())); } // create error small if needed var errorTextSmall = FoundationInputErrorBuilder(requiredMessage, labelText, dataTypeAttribute, abidePatternAttribute); // place the input inside the <label> tag after the label text label.InnerHtml += textAreaFor.ToHtmlString(); return(new MvcHtmlString(label.ToString() + errorTextSmall)); }
/// <summary> /// Read attributes associated with the Model object /// </summary> /// <param name="htmlAttributes">Dictionary of htmlAttributes to add to based on Model Attributes</param> /// <param name="modelPropertyMemberExpression">MemberExpression used to read Model attributes</param> /// <param name="requiredMessage">reference to RequredMessage object, may return null</param> /// <param name="dataTypeAttribute">reference to DataType attribute to get the type of data the Model is</param> /// <param name="abidePatternAttribute"></param> /// <returns>RequiredAttribute object, may be null</returns> private static RequiredAttribute FoundationInputModelRequiredAttributeReader( ref IDictionary <string, object> htmlAttributes, MemberExpression modelPropertyMemberExpression, ref string requiredMessage, ref DataTypeAttribute dataTypeAttribute, ref FoundationAbidePatternAttribute abidePatternAttribute) { if (modelPropertyMemberExpression == null) { return(null); } var requiredAttribute = modelPropertyMemberExpression.Member.GetCustomAttributes(typeof(RequiredAttribute), false) .Cast <RequiredAttribute>() .FirstOrDefault(); if (requiredAttribute != null) { requiredMessage = requiredAttribute.ErrorMessage.IsNotNullOrEmpty() ? requiredAttribute.ErrorMessage : null; htmlAttributes.Add("required", ""); } // if the Model (property) has the FoundationAbidePatternAttribute then add it to the html attributes on in the text input abidePatternAttribute = modelPropertyMemberExpression.Member.GetCustomAttributes(typeof(FoundationAbidePatternAttribute), false) .Cast <FoundationAbidePatternAttribute>() .FirstOrDefault(); if (abidePatternAttribute != null) { htmlAttributes.Add("pattern", abidePatternAttribute.AbidePattern); if (requiredMessage.IsNullOrEmpty() && abidePatternAttribute.ValidationMessage.IsNotNullOrEmpty()) { requiredMessage = abidePatternAttribute.ValidationMessage; } } dataTypeAttribute = modelPropertyMemberExpression.Member.GetCustomAttributes(typeof(DataTypeAttribute), false) .Cast <DataTypeAttribute>() .FirstOrDefault(); return(requiredAttribute); }
/// <summary> /// Create HTML for error below input to show from Abide javascript code /// </summary> /// <param name="requiredMessage">optional message to show inside the error HTML</param> /// <param name="labelText">label of the input the error is for</param> /// <param name="dataTypeAttribute">type of data the field should have</param> /// <param name="abidePatternAttribute"></param> /// <returns>TagBuilder object of error HTML</returns> private static TagBuilder FoundationInputErrorBuilder(string requiredMessage, string labelText, DataTypeAttribute dataTypeAttribute, FoundationAbidePatternAttribute abidePatternAttribute) { var errorTextSmall = new TagBuilder("small"); errorTextSmall.AddCssClass("error"); if (requiredMessage.IsNotNullOrEmpty()) { errorTextSmall.SetInnerText(requiredMessage); } else { var message = new StringBuilder(); message.Append(labelText).Append(" is required"); if (dataTypeAttribute != null) { message.Append(" and must be "); switch (dataTypeAttribute.DataType) { case DataType.CreditCard: message.Append("a valid credit card number"); break; case DataType.Currency: message.Append("a valid dollar amount"); break; case DataType.Custom: message.Append(""); break; case DataType.Date: message.Append("a valid date: MM-DD-YYYY"); break; case DataType.DateTime: message.Append("a valid date and time: MM-DD-YYYY HH:MM:SS"); break; case DataType.Duration: break; case DataType.EmailAddress: message.Append("a valid email address"); break; case DataType.Html: break; case DataType.ImageUrl: break; case DataType.MultilineText: message.Append("text"); break; case DataType.Password: break; case DataType.PhoneNumber: message.Append("a valid phone number"); break; case DataType.PostalCode: message.Append("a valid postal (ZIP) code"); break; case DataType.Text: message.Append("text"); break; case DataType.Time: message.Append("a valid time: HH:MM:SS"); break; case DataType.Upload: break; case DataType.Url: message.Append("a valid URL"); break; } } if (abidePatternAttribute != null) { var pattern = abidePatternAttribute.AbidePattern.Split('_'); if (pattern.Length > 0) { if (pattern[0] == "length") { message.Append(" and cannot be longer than ").Append(pattern[1]).Append(" characters"); } } } errorTextSmall.SetInnerText(message.ToString()); } return(errorTextSmall); }
/// <summary> /// /// </summary> /// <typeparam name="TModel">Type of the Model object</typeparam> /// <typeparam name="TValue">Value of the Model object</typeparam> /// <param name="html">class this method extends</param> /// <param name="modelProperty">An modelProperty (linq) that identifies the Model</param> /// <param name="htmlAttributes">dictionary of html attributes for the Model in the modelProperty</param> /// <param name="includeLabel"></param> /// <returns></returns> private static MvcHtmlString FoundationTextBoxFor <TModel, TValue>(this HtmlHelper <TModel> html, Expression <Func <TModel, TValue> > modelProperty, IDictionary <string, object> htmlAttributes, bool includeLabel = true) { // Returns the modelPropertyMetaData from the Expression parameter for the model var modelPropertyMetaData = ModelMetadata.FromLambdaExpression(modelProperty, html.ViewData); // Value of the "name" attribute var htmlFieldName = ExpressionHelper.GetExpressionText(modelProperty); // used to retrieve RequiredAttribute from Model/Property if there is one var modelPropertyMemberExpression = (modelProperty.Body as MemberExpression); var isNotRequired = htmlAttributes.ContainsKey("notrequired"); DataTypeAttribute dataTypeAttribute = null; string requiredMessage = null; RequiredAttribute requiredAttribute = null; FoundationAbidePatternAttribute abidePatternAttribute = null; if (!isNotRequired) { requiredAttribute = FoundationInputModelRequiredAttributeReader(ref htmlAttributes, modelPropertyMemberExpression, ref requiredMessage, ref dataTypeAttribute, ref abidePatternAttribute); } // retrieve the text used for the label: use the DisplayNameAttribute, then the Property's name, then the html name attribute string var labelText = html.Encode(modelPropertyMetaData.DisplayName ?? modelPropertyMetaData.PropertyName ?? htmlFieldName.Split('.').Last()); // create label var label = FoundationInputLabelBuilder(includeLabel, labelText, htmlFieldName, requiredAttribute); // add maxlength property to input to prevent adding too many characters to input field if (abidePatternAttribute != null) { var pattern = abidePatternAttribute.AbidePattern.Split('_'); if (pattern.Length > 0) { if (pattern[0] == "length") { htmlAttributes.Add(new KeyValuePair <string, object>("maxlength", pattern[1])); } } } // create text box input var textBoxFor = html.TextBoxFor(modelProperty, htmlAttributes); // check if htmlAttributes contains "name=''" and if so set the name property to blank - used to prevent field from posting with for security issues such as credit card information if (htmlAttributes.ContainsKey("name")) { var index1 = textBoxFor.ToString().IndexOf(" name=\"", StringComparison.Ordinal) + 7; var index2 = textBoxFor.ToString().IndexOf("\"", index1, StringComparison.Ordinal); var newText = textBoxFor.ToString().Remove(index1, index2 - index1); textBoxFor = new MvcHtmlString(newText); } // if the "notrequired" attribute was provided then remove the auto-generated "required" attribute from the input if (isNotRequired) { textBoxFor = new MvcHtmlString(textBoxFor.ToString().Replace(" required ", " ")); } // return html if the required attribute is not required or their is no required field message if (requiredAttribute == null && requiredMessage.IsNullOrEmpty()) { // place the input inside the <label> tag after the label text label.InnerHtml += textBoxFor.ToHtmlString(); return(includeLabel ? new MvcHtmlString(label.ToString()) : new MvcHtmlString(textBoxFor.ToHtmlString())); } // create error small if needed var errorTextSmall = FoundationInputErrorBuilder(requiredMessage, labelText, dataTypeAttribute, abidePatternAttribute); // place the input inside the <label> tag after the label text label.InnerHtml += textBoxFor.ToHtmlString(); return(new MvcHtmlString(label.ToString() + errorTextSmall)); }
private static MvcHtmlString FoundationRadioButtonFor <TModel, TValue>( this HtmlHelper <TModel> html, Expression <Func <TModel, TValue> > modelProperty, IDictionary <string, object> htmlAttributes, IEnumerable <KeyValuePair <string, object> > valuesLabels, Expression <Func <TModel, TValue> > labelModelExpression, string labelText, bool includeLabel) { if (htmlAttributes == null) { htmlAttributes = new Dictionary <string, object>(); } // Returns the modelPropertyMetaData from the Expression parameter for the model var modelPropertyMetaData = ModelMetadata.FromLambdaExpression(modelProperty, html.ViewData); // Value of the "name" attribute var htmlFieldName = ExpressionHelper.GetExpressionText(modelProperty); // used to retrieve RequiredAttribute from Model/Property if there is one var modelPropertyMemberExpression = (modelProperty.Body as MemberExpression); DataTypeAttribute dataTypeAttribute = null; string requiredMessage = null; FoundationAbidePatternAttribute abidePatternAttribute = null; var requiredAttribute = FoundationInputModelRequiredAttributeReader(ref htmlAttributes, modelPropertyMemberExpression, ref requiredMessage, ref dataTypeAttribute, ref abidePatternAttribute); // retrieve the text used for the label: use the DisplayNameAttribute, then the Property's name, then the html name attribute string string label = null; if (includeLabel) { // create label if (labelModelExpression != null) { label = html.LabelFor(labelModelExpression).ToHtmlString(); } else if (labelText.IsNotNullOrEmpty()) { label = FoundationInputLabelBuilder(true, labelText, htmlFieldName, null).ToString(); } else { labelText = modelPropertyMetaData.DisplayName ?? modelPropertyMetaData.PropertyName ?? htmlFieldName.Split('.').Last(); label = FoundationInputLabelBuilder(true, labelText, htmlFieldName, requiredAttribute).ToString(); } } object noCustom; htmlAttributes.TryGetValue("class", out noCustom); object labelAttributes = noCustom == null ? new { @class = "label-radio" } : new { @class = "label-radio no-custom" }; // create all of the radio button inputs with labels into a string var radioInputs = string.Empty; foreach (var item in valuesLabels) { // set the id value to be prefixed with the radio value to provide a unique value for the radio's label var radioInput = html.RadioButtonFor(modelProperty, item.Value).ToHtmlString(); // start of id tag value var index1 = radioInput.IndexOf(" id=\"", StringComparison.Ordinal) + 5; // end of id tag value var index2 = radioInput.IndexOf("\"", index1, StringComparison.Ordinal); // id tag value radioInput = radioInput.Insert(index2, item.Key); var radioInputLabel = html.LabelFor(modelProperty, item.Key, labelAttributes).ToHtmlString(); // start of for tag value index1 = radioInputLabel.IndexOf(" for=\"", StringComparison.Ordinal) + 6; // end of for tag value index2 = radioInputLabel.IndexOf("\"", index1, StringComparison.Ordinal); // id tag value radioInputLabel = radioInputLabel.Insert(index2, item.Key); radioInputs += radioInput + " " + radioInputLabel + " "; } if (requiredAttribute == null) { return(includeLabel ? new MvcHtmlString(label + radioInputs) : new MvcHtmlString(radioInputs)); } // create error small if needed var errorTextSmall = FoundationInputErrorBuilder(requiredMessage, labelText, dataTypeAttribute, abidePatternAttribute); return(new MvcHtmlString(label + radioInputs + errorTextSmall)); }