Пример #1
0
        /// <inheritdoc />
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            ModelExplorer modelExplorer = For.ModelExplorer;
            IDictionary <string, object>?htmlAttributes = null;

            // Pass through attributes that are also well-known HTML attributes.
            // Must be done prior to any copying from a TagBuilder.
            if (InputTypeName is not null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Name is not null)
            {
                output.CopyHtmlAttribute(nameof(Name), context);
            }

            if (Value is not null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            var inputType = string.IsNullOrEmpty(InputTypeName)
                                ? InputType.CheckBox.ToString().ToLowerInvariant()
                                : InputTypeName.ToLowerInvariant();

            // inputType may be more specific than default the generator chooses below.
            if (output.Attributes.ContainsName("type") != true)
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            // Ensure Generator does not throw due to empty "fullName" if user provided a name attribute.
            if (string.IsNullOrEmpty(For.Name) && string.IsNullOrEmpty(ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix) &&
                string.IsNullOrEmpty(Name) != true)
            {
                htmlAttributes = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase)
                {
                    { "name", Name },
                };
            }

            TagBuilder tagBuilder = GenerateCheckBox(modelExplorer, htmlAttributes);

            output.MergeAttributes(tagBuilder);
        }
        private TagBuilder GetTag()
        {
            var input1 = new TagBuilder("input")
            {
                TagRenderMode = TagRenderMode.StartTag
            };

            var type = InputTypeName?.ToLower();

            input1.Attributes.Add("readonly", null);
            // input1.Attributes.Add("type", type);
            input1.Attributes.Add("id", For.Name);
            input1.Attributes.Add("name", For.Name);
            input1.Attributes.Add("value", $"{For.Model}");

            return(input1);
        }
Пример #3
0
        /// <inheritdoc />
        /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
        /// <exception cref="InvalidOperationException">
        /// Thrown if <see cref="Format"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>.
        /// </exception>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.
            if (InputTypeName != null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient.
            // IHtmlGenerator will enforce name requirements.
            var metadata      = For.Metadata;
            var modelExplorer = For.ModelExplorer;

            if (metadata == null)
            {
                throw new InvalidOperationException(Resources.FormatTagHelpers_NoProvidedMetadata(
                                                        "<input>",
                                                        ForAttributeName,
                                                        nameof(IModelMetadataProvider),
                                                        For.Name));
            }

            string inputType;
            string inputTypeHint;

            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }
            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (!output.Attributes.ContainsName("type"))
            {
                output.Attributes["type"] = inputType;
            }

            TagBuilder tagBuilder;

            switch (inputType)
            {
            case "checkbox":
                GenerateCheckBox(modelExplorer, output);
                return;

            case "hidden":
                tagBuilder = Generator.GenerateHidden(
                    ViewContext,
                    modelExplorer,
                    For.Name,
                    value: For.Model,
                    useViewData: false,
                    htmlAttributes: null);
                break;

            case "password":
                tagBuilder = Generator.GeneratePassword(
                    ViewContext,
                    modelExplorer,
                    For.Name,
                    value: null,
                    htmlAttributes: null);
                break;

            case "radio":
                tagBuilder = GenerateRadio(modelExplorer);
                break;

            default:
                tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType);
                break;
            }

            if (tagBuilder != null)
            {
                // This TagBuilder contains the one <input/> element of interest. Since this is not the "checkbox"
                // special-case, output is a self-closing element no longer guaranteed.
                output.MergeAttributes(tagBuilder);
                output.Content.Append(tagBuilder.InnerHtml);
            }
        }
Пример #4
0
        /// <inheritdoc />
        /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
        /// <exception cref="InvalidOperationException">
        /// Thrown if <see cref="Format"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>.
        /// </exception>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.
            if (InputTypeName != null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Name != null)
            {
                output.CopyHtmlAttribute(nameof(Name), context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient.
            // IHtmlGenerator will enforce name requirements.
            var metadata      = For.Metadata;
            var modelExplorer = For.ModelExplorer;

            if (metadata == null)
            {
                throw new InvalidOperationException(Resources.FormatTagHelpers_NoProvidedMetadata(
                                                        "<input>",
                                                        ForAttributeName,
                                                        nameof(IModelMetadataProvider),
                                                        For.Name));
            }

            string inputType;
            string inputTypeHint;

            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }
            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (!output.Attributes.ContainsName("type"))
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            // Ensure Generator does not throw due to empty "fullName" if user provided a name attribute.
            IDictionary <string, object> htmlAttributes = null;

            if (string.IsNullOrEmpty(For.Name) &&
                string.IsNullOrEmpty(ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix) &&
                !string.IsNullOrEmpty(Name))
            {
                htmlAttributes = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase)
                {
                    { "name", Name },
                };
            }

            TagBuilder tagBuilder;

            switch (inputType)
            {
            case "hidden":
                tagBuilder = GenerateHidden(modelExplorer, htmlAttributes);
                break;

            case "checkbox":
                tagBuilder = GenerateCheckBox(modelExplorer, output, htmlAttributes);
                break;

            case "password":
                tagBuilder = Generator.GeneratePassword(
                    ViewContext,
                    modelExplorer,
                    For.Name,
                    value: null,
                    htmlAttributes: htmlAttributes);
                break;

            case "radio":
                tagBuilder = GenerateRadio(modelExplorer, htmlAttributes);
                break;

            default:
                tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType, htmlAttributes);
                break;
            }

            if (tagBuilder != null)
            {
                // This TagBuilder contains the one <input/> element of interest.
                output.MergeAttributes(tagBuilder);
                if (tagBuilder.HasInnerHtml)
                {
                    // Since this is not the "checkbox" special-case, no guarantee that output is a self-closing
                    // element. A later tag helper targeting this element may change output.TagMode.
                    output.Content.AppendHtml(tagBuilder.InnerHtml);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Synchronously executes the <see
        /// cref="T:Microsoft.AspNetCore.Razor.TagHelpers.TagHelper"/> with the given <paramref
        /// name="context"/> and <paramref name="output"/>.
        /// </summary>
        /// <param name="context">Contains information associated with the current HTML tag.</param>
        /// <param name="output">A stateful HTML element used to generate an HTML tag.</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (ForAttribute == null)
            {
                return;
            }

            if (InputTypeName != null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            var metadata      = ForAttribute.Metadata;
            var modelExplorer = ForAttribute.ModelExplorer;

            if (metadata == null)
            {
                throw new InvalidOperationException(
                          string.Format("The {2} was unable to provide metadata about '{1}' expression value '{3}' for {0}.",
                                        "<input>",
                                        "qf-for",
                                        nameof(IModelMetadataProvider),
                                        ForAttribute.Name));
            }

            string inputType;
            string inputTypeHint;

            if (string.IsNullOrEmpty(InputTypeName))
            {
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }
            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            var format = string.IsNullOrEmpty(Format) ? GetFormat(modelExplorer, inputTypeHint, inputType) : Format;

            if (format == "checkbox")
            {
                GenerateCheckBox(modelExplorer, output, ForAttribute);
            }
            else
            {
                var val = string.IsNullOrEmpty(Value) ? ForAttribute.Model : Value;
                if (modelExplorer.ModelType == typeof(DateTime) || modelExplorer.ModelType == typeof(DateTimeOffset))
                {
                    DateTime convertedValue = default(DateTime);
                    DateTime.TryParse(val.ToString(), out convertedValue);
                    if (convertedValue == default(DateTime))
                    {
                        return;
                    }
                }
                var formattedVal = string.IsNullOrEmpty(format)
                                        ? Convert.ToString(val, CultureInfo.CurrentCulture)
                                        : string.Format(format, val);
                output.PostContent.AppendHtml(formattedVal);
            }
        }
Пример #6
0
        /// <inheritdoc/>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.
            if (InputTypeName != null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            string inputType;
            string inputTypeHint;

            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(Column, out inputTypeHint);
            }
            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (!output.Attributes.ContainsName("type"))
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            TagBuilder tagBuilder;

            switch (inputType)
            {
            case "hidden":
                tagBuilder = GenerateHidden();
                break;

            case "checkbox":
                tagBuilder = GenerateCheckBox(output);
                break;

            case "password":
                tagBuilder = Generator.GeneratePassword(ViewContext, FullHtmlFieldName, Column, value: null, htmlAttributes: null);
                break;

            case "radio":
                tagBuilder = GenerateRadio();
                break;

            default:
                tagBuilder = GenerateTextBox(inputTypeHint, inputType);
                break;
            }

            if (tagBuilder != null)
            {
                // This TagBuilder contains the one <input/> element of interest.
                output.MergeAttributes(tagBuilder);
                if (tagBuilder.HasInnerHtml)
                {
                    // Since this is not the "checkbox" special-case, no guarantee that output is a self-closing
                    // element. A later tag helper targeting this element may change output.TagMode.
                    output.Content.AppendHtml(tagBuilder.InnerHtml);
                }
            }
        }
Пример #7
0
        /// <inheritdoc />
        /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
        /// <exception cref="InvalidOperationException">
        /// Thrown if <see cref="Format"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>.
        /// </exception>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            var validations = output.Attributes.Where(x => x.Name.ToString().Contains("data-val-")).ToArray();

            if (LanguageSupport && validations.Any())
            {
                foreach (var validation in validations)
                {
                    output.Attributes.RemoveAll(validation.Name);
                    string message = validation.Value.ToString();
                    output.Attributes.Add(validation.Name, languageProviderService.GetlangByKey(message));
                }
            }


            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.
            if (InputTypeName != null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient.
            // IHtmlGenerator will enforce name requirements.
            ModelMetadata metadata      = For.Metadata;
            ModelExplorer modelExplorer = For.ModelExplorer;

            if (metadata == null)
            {
                return;
            }

            string inputType;
            string inputTypeHint;

            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }
            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (!output.Attributes.ContainsName("type"))
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            TagBuilder tagBuilder;

            switch (inputType)
            {
            case "hidden":
                tagBuilder = GenerateHidden(modelExplorer);
                break;

            case "checkbox":
                GenerateCheckBox(modelExplorer, output);
                return;

            case "password":
                tagBuilder = Generator.GeneratePassword(
                    ViewContext,
                    modelExplorer,
                    For.Name,
                    value: null,
                    htmlAttributes: null);
                break;

            case "radio":
                tagBuilder = GenerateRadio(modelExplorer);
                break;

            default:
                tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType);
                break;
            }

            if (tagBuilder != null)
            {
                // This TagBuilder contains the one <input/> element of interest.
                output.MergeAttributes(tagBuilder);
                if (tagBuilder.HasInnerHtml)
                {
                    // Since this is not the "checkbox" special-case, no guarantee that output is a self-closing
                    // element. A later tag helper targeting this element may change output.TagMode.
                    output.Content.AppendHtml(tagBuilder.InnerHtml);
                }
            }
        }
Пример #8
0
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            var modelExplorer = For.ModelExplorer;

            InputTypeName = InputTypeName == null ? null : InputTypeName.Trim().ToLowerInvariant();
            string min = string.IsNullOrEmpty(Min)? null : Min, max = string.IsNullOrEmpty(Max)? null : Max;

            var metaData = modelExplorer.Metadata;
            var utype    = modelExplorer.Metadata.UnderlyingOrModelType;
            var typeName = utype.Name.ToLowerInvariant();
            var hint     = (metaData.DataTypeName ?? metaData.TemplateHint)?.ToLowerInvariant();

            if (string.IsNullOrEmpty(InputTypeName) && !output.Attributes.ContainsName("type"))
            {
                string type = null;
                if (hint == "color")
                {
                    type = hint;
                }
                else if (typeName == "single" || typeName == "double" || typeName == "decimal")
                {
                    type = "number";
                }
                else if (typeName == "week" || typeName == "month")
                {
                    type = typeName;
                }
                else if (typeName == "datetimeoffset" || (typeName == "datetime" && string.IsNullOrEmpty(hint)))
                {
                    type = "datetime-local";
                }

                if (type != null)
                {
                    output.Attributes.Add("type", type);
                }
            }
            bool isDecimal = typeName == "single" || typeName == "double" || typeName == "decimal";

            bool isNumber    = (string.IsNullOrEmpty(InputTypeName) || InputTypeName == "number" || InputTypeName == "range");
            bool isPositive  = positiveIntegerTypes.Contains(typeName);
            bool isIntegerNP = integerTypes.Contains(typeName);


            bool isHtml5DateTime = (string.IsNullOrEmpty(InputTypeName) || InputTypeName == "date" || InputTypeName == "datetime" || InputTypeName == "datetime-local" || InputTypeName == "week" || InputTypeName == "month");
            bool isDateTimeType  = typeName == "datetime" || typeName == "timespan" || typeName == "week" || typeName == "month" || typeName == "datetimeoffset";

            if (isDecimal || isPositive || isIntegerNP)
            {
                output.Attributes.Add("data-basic-type", "numeric");
            }
            else if (isDateTimeType)
            {
                output.Attributes.Add("data-basic-type", "time");
            }
            else
            {
                output.Attributes.Add("data-basic-type", "string");
            }
            object         minimum = null, maximum = null;
            RangeAttribute limits = metaData.ValidatorMetadata.Where(m => m is RangeAttribute).FirstOrDefault() as RangeAttribute;

            if (limits != null)
            {
                minimum = limits.Minimum;
                maximum = limits.Maximum;
            }
            else
            {
                DynamicRangeAttribute limitsExt = metaData.ValidatorMetadata.Where(m => m is DynamicRangeAttribute).FirstOrDefault() as DynamicRangeAttribute;
                if (limitsExt != null)
                {
                    List <string> a, b;
                    maximum = limitsExt.GetGlobalMaximum(modelExplorer.Container.Model, out a, out b);
                    minimum = limitsExt.GetGlobalMinimum(modelExplorer.Container.Model, out a, out b);
                }
            }

            if (string.IsNullOrWhiteSpace(Value) && ((isNumber && (isPositive || isIntegerNP || isDecimal)) || (isHtml5DateTime && isDateTimeType)))

            {
                string value = modelExplorer.Model == null ? null : coverter(modelExplorer.Model, hint);
                if (!string.IsNullOrEmpty(value))
                {
                    if (!output.Attributes.ContainsName("value"))
                    {
                        output.Attributes.Add("value", value);
                    }
                }
            }
            if (typeName == "week")
            {
                string value = modelExplorer.Model == null ? "" : ((Week)modelExplorer.Model).StartDate().ToString("yyyy-MM-dd");

                output.Attributes.Add("data-date-value", value);
            }
            if (minimum != null || maximum != null)
            {
                if (min == null && minimum != null)
                {
                    if (isNumber && isPositive)
                    {
                        var trueMin = ((minimum is string) ? Convert.ChangeType(minimum, limits.OperandType, CultureInfo.InvariantCulture) : minimum) as IComparable;
                        if (trueMin.CompareTo(Convert.ChangeType("0", trueMin.GetType())) < 0)
                        {
                            min = "0";
                        }
                        else
                        {
                            min = (trueMin as IFormattable).ToString(null, CultureInfo.InvariantCulture);
                        }
                    }
                    else if (isNumber && (isIntegerNP || isDecimal))
                    {
                        min = (minimum is string) ? minimum as string : (minimum as IConvertible).ToString(CultureInfo.InvariantCulture);
                    }
                    else if (isHtml5DateTime && isDateTimeType)
                    {
                        if (utype == typeof(DateTimeOffset))
                        {
                            min = processDTOffsetValue(minimum);
                        }
                        else
                        {
                            min = (minimum is string) ? minimum as string : (minimum is IConvertible ? coverter(minimum, hint) : minimum.ToString());
                        }
                    }
                }
                if (max == null && maximum != null)
                {
                    if (isNumber && (isPositive || isIntegerNP || isDecimal))
                    {
                        max = (maximum is string) ? maximum as string : (maximum as IConvertible).ToString(CultureInfo.InvariantCulture);
                    }
                    else if (isHtml5DateTime && isDateTimeType)
                    {
                        if (utype == typeof(DateTimeOffset))
                        {
                            max = processDTOffsetValue(maximum);
                        }
                        else
                        {
                            max = (maximum is string) ? maximum as string : (maximum is IConvertible ? coverter(maximum, hint) : maximum.ToString());
                        }
                    }
                }
            }
            if (utype == typeof(DateTimeOffset))
            {
                output.Attributes.Add("data-is-utc", "true");
            }
            if (isNumber && isPositive && min == null)
            {
                min = "0";
            }
            if (min != null)
            {
                if (output.Attributes.ContainsName("min"))
                {
                    output.Attributes.Remove(output.Attributes["min"]);
                }
                output.Attributes.Add("min", min);
            }
            if (max != null)
            {
                if (output.Attributes.ContainsName("max"))
                {
                    output.Attributes.Remove(output.Attributes["max"]);
                }
                output.Attributes.Add("max", max);
            }
            if (InputTypeName == "range")
            {
                var fullName = ViewContext.ViewData.GetFullHtmlFieldName(For.Name);
                fullName = fullName.Length > 0 ? fullName + "._" : "_";
                output.PostElement.AppendHtml("<input name='" + fullName + "' type='hidden'/>");
            }
            else if (utype == typeof(DateTimeOffset))
            {
                var fullName = ViewContext.ViewData.GetFullHtmlFieldName(For.Name);
                fullName = fullName.Length > 0 ? fullName + ".O" : "O";
                output.PostElement.AppendHtml("<input name='" + fullName + "' type='hidden' value='0' />");
            }
        }
Пример #9
0
        /// <inheritdoc />
        /// <remarks>Does nothing if <see cref="For"/> is <c>null</c></remarks>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.
            if (!string.IsNullOrEmpty(InputTypeName))
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            if (For == null)
            {
                // Regular HTML <input/> element. Just make sure Format wasn't specified.
                if (Format != null)
                {
                    throw new InvalidOperationException(Resources.FormatInputTagHelper_UnableToFormat(
                                                            "<input>",
                                                            nameof(For).ToLowerInvariant(),
                                                            nameof(Format).ToLowerInvariant()));
                }
            }
            else
            {
                // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient.
                // IHtmlGenerator will enforce name requirements.
                var metadata = For.Metadata;
                if (metadata == null)
                {
                    throw new InvalidOperationException(Resources.FormatTagHelpers_NoProvidedMetadata(
                                                            "<input>",
                                                            nameof(For).ToLowerInvariant(),
                                                            nameof(IModelMetadataProvider),
                                                            For.Name));
                }

                string inputType;
                string inputTypeHint;
                if (string.IsNullOrEmpty(InputTypeName))
                {
                    inputType = GetInputType(metadata, out inputTypeHint);
                }
                else
                {
                    inputType     = InputTypeName.ToLowerInvariant();
                    inputTypeHint = null;
                }

                if (!string.IsNullOrEmpty(inputType))
                {
                    // inputType may be more specific than default the generator chooses below.
                    // TODO: Use Attributes.ContainsKey once aspnet/Razor#186 is fixed.
                    if (!output.Attributes.Any(
                            item => string.Equals("type", item.Key, StringComparison.OrdinalIgnoreCase)))
                    {
                        output.Attributes["type"] = inputType;
                    }
                }

                TagBuilder tagBuilder;
                switch (inputType)
                {
                case "checkbox":
                    GenerateCheckBox(metadata, output);
                    return;

                case "hidden":
                    tagBuilder = Generator.GenerateHidden(
                        ViewContext,
                        metadata,
                        For.Name,
                        value: metadata.Model,
                        useViewData: false,
                        htmlAttributes: null);
                    break;

                case "password":
                    tagBuilder = Generator.GeneratePassword(
                        ViewContext,
                        metadata,
                        For.Name,
                        value: null,
                        htmlAttributes: null);
                    break;

                case "radio":
                    tagBuilder = GenerateRadio(metadata);
                    break;

                default:
                    tagBuilder = GenerateTextBox(metadata, inputTypeHint, inputType);
                    break;
                }

                if (tagBuilder != null)
                {
                    // This TagBuilder contains the one <input/> element of interest. Since this is not the "checkbox"
                    // special-case, output is a self-closing element and can merge the TagBuilder in directly.
                    output.SelfClosing = true;
                    output.Merge(tagBuilder);
                }
            }
        }
Пример #10
0
        public InputModelInfo(
            IHtmlGenerator generator,
            ModelExpression forModelExp,
            string format,
            string inputTypeName,             // <- [HtmlAttributeName("type")]
            string value,
            string placeholder,
            string labelText,
            ViewContext viewContext)
            : base(generator)
        {
            base.For           = forModelExp;
            base.Format        = format;
            base.InputTypeName = inputTypeName;
            base.Value         = value;
            base.ViewContext   = viewContext;
            HtmlFieldPrefix    = ViewContext?.ViewData?.TemplateInfo?.HtmlFieldPrefix;

            Name         = For.Name;
            FullName     = ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(Name);
            PropertyName = Meta.PropertyName;
            FullNameId   = TagBuilder.CreateSanitizedId(FullName, "_");

            if (placeholder.NotNulle())
            {
                Placeholder = placeholder.HtmlEncode(undoApostropheEsc: true);                 // important for placeholder
            }
            LabelText = labelText.NotNulle() && labelText.IsNullOrWhiteSpace()
                                ? "&#160;"
                                : labelText.FirstNotNulle(GetLabelText()).HtmlEncode();

            // THIS allows them to send in " " (space) if they want no label, but we can't treat empty as that,
            // because e.g. label="" sends in empty not null, but what about label="@Model.Prop", want to allow
            // a default to fall back if default is not set

            if (InputTypeName.IsNulle())
            {
                InputTypeName = GetInputType(For.ModelExplorer, out string inputTypeHint);
                // Note GetInputType never returns null.
                // Nick's note: If none defaults to "text", so do NOT set that default yourself anywhere else, this will handle
                InputTypeHint = inputTypeHint;
            }
            else
            {
                InputTypeName = InputTypeName.ToLowerInvariant();
                InputTypeHint = null;
            }

            if (For.Metadata == null)
            {
                ThrowExOnMetadataNull(ForAttributeName, Name);
            }

            if (Format.IsNulle())
            {
                Format = GetFormat(For.ModelExplorer, InputTypeHint, InputTypeName);
            }

            Type t = ModelType = this.ModelExplorer?.ModelType;

            if (t != null)
            {
                if (!t.IsPrimitive)
                {
                    NullableBaseType = t.GetUnderlyingTypeIfNullable();
                }

                t = MainType;
                TypeAllowsStringBasedEqualityComparison =
                    t.IsPrimitive || t.IsEnum || ExtraPrimitiveTypesAllowingStringBasedEqualityChecks.ContainsKey(t);
            }
        }
Пример #11
0
        /// <inheritdoc />
        /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
        /// <exception cref="InvalidOperationException">
        /// Thrown if <see cref="Format"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>.
        /// </exception>
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.
            if (InputTypeName != null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient.
            // IHtmlGenerator will enforce name requirements.
            var metadata      = For.Metadata;
            var modelExplorer = For.ModelExplorer;

            if (metadata == null)
            {
                throw new InvalidOperationException();
            }

            string inputType;
            string inputTypeHint;

            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }
            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (!output.Attributes.ContainsName("type"))
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            TagBuilder tagBuilder;

            switch (inputType)
            {
            case "checkbox":
                GenerateCheckBox(modelExplorer, output);
                return;

            case "hidden":
                tagBuilder = Generator.GenerateHidden(
                    ViewContext,
                    modelExplorer,
                    For.Name,
                    value: For.Model,
                    useViewData: false,
                    htmlAttributes: null);
                break;

            case "password":
                tagBuilder = Generator.GeneratePassword(
                    ViewContext,
                    modelExplorer,
                    For.Name,
                    value: null,
                    htmlAttributes: null);
                break;

            case "radio":
                tagBuilder = GenerateRadio(modelExplorer);
                break;

            default:
                tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType);
                break;
            }

            if (tagBuilder != null)
            {
                ServiceContext serviceContext = ViewContext.ViewBag.ServiceContext;
                string         modelPath      = serviceContext.RootName + "." + ModelHelper.GetMetadataModelPath(For.Name);

                ElementMetadata elementData = null;
                if (serviceContext?.ServiceMetaData.Elements.ContainsKey(modelPath) == true)
                {
                    elementData = serviceContext.ServiceMetaData.Elements[modelPath];
                }

                if (elementData != null && elementData.IsReadOnly)
                {
                    output.Attributes.Add("disabled", null);
                }

                // This TagBuilder contains the one <input/> element of interest. Since this is not the "checkbox"
                // special-case, output is a self-closing element no longer guaranteed.
                output.MergeAttributes(tagBuilder);
                output.Content.AppendHtml(tagBuilder.InnerHtml);
                ReplaceAttributeTextKeysWithText(output, serviceContext);
            }
        }
Пример #12
0
        /// <inheritdoc />
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            string        inputType;
            string?       inputTypeHint;
            ModelExplorer modelExplorer = For.ModelExplorer;
            IDictionary <string, object>?htmlAttributes = null;

            // Pass through attributes that are also well-known HTML attributes.
            // Must be done prior to any copying from a TagBuilder.
            if (InputTypeName is not null)
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Name is not null)
            {
                output.CopyHtmlAttribute(nameof(Name), context);
            }

            if (Value is not null)
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            output.Attributes.SetAttribute(nameof(Appearance), Appearance.ToString().ToLowerInvariant());

            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }

            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (output.Attributes.ContainsName("type") != true)
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            // Ensure Generator does not throw due to empty "fullName" if user provided a name attribute.
            if (string.IsNullOrEmpty(For.Name) && string.IsNullOrEmpty(ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix) &&
                string.IsNullOrEmpty(Name) != true)
            {
                htmlAttributes = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase)
                {
                    { "name", Name },
                };
            }

            TagBuilder tagBuilder = inputType switch
            {
                "password" => GeneratePasswordField(modelExplorer, htmlAttributes),
                _ => GenerateTextField(modelExplorer, inputTypeHint, inputType, htmlAttributes),
            };

            output.MergeAttributes(tagBuilder);
        }
Пример #13
0
        public TagBuilder ProcessTagBuilder(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying
            // from a TagBuilder.

            // NP: Had to add && context.AllAttributes.ContainsName("type") because CopyHtmlAttribute expects value in context attributes
            // issue is that we already set the InputTypeName in the constructor (with our different usage). I THINK these values
            // are only set if THE USER sent in a value in the tags...
            if (InputTypeName != null && context.AllAttributes.ContainsName("type"))
            {
                output.CopyHtmlAttribute("type", context);
            }

            if (Value != null && context.AllAttributes.ContainsName(nameof(Value)))
            {
                output.CopyHtmlAttribute(nameof(Value), context);
            }

            // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient.
            // IHtmlGenerator will enforce name requirements.
            var metadata      = For.Metadata;
            var modelExplorer = For.ModelExplorer;

            if (metadata == null)
            {
                ThrowExOnMetadataNull(ForAttributeName, For.Name);
            }

            string inputType;
            string inputTypeHint;

            if (string.IsNullOrEmpty(InputTypeName))
            {
                // Note GetInputType never returns null.
                inputType = GetInputType(modelExplorer, out inputTypeHint);
            }
            else
            {
                inputType     = InputTypeName.ToLowerInvariant();
                inputTypeHint = null;
            }

            // inputType may be more specific than default the generator chooses below.
            if (!output.Attributes.ContainsName("type"))
            {
                output.Attributes.SetAttribute("type", inputType);
            }

            TagBuilder tagBuilder;

            switch (inputType)
            {
            case "hidden":
                tagBuilder = GenerateHidden(modelExplorer, null);
                break;

            case "checkbox":
                tagBuilder = GenerateCheckBox(modelExplorer, output, null);
                break;

            case "password":
                tagBuilder = Generator.GeneratePassword(
                    ViewContext,
                    modelExplorer,
                    For.Name,
                    value: null,
                    htmlAttributes: null);
                break;

            case "radio":
                tagBuilder = GenerateRadio(modelExplorer, null);
                break;

            default:
                tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType, null);
                break;
            }
            return(tagBuilder);
        }
Пример #14
0
    public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        var inputType = string.IsNullOrEmpty(InputTypeName) ? GetInputType(For.ModelExplorer, out _) : InputTypeName.ToLowerInvariant();

        if (inputType != "checkbox")
        {
            output.AddClass("form-control", HtmlEncoder.Default);
        }
        return(Task.CompletedTask);
    }