parent
557974b948
commit
2fd51c82f9
|
|
@ -107,19 +107,35 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cannot parse '{1}' value '{2}' for {0}. Acceptable values are '{3}', '{4}' and '{5}'.
|
/// Cannot determine body for {0}. '{2}' must be null if '{1}' is null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string ValidationSummaryTagHelper_InvalidValidationSummaryValue
|
internal static string SelectTagHelper_CannotDetermineContentWhenOnlyItemsSpecified
|
||||||
{
|
{
|
||||||
get { return GetString("ValidationSummaryTagHelper_InvalidValidationSummaryValue"); }
|
get { return GetString("SelectTagHelper_CannotDetermineContentWhenOnlyItemsSpecified"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cannot determine body for {0}. '{2}' must be null if '{1}' is null.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatSelectTagHelper_CannotDetermineContentWhenOnlyItemsSpecified(object p0, object p1, object p2)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("SelectTagHelper_CannotDetermineContentWhenOnlyItemsSpecified"), p0, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cannot parse '{1}' value '{2}' for {0}. Acceptable values are '{3}', '{4}' and '{5}'.
|
/// Cannot parse '{1}' value '{2}' for {0}. Acceptable values are '{3}', '{4}' and '{5}'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string FormatValidationSummaryTagHelper_InvalidValidationSummaryValue(object p0, object p1, object p2, object p3, object p4, object p5)
|
internal static string TagHelpers_InvalidValue_ThreeAcceptableValues
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("ValidationSummaryTagHelper_InvalidValidationSummaryValue"), p0, p1, p2, p3, p4, p5);
|
get { return GetString("TagHelpers_InvalidValue_ThreeAcceptableValues"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cannot parse '{1}' value '{2}' for {0}. Acceptable values are '{3}', '{4}' and '{5}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatTagHelpers_InvalidValue_ThreeAcceptableValues(object p0, object p1, object p2, object p3, object p4, object p5)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelpers_InvalidValue_ThreeAcceptableValues"), p0, p1, p2, p3, p4, p5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,10 @@
|
||||||
<data name="FormTagHelper_CannotDetermineAction" xml:space="preserve">
|
<data name="FormTagHelper_CannotDetermineAction" xml:space="preserve">
|
||||||
<value>Cannot determine an '{1}' for {0}. A {0} with a URL-based '{1}' must not have attributes starting with '{3}' or a '{2}' attribute.</value>
|
<value>Cannot determine an '{1}' for {0}. A {0} with a URL-based '{1}' must not have attributes starting with '{3}' or a '{2}' attribute.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ValidationSummaryTagHelper_InvalidValidationSummaryValue" xml:space="preserve">
|
<data name="SelectTagHelper_CannotDetermineContentWhenOnlyItemsSpecified" xml:space="preserve">
|
||||||
|
<value>Cannot determine body for {0}. '{2}' must be null if '{1}' is null.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TagHelpers_InvalidValue_ThreeAcceptableValues" xml:space="preserve">
|
||||||
<value>Cannot parse '{1}' value '{2}' for {0}. Acceptable values are '{3}', '{4}' and '{5}'.</value>
|
<value>Cannot parse '{1}' value '{2}' for {0}. Acceptable values are '{3}', '{4}' and '{5}'.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TagHelpers_NoProvidedMetadata" xml:space="preserve">
|
<data name="TagHelpers_NoProvidedMetadata" xml:space="preserve">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||||
|
using Microsoft.AspNet.Razor.TagHelpers;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="ITagHelper"/> implementation targeting <select> elements.
|
||||||
|
/// </summary>
|
||||||
|
[ContentBehavior(ContentBehavior.Append)]
|
||||||
|
public class SelectTagHelper : TagHelper
|
||||||
|
{
|
||||||
|
// Protected to ensure subclasses are correctly activated. Internal for ease of use when testing.
|
||||||
|
[Activate]
|
||||||
|
protected internal IHtmlGenerator Generator { get; set; }
|
||||||
|
|
||||||
|
// Protected to ensure subclasses are correctly activated. Internal for ease of use when testing.
|
||||||
|
[Activate]
|
||||||
|
protected internal ViewContext ViewContext { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An expression to be evaluated against the current model.
|
||||||
|
/// </summary>
|
||||||
|
public ModelExpression For { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies that multiple options can be selected at once.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Passed through to the generated HTML if value is <c>multiple</c>. Converted to <c>multiple</c> or absent if
|
||||||
|
/// value is <c>true</c> or <c>false</c>. Other values are not acceptable. Also used to determine the correct
|
||||||
|
/// "selected" attributes for generated <option> elements.
|
||||||
|
/// </remarks>
|
||||||
|
public string Multiple { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of <see cref="SelectListItem"/> objects used to populate the <select> element with
|
||||||
|
/// <optgroup> and <option> elements.
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<SelectListItem> Items { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
/// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks>
|
||||||
|
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||||
|
{
|
||||||
|
if (For == null)
|
||||||
|
{
|
||||||
|
// Regular HTML <select/> element. Just make sure Items wasn't specified.
|
||||||
|
if (Items != null)
|
||||||
|
{
|
||||||
|
var message = Resources.FormatSelectTagHelper_CannotDetermineContentWhenOnlyItemsSpecified(
|
||||||
|
"<select>",
|
||||||
|
nameof(For).ToLowerInvariant(),
|
||||||
|
nameof(Items).ToLowerInvariant());
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass through attribute that is also a well-known HTML attribute.
|
||||||
|
if (!string.IsNullOrEmpty(Multiple))
|
||||||
|
{
|
||||||
|
output.CopyHtmlAttribute(nameof(Multiple), context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(
|
||||||
|
"<select>",
|
||||||
|
nameof(For).ToLowerInvariant(),
|
||||||
|
nameof(IModelMetadataProvider),
|
||||||
|
For.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool allowMultiple;
|
||||||
|
if (string.IsNullOrEmpty(Multiple))
|
||||||
|
{
|
||||||
|
// Base allowMultiple on the instance or declared type of the expression.
|
||||||
|
var realModelType = For.Metadata.RealModelType;
|
||||||
|
allowMultiple =
|
||||||
|
typeof(string) != realModelType && typeof(IEnumerable).IsAssignableFrom(realModelType);
|
||||||
|
}
|
||||||
|
else if (string.Equals(Multiple, "multiple", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
allowMultiple = true;
|
||||||
|
|
||||||
|
// Copy exact attribute name and value the user entered. Must be done prior to any copying from a
|
||||||
|
// TagBuilder. Not done in next case because "true" and "false" aren't valid for the HTML 5
|
||||||
|
// attribute.
|
||||||
|
output.CopyHtmlAttribute(nameof(Multiple), context);
|
||||||
|
}
|
||||||
|
else if (!bool.TryParse(Multiple.ToLowerInvariant(), out allowMultiple))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(Resources.FormatTagHelpers_InvalidValue_ThreeAcceptableValues(
|
||||||
|
"<select>",
|
||||||
|
nameof(Multiple).ToLowerInvariant(),
|
||||||
|
Multiple,
|
||||||
|
bool.FalseString.ToLowerInvariant(),
|
||||||
|
bool.TrueString.ToLowerInvariant(),
|
||||||
|
nameof(Multiple).ToLowerInvariant())); // acceptable value (as well as attribute name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure GenerateSelect() _never_ looks anything up in ViewData.
|
||||||
|
var items = Items ?? Enumerable.Empty<SelectListItem>();
|
||||||
|
|
||||||
|
var tagBuilder = Generator.GenerateSelect(
|
||||||
|
ViewContext,
|
||||||
|
For.Metadata,
|
||||||
|
optionLabel: null,
|
||||||
|
name: For.Name,
|
||||||
|
selectList: items,
|
||||||
|
allowMultiple: allowMultiple,
|
||||||
|
htmlAttributes: null);
|
||||||
|
|
||||||
|
if (tagBuilder != null)
|
||||||
|
{
|
||||||
|
output.SelfClosing = false;
|
||||||
|
output.Merge(tagBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
||||||
if (!Enum.TryParse(ValidationSummaryValue, ignoreCase: true, result: out validationSummaryValue))
|
if (!Enum.TryParse(ValidationSummaryValue, ignoreCase: true, result: out validationSummaryValue))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
Resources.FormatValidationSummaryTagHelper_InvalidValidationSummaryValue(
|
Resources.FormatTagHelpers_InvalidValue_ThreeAcceptableValues(
|
||||||
"<div>",
|
"<div>",
|
||||||
"validation-summary",
|
"validation-summary",
|
||||||
ValidationSummaryValue,
|
ValidationSummaryValue,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue