Exemplo n.º 1
0
 private string LabelHtml <TProperty>(Expression <Func <TModel, TProperty> > expression, FieldConfiguration fieldConfiguration)
 {
     return((
                fieldConfiguration.FieldName != null
         ? _htmlHelper.LabelFor(expression, fieldConfiguration.FieldName)
         : _htmlHelper.LabelFor(expression)
                )
            .ToHtmlString());
 }
Exemplo n.º 2
0
        private FlowFormField FieldFor <TProperty>(Expression <Func <TModel, TProperty> > expression, bool containsSection, FieldConfiguration fieldConfiguration = null)
        {
            /*
             * Renders a field for a non-boolean property of the model
             */

            fieldConfiguration = fieldConfiguration ?? new FieldConfiguration();

            if (fieldConfiguration.HideIfNull && fieldConfiguration.ReadOnly && GetValue(expression) == null)
            {
                return(null);
            }

            var htmlAttrs  = Helper.ObjectToDictionary(fieldConfiguration.HtmlAttributes);
            var type       = ElementType.Text;
            var grid       = default(Grid);
            var selectList = default(MultiSelectList);
            var metadata   = ModelMetadata.FromLambdaExpression(expression, _htmlHelper.ViewData);

            // Label
            var labelHtml = LabelHtml(expression, fieldConfiguration);

            if (fieldConfiguration.ReadOnly)
            {
                labelHtml = labelHtml.ReReplace(@"</?label.*?>", "", RegexOptions.IgnoreCase);
            }

            if (fieldConfiguration.ReadOnly && expression.ReturnType.Name != "Grid`1")
            {
                var value      = (GetValue(expression) ?? "?");
                var fi         = value.GetType().GetField(value.ToString());
                var attributes = fi != null ? (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false) : new DescriptionAttribute[] { };

                var stringValue = (attributes.Length > 0) ? attributes[0].Description : value.ToString();

                return(new FlowFormField(_writer, containsSection, labelHtml, (new HtmlString(stringValue)).ToString(), parentClass: fieldConfiguration.ParentClass));
            }

            var validators = metadata.GetValidators(_htmlHelper.ViewContext.Controller.ControllerContext);

            var classes = new ClassBuilder();

            if (htmlAttrs.ContainsKey("class"))
            {
                classes.Add((string)htmlAttrs["class"]);
            }

            if (metadata.IsRequired && (!metadata.ModelType.IsEnum || fieldConfiguration.Exclude == null || fieldConfiguration.Exclude.Length == 0))
            {
                classes.Add("required");
            }
            else
            {
                labelHtml = labelHtml.Replace("</label>", " <em>(Optional)</em></label>");
            }

            switch (metadata.DataTypeName)
            {
            case "Digits":
            case "CreditCard":
                classes.Add(metadata.DataTypeName.Replace("-", "").ToLower());
                break;

            case "IPAddress":
                classes.Add("ip-address");
                break;

            case "MultilineText":
                type = ElementType.TextArea;
                break;
            }
            switch (metadata.ModelType.Name)
            {
            case "Double":
                classes.Add("number");
                break;

            case "Int32":
                classes.Add("integer");
                break;

            case "Email":
                classes.Add("email");
                break;

            case "Password":
                type = ElementType.Password;
                break;

            case "Date":
                classes.Add("date");
                break;

            case "HttpPostedFileBase":
                htmlAttrs["type"] = "file";
                break;
            }

            if (metadata.ModelType.IsEnum && metadata.ModelType.IsDefined(typeof(FlagsAttribute), false))
            {
                type = ElementType.Select;
                var list           = (IEnumerable <object>)EnumInfo.CreateList(metadata.ModelType, fieldConfiguration.Exclude);
                var selectedValues = GetSelectedEnums((Enum)metadata.Model, fieldConfiguration.Exclude).ToList();
                selectList = new MultiSelectList(list, "Value", "Display", selectedValues);
            }
            else if (metadata.ModelType.IsEnum || (
                         metadata.ModelType.IsGenericType &&
                         metadata.ModelType.GetGenericTypeDefinition().FullName == "System.Nullable`1" &&
                         metadata.ModelType.GetGenericArguments()[0].IsEnum
                         ) || (
                         typeof(IEnumerable).IsAssignableFrom(metadata.ModelType) &&
                         !typeof(string).IsAssignableFrom(metadata.ModelType) &&
                         metadata.ModelType.GetGenericArguments()[0].IsEnum
                         )
                     )
            {
                type = ElementType.Select;
                var list           = (IEnumerable <object>)EnumInfo.CreateList(metadata.ModelType.IsGenericType ? metadata.ModelType.GetGenericArguments()[0] : metadata.ModelType, fieldConfiguration.Exclude);
                var selectedValues = GetSelected(metadata.Model);
                selectList = new MultiSelectList(list, "Value", "Display", selectedValues);
            }

            foreach (var rule in validators.SelectMany(v => v.GetClientValidationRules()))
            {
                switch (rule.ValidationType)
                {
                case "range":
                    classes.Add(string.Format("range([{0},{1}])", rule.ValidationParameters["min"], rule.ValidationParameters["max"]));
                    break;

                case "min":
                    classes.Add(string.Format("min({0})", rule.ValidationParameters["min"]));
                    break;

                case "max":
                    classes.Add(string.Format("max({0})", rule.ValidationParameters["max"]));
                    break;

                case "regex":
                    classes.Add(string.Format("match(/{0}/)", rule.ValidationParameters["pattern"]));
                    break;

                case "length":
                case "maxlength":
                    if (type == ElementType.Text || type == ElementType.Password)
                    {
                        htmlAttrs["maxlength"] = rule.ValidationParameters["max"];
                    }
                    else
                    {
                        classes.Add(string.Format("maxlength({0})", rule.ValidationParameters["max"]));
                    }
                    break;

                case "minlength":
                    classes.Add(string.Format("minlength({0})", rule.ValidationParameters["min"]));
                    break;

                case "rangelength":
                    classes.Add(string.Format("rangelength([{0},{1}])", rule.ValidationParameters["min"], rule.ValidationParameters["max"]));
                    break;

                case "equalto":
                    classes.Add(string.Format("equalTo('#{0}')", rule.ValidationParameters["other"].ToString().Split('.')[1]));
                    labelHtml = labelHtml.Replace(" <em>(Optional)</em>", "");
                    break;

                case "existsin":
                    type       = ElementType.Select;
                    selectList = GetSelectListFromCollection(expression, metadata, rule);
                    break;

                case "grid":
                    grid = GetGrid(expression, metadata, rule);
                    break;

                case "notrequired":
                    labelHtml = labelHtml.Replace(" <em>(Optional)</em>", "");
                    break;

                case "filetype":
                    classes.Add(string.Format("accept('{0}')", rule.ValidationParameters["extension"]));
                    fieldConfiguration.Tip = fieldConfiguration.Tip ?? string.Format("Filetype must be: {0}", rule.ValidationParameters["pretty-extension"]);
                    break;
                }
            }

            if (classes.ToString().Trim() != "")
            {
                htmlAttrs["class"] = classes.ToString();
            }

            if (fieldConfiguration.As.HasValue)
            {
                var validOverride        = false;
                var overrideErrorMessage = "";
                switch (type)
                {
                case ElementType.Select:
                    switch (fieldConfiguration.As.Value)
                    {
                    case ElementType.Checkboxes:
                    case ElementType.RadioButtons:
                    case ElementType.Text:
                        type          = fieldConfiguration.As.Value;
                        validOverride = true;
                        break;
                    }
                    break;

                case ElementType.Text:
                    switch (fieldConfiguration.As.Value)
                    {
                    case ElementType.Checkboxes:
                    case ElementType.RadioButtons:
                    case ElementType.Select:
                        if (fieldConfiguration.PossibleValues != null)
                        {
                            selectList    = fieldConfiguration.PossibleValues;
                            type          = fieldConfiguration.As.Value;
                            validOverride = true;
                        }
                        else
                        {
                            overrideErrorMessage = "I was expecting a list.";
                        }
                        break;
                    }
                    break;
                }
                if (!validOverride)
                {
                    throw new ApplicationException(string.Format("FieldConfiguration{{ As = {0} }} not valid for field: {1} (which defaults to {2}). {3}",
                                                                 fieldConfiguration.As.Value, expression, type, overrideErrorMessage));
                }
            }

            var elementHtml = string.Empty;
            var errorHtml   = string.Empty;
            var isValid     = true;

            if (grid != null)
            {
                elementHtml = RenderGrid(grid, fieldConfiguration.ReadOnly);
                isValid     = GetErrors(expression, out errorHtml);
            }
            else
            {
                switch (type)
                {
                case ElementType.Text:
                    elementHtml = _htmlHelper.TextBoxFor(expression, htmlAttrs).ToHtmlString();
                    break;

                case ElementType.Password:
                    elementHtml = _htmlHelper.PasswordFor(expression, htmlAttrs).ToHtmlString();
                    break;

                case ElementType.TextArea:
                    elementHtml = _htmlHelper.TextAreaFor(expression, htmlAttrs).ToHtmlString();
                    break;

                case ElementType.Select:
                    if (typeof(IEnumerable).IsAssignableFrom(metadata.ModelType) &&
                        !typeof(string).IsAssignableFrom(metadata.ModelType))
                    {
                        elementHtml = _htmlHelper.ListBoxFor(expression, selectList, htmlAttrs).ToHtmlString();
                    }
                    else
                    {
                        elementHtml = _htmlHelper.DropDownListFor(expression, selectList, fieldConfiguration.Label, htmlAttrs).ToHtmlString();
                    }
                    break;

                case ElementType.Checkboxes:
                case ElementType.RadioButtons:
                    // TODO: Use HTML Attributes
                    var typeString = type == ElementType.Checkboxes ? "checkbox" : "radio";
                    elementHtml += HelperDefinitions.BeginInputList(typeString);
                    elementHtml += string.Join("", selectList.Select(i => HelperDefinitions.InputListItem(typeString, expression.GetFieldName(), i.Value, i.Text, i.Selected).ToString()));
                    elementHtml += HelperDefinitions.EndInputList();
                    break;
                }
                isValid = GetErrors(expression, out errorHtml);
            }

            elementHtml = (fieldConfiguration.Before ?? "") + elementHtml + (fieldConfiguration.After ?? "");

            return(new FlowFormField(_writer, containsSection, labelHtml, elementHtml, errorHtml, isValid, fieldConfiguration.Hint, fieldConfiguration.Tip, fieldConfiguration.HideTip, fieldConfiguration.HintClass, fieldConfiguration.ParentClass, fieldConfiguration.DisplayFieldName));
        }
Exemplo n.º 3
0
 /// <summary>
 /// Render the start of a basic flow form field for a property in the page model.
 /// </summary>
 /// <remarks>
 /// Will render the end of the field after Dispose() is called.<br />
 /// Usually, you would use this within a using block and then use the returned section to output nested fields, e.g.:<br />
 /// using (var ss = s.BeginFieldFor(m => m.MyField) {<br />
 ///     &#160; &#160; @ss.Field(...)<br />
 /// }
 /// </remarks>
 /// <typeparam name="TProperty">The type of the property in the model that is being rendered</typeparam>
 /// <param name="expression">m => m.PropertyFromPageModel</param>
 /// <param name="fieldConfiguration">Configuration data for the field</param>
 /// <param name="sectionId">Adds an id to the <![CDATA[<dl>]]> of the nested section</param>
 /// <returns>A FlowFormSection object that will be nested within this field and can be used to create nested fields</returns>
 public FlowFormSection <TModel> BeginFieldFor <TProperty>(Expression <Func <TModel, TProperty> > expression, FieldConfiguration fieldConfiguration = null, string sectionId = null)
 {
     return(new FlowFormSection <TModel>(_htmlHelper, true, null, sectionId, parentField: FieldFor(expression, true, fieldConfiguration)));
 }
Exemplo n.º 4
0
 /// <summary>
 /// Render a flow form field for a property in the page model.
 /// </summary>
 /// <typeparam name="TProperty">The type of the property in the model that is being rendered</typeparam>
 /// <param name="expression">m => m.PropertyFromPageModel</param>
 /// <param name="fieldConfiguration">Configuration data for the field</param>
 /// <returns>A FlowFormField object (has a ToString() that prints "" so can safely have @ in Razor before this call)</returns>
 public FlowFormField FieldFor <TProperty>(Expression <Func <TModel, TProperty> > expression, FieldConfiguration fieldConfiguration = null)
 {
     return(FieldFor(expression, false, fieldConfiguration));
 }
Exemplo n.º 5
0
        public FlowFormField RadioFor(Expression <Func <TModel, bool?> > expression, string falseLabel = "No", string trueLabel = "Yes", FieldConfiguration fieldConfiguration = null)
        {
            fieldConfiguration = fieldConfiguration ?? new FieldConfiguration();

            if (fieldConfiguration.As != null & fieldConfiguration.As != ElementType.RadioButtons)
            {
                throw new ApplicationException(string.Format("FieldConfiguration{{ As = {0} }} not valid for field: {1} (which defaults to RadioButton)."
                                                             , fieldConfiguration.As.Value, expression));
            }

            // var metadata = ModelMetadata.FromLambdaExpression(expression, _htmlHelper.ViewData);
            var value       = expression.Compile().Invoke(_htmlHelper.ViewData.Model);
            var elementHtml = HelperDefinitions.BooleanRadioNullable(expression.GetFieldName(), value, falseLabel, trueLabel).ToString();

            elementHtml = (fieldConfiguration.Before ?? "") + elementHtml + (fieldConfiguration.After ?? "");

            return(new FlowFormField(_writer, false, LabelHtml(expression, fieldConfiguration), elementHtml, null, true, fieldConfiguration.Hint, fieldConfiguration.Tip, fieldConfiguration.HideTip, fieldConfiguration.HintClass, fieldConfiguration.ParentClass, fieldConfiguration.DisplayFieldName));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Render the start of a basic flow form field with specified HTML for the label and element placeholders.
        /// </summary>
        /// <remarks>
        /// Will render the end of the field after Dispose() is called.<br />
        /// Usually, you would use this within a using block and then use the returned section to output nested fields, e.g.:<br />
        /// using (var ss = s.BeginField("MyLabel", new HtmlString("MyElement")) {<br />
        ///     &#160; &#160; @ss.Field(...)<br />
        /// }
        /// </remarks>
        /// <param name="expression">m => m.BooleanPropertyFromPageModel</param>
        /// <param name="label">The label to add after the checkbox element</param>
        /// <param name="fieldConfiguration">Configuration data for the field</param>
        /// <param name="sectionId">Adds an id to the &lt;dl&gt; of the nested section</param>
        /// <returns>A FlowFormSection object that will be nested within this field and can be used to create nested fields</returns>
        public FlowFormSection <TModel> BeginFieldFor(Expression <Func <TModel, bool> > expression, string label, FieldConfiguration fieldConfiguration = null, string sectionId = null)
        {
            fieldConfiguration = fieldConfiguration ?? new FieldConfiguration();

            var elementHtml = _htmlHelper.CheckBoxFor(expression, fieldConfiguration.HtmlAttributes).ToHtmlString() +
                              _htmlHelper.LabelFor(expression, label);

            string errorHtml;
            var    isValid = GetErrors(expression, out errorHtml);

            var field = new FlowFormField(_writer, true, LabelHtml(expression, fieldConfiguration), elementHtml, errorHtml, isValid, fieldConfiguration.Hint, fieldConfiguration.Tip, fieldConfiguration.HideTip, fieldConfiguration.HintClass, fieldConfiguration.ParentClass, fieldConfiguration.DisplayFieldName);

            return(new FlowFormSection <TModel>(_htmlHelper, true, null, sectionId, parentField: field));
        }