parent
93774a0234
commit
f95d49c870
|
|
@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{ "Url", "url" },
|
||||
{ "EmailAddress", "email" },
|
||||
{ "Date", "date" },
|
||||
{ "DateTime", "datetime" },
|
||||
{ "DateTime", "datetime-local" },
|
||||
{ "DateTime-local", "datetime-local" },
|
||||
{ "Time", "time" },
|
||||
{ nameof(Byte), "number" },
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
|
|||
{ "Text", DefaultEditorTemplates.StringTemplate },
|
||||
{ "Url", DefaultEditorTemplates.UrlInputTemplate },
|
||||
{ "Date", DefaultEditorTemplates.DateInputTemplate },
|
||||
{ "DateTime", DefaultEditorTemplates.DateTimeInputTemplate },
|
||||
{ "DateTime", DefaultEditorTemplates.DateTimeLocalInputTemplate },
|
||||
{ "DateTime-local", DefaultEditorTemplates.DateTimeLocalInputTemplate },
|
||||
{ "Time", DefaultEditorTemplates.TimeInputTemplate },
|
||||
{ typeof(byte).Name, DefaultEditorTemplates.NumberInputTemplate },
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
<validationMessageElement class=""field-validation-error"">An error occurred.</validationMessageElement>
|
||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||
<div class=""editor-label""><label for=""MyDate"">MyDate</label></div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime"" value=""2000-01-02T03:04:05.060+00:00"" /> </div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime-local"" value=""2000-01-02T03:04:05.060"" /> </div>
|
||||
|
||||
<div class=""validation-summary-errors""><validationSummaryElement>MySummary</validationSummaryElement>
|
||||
<ul><li>A model error occurred.</li>
|
||||
|
|
@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
<validationMessageElement class=""field-validation-error"">An error occurred.</validationMessageElement>
|
||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||
<div class=""editor-label""><label for=""MyDate"">MyDate</label></div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime"" value=""2000-01-02T03:04:05.060+00:00"" /> </div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime-local"" value=""2000-01-02T03:04:05.060"" /> </div>
|
||||
|
||||
False";
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ False";
|
|||
<ValidationInView class=""field-validation-error"" data-valmsg-for=""Error"" data-valmsg-replace=""true"">An error occurred.</ValidationInView>
|
||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||
<div class=""editor-label""><label for=""MyDate"">MyDate</label></div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" data-val=""true"" data-val-required=""The MyDate field is required."" id=""MyDate"" name=""MyDate"" type=""datetime"" value=""02/01/2000 03:04:05 +00:00"" /> <ValidationInView class=""field-validation-valid"" data-valmsg-for=""MyDate"" data-valmsg-replace=""true""></ValidationInView></div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" data-val=""true"" data-val-required=""The MyDate field is required."" id=""MyDate"" name=""MyDate"" type=""datetime-local"" value=""02/01/2000 03:04:05 +00:00"" /> <ValidationInView class=""field-validation-valid"" data-valmsg-for=""MyDate"" data-valmsg-replace=""true""></ValidationInView></div>
|
||||
|
||||
True
|
||||
<div class=""validation-summary-errors""><ValidationSummaryInPartialView>MySummary</ValidationSummaryInPartialView>
|
||||
|
|
@ -68,7 +68,7 @@ True
|
|||
<ValidationInPartialView class=""field-validation-error"" data-valmsg-for=""Error"" data-valmsg-replace=""true"">An error occurred.</ValidationInPartialView>
|
||||
<input id=""Prefix!Property1"" name=""Prefix.Property1"" type=""text"" value="""" />
|
||||
<div class=""editor-label""><label for=""MyDate"">MyDate</label></div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime"" value=""02/01/2000 03:04:05 +00:00"" /> <ValidationInPartialView class=""field-validation-valid"" data-valmsg-for=""MyDate"" data-valmsg-replace=""true""></ValidationInPartialView></div>
|
||||
<div class=""editor-field""><input class=""text-box single-line"" id=""MyDate"" name=""MyDate"" type=""datetime-local"" value=""02/01/2000 03:04:05 +00:00"" /> <ValidationInPartialView class=""field-validation-valid"" data-valmsg-for=""MyDate"" data-valmsg-replace=""true""></ValidationInPartialView></div>
|
||||
|
||||
True";
|
||||
|
||||
|
|
|
|||
|
|
@ -248,7 +248,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, "datetime")]
|
||||
[InlineData("datetime", "datetime")]
|
||||
[InlineData(null, "datetime-local")]
|
||||
[InlineData("hidden", "hidden")]
|
||||
public void Process_GeneratesFormattedOutput(string specifiedType, string expectedType)
|
||||
{
|
||||
|
|
@ -820,7 +821,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{ "custom-datatype", null, "text" },
|
||||
{ "Custom-Datatype", null, "text" },
|
||||
{ "date", null, "date" }, // No date/time special cases since ModelType is string.
|
||||
{ "datetime", null, "datetime" },
|
||||
{ "datetime", null, "datetime-local" },
|
||||
{ "datetime-local", null, "datetime-local" },
|
||||
{ "DATETIME-local", null, "datetime-local" },
|
||||
{ "Decimal", "{0:0.00}", "text" },
|
||||
|
|
@ -921,20 +922,88 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
Assert.Equal(expectedTagName, output.TagName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_CallsGenerateTextBox_InputTypeDateTime_RendersAsDateTime()
|
||||
{
|
||||
// Arrange
|
||||
var expectedAttributes = new TagHelperAttributeList
|
||||
{
|
||||
{ "type", "datetime" }, // Calculated; not passed to HtmlGenerator.
|
||||
};
|
||||
var expectedTagName = "not-input";
|
||||
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: new TagHelperAttributeList()
|
||||
{
|
||||
{"type", "datetime" }
|
||||
},
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
|
||||
var output = new TagHelperOutput(
|
||||
expectedTagName,
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
||||
new DefaultTagHelperContent()))
|
||||
{
|
||||
TagMode = TagMode.SelfClosing,
|
||||
};
|
||||
|
||||
var htmlAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "type", "datetime" }
|
||||
};
|
||||
|
||||
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
||||
|
||||
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
var tagHelper = GetTagHelper(
|
||||
htmlGenerator.Object,
|
||||
model: null,
|
||||
propertyName: "DateTime",
|
||||
metadataProvider: metadataProvider);
|
||||
tagHelper.ViewContext.Html5DateRenderingMode = Html5DateRenderingMode.Rfc3339;
|
||||
tagHelper.InputTypeName = "datetime";
|
||||
var tagBuilder = new TagBuilder("input");
|
||||
htmlGenerator
|
||||
.Setup(mock => mock.GenerateTextBox(
|
||||
tagHelper.ViewContext,
|
||||
tagHelper.For.ModelExplorer,
|
||||
tagHelper.For.Name,
|
||||
null, // value
|
||||
"{0:yyyy-MM-ddTHH:mm:ss.fffK}",
|
||||
htmlAttributes)) // htmlAttributes
|
||||
.Returns(tagBuilder)
|
||||
.Verifiable();
|
||||
|
||||
// Act
|
||||
await tagHelper.ProcessAsync(context, output);
|
||||
|
||||
// Assert
|
||||
htmlGenerator.Verify();
|
||||
|
||||
Assert.Equal(TagMode.SelfClosing, output.TagMode);
|
||||
Assert.Equal(expectedAttributes, output.Attributes);
|
||||
Assert.Empty(output.PreContent.GetContent());
|
||||
Assert.Equal(string.Empty, output.Content.GetContent());
|
||||
Assert.Empty(output.PostContent.GetContent());
|
||||
Assert.Equal(expectedTagName, output.TagName);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Date", Html5DateRenderingMode.CurrentCulture, "{0:d}", "date")] // Format from [DataType].
|
||||
[InlineData("Date", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")]
|
||||
[InlineData("DateTime", Html5DateRenderingMode.CurrentCulture, null, "datetime")]
|
||||
[InlineData("DateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fffK}", "datetime")]
|
||||
[InlineData("DateTimeOffset", Html5DateRenderingMode.CurrentCulture, null, "datetime")]
|
||||
[InlineData("DateTimeOffset", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fffK}", "datetime")]
|
||||
[InlineData("DateTime", Html5DateRenderingMode.CurrentCulture, null, "datetime-local")]
|
||||
[InlineData("DateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")]
|
||||
[InlineData("DateTimeOffset", Html5DateRenderingMode.CurrentCulture, null, "datetime-local")]
|
||||
[InlineData("DateTimeOffset", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")]
|
||||
[InlineData("DateTimeLocal", Html5DateRenderingMode.CurrentCulture, null, "datetime-local")]
|
||||
[InlineData("DateTimeLocal", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")]
|
||||
[InlineData("Time", Html5DateRenderingMode.CurrentCulture, "{0:t}", "time")] // Format from [DataType].
|
||||
[InlineData("Time", Html5DateRenderingMode.Rfc3339, "{0:HH:mm:ss.fff}", "time")]
|
||||
[InlineData("NullableDate", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")]
|
||||
[InlineData("NullableDateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fffK}", "datetime")]
|
||||
[InlineData("NullableDateTimeOffset", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fffK}", "datetime")]
|
||||
[InlineData("NullableDateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")]
|
||||
[InlineData("NullableDateTimeOffset", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")]
|
||||
public async Task ProcessAsync_CallsGenerateTextBox_AddsExpectedAttributesForRfc3339(
|
||||
string propertyName,
|
||||
Html5DateRenderingMode dateRenderingMode,
|
||||
|
|
@ -967,7 +1036,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
{ "type", expectedType }
|
||||
};
|
||||
|
||||
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
||||
|
||||
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
var tagHelper = GetTagHelper(
|
||||
htmlGenerator.Object,
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
|
|||
{ "url", "__TextBox__ class='text-box single-line' type='url'" },
|
||||
{ "Date", "__TextBox__ class='text-box single-line' type='date'" },
|
||||
{ "DATE", "__TextBox__ class='text-box single-line' type='date'" },
|
||||
{ "DateTime", "__TextBox__ class='text-box single-line' type='datetime'" },
|
||||
{ "datetime", "__TextBox__ class='text-box single-line' type='datetime'" },
|
||||
{ "DateTime", "__TextBox__ class='text-box single-line' type='datetime-local'" },
|
||||
{ "datetime", "__TextBox__ class='text-box single-line' type='datetime-local'" },
|
||||
{ "DateTime-local", "__TextBox__ class='text-box single-line' type='datetime-local'" },
|
||||
{ "DATETIME-LOCAL", "__TextBox__ class='text-box single-line' type='datetime-local'" },
|
||||
{ "Time", "__TextBox__ class='text-box single-line' type='time'" },
|
||||
|
|
@ -766,21 +766,66 @@ Environment.NewLine;
|
|||
HtmlContentUtilities.HtmlContentToString(result));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Editor_InputTypeDateTime_RendersAsDateTime()
|
||||
{
|
||||
// Arrange
|
||||
var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("DateTimeOffset");
|
||||
var expectedInput = "<input class=\"HtmlEncode[[text-box single-line]]\" data-val=\"HtmlEncode[[true]]\" " +
|
||||
$"data-val-required=\"HtmlEncode[[{requiredMessage}]]\" id=\"HtmlEncode[[FieldPrefix]]\" " +
|
||||
"name=\"HtmlEncode[[FieldPrefix]]\" type=\"HtmlEncode[[datetime]]\" value=\"HtmlEncode[[2000-01-02T03:04:05.006]]\" />";
|
||||
|
||||
var offset = TimeSpan.FromHours(0);
|
||||
var model = new DateTimeOffset(
|
||||
year: 2000,
|
||||
month: 1,
|
||||
day: 2,
|
||||
hour: 3,
|
||||
minute: 4,
|
||||
second: 5,
|
||||
millisecond: 6,
|
||||
offset: offset);
|
||||
var viewEngine = new Mock<ICompositeViewEngine>(MockBehavior.Strict);
|
||||
viewEngine
|
||||
.Setup(v => v.GetView(/*executingFilePath*/ null, It.IsAny<string>(), /*isMainPage*/ false))
|
||||
.Returns(ViewEngineResult.NotFound(string.Empty, Enumerable.Empty<string>()));
|
||||
viewEngine
|
||||
.Setup(v => v.FindView(It.IsAny<ActionContext>(), It.IsAny<string>(), /*isMainPage*/ false))
|
||||
.Returns(ViewEngineResult.NotFound(string.Empty, Enumerable.Empty<string>()));
|
||||
|
||||
var provider = new TestModelMetadataProvider();
|
||||
|
||||
var helper = DefaultTemplatesUtilities.GetHtmlHelper(
|
||||
model,
|
||||
Mock.Of<IUrlHelper>(),
|
||||
viewEngine.Object,
|
||||
provider);
|
||||
helper.ViewData.TemplateInfo.HtmlFieldPrefix = "FieldPrefix";
|
||||
|
||||
// Act
|
||||
var result = helper.Editor(
|
||||
string.Empty,
|
||||
new { htmlAttributes = new { type = "datetime" }});
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedInput, HtmlContentUtilities.HtmlContentToString(result));
|
||||
}
|
||||
|
||||
// DateTime-local is not special-cased unless using Html5DateRenderingMode.Rfc3339.
|
||||
[Theory]
|
||||
[InlineData("date", "{0:d}", "2000-01-02")]
|
||||
[InlineData("datetime", null, "2000-01-02T03:04:05.006+00:00")]
|
||||
[InlineData("datetime-local", null, "2000-01-02T03:04:05.006")]
|
||||
[InlineData("time", "{0:t}", "03:04:05.006")]
|
||||
public void Editor_FindsCorrectDateOrTimeTemplate(string dataTypeName, string editFormatString, string expected)
|
||||
[InlineData("date", "{0:d}", "2000-01-02", "date")]
|
||||
[InlineData("datetime", null, "2000-01-02T03:04:05.006", "datetime-local")]
|
||||
[InlineData("datetime-local", null, "2000-01-02T03:04:05.006", "datetime-local")]
|
||||
[InlineData("time", "{0:t}", "03:04:05.006", "time")]
|
||||
public void Editor_FindsCorrectDateOrTimeTemplate(string dataTypeName, string editFormatString, string expectedFormat, string expectedType)
|
||||
{
|
||||
// Arrange
|
||||
var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("DateTimeOffset");
|
||||
var expectedInput = "<input class=\"HtmlEncode[[text-box single-line]]\" data-val=\"HtmlEncode[[true]]\" " +
|
||||
$"data-val-required=\"HtmlEncode[[{requiredMessage}]]\" id=\"HtmlEncode[[FieldPrefix]]\" " +
|
||||
"name=\"HtmlEncode[[FieldPrefix]]\" type=\"HtmlEncode[[" +
|
||||
dataTypeName +
|
||||
"]]\" value=\"HtmlEncode[[" + expected + "]]\" />";
|
||||
expectedType +
|
||||
"]]\" value=\"HtmlEncode[[" + expectedFormat + "]]\" />";
|
||||
|
||||
var offset = TimeSpan.FromHours(0);
|
||||
var model = new DateTimeOffset(
|
||||
|
|
@ -822,11 +867,11 @@ Environment.NewLine;
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("date", "{0:d}", "2000-01-02")]
|
||||
[InlineData("datetime", null, "2000-01-02T03:04:05.060+00:00")]
|
||||
[InlineData("datetime-local", null, "2000-01-02T03:04:05.060")]
|
||||
[InlineData("time", "{0:t}", "03:04:05.060")]
|
||||
public void Editor_AppliesRfc3339(string dataTypeName, string editFormatString, string expected)
|
||||
[InlineData("date", "{0:d}", "2000-01-02", "date")]
|
||||
[InlineData("datetime", null, "2000-01-02T03:04:05.060", "datetime-local")]
|
||||
[InlineData("datetime-local", null, "2000-01-02T03:04:05.060", "datetime-local")]
|
||||
[InlineData("time", "{0:t}", "03:04:05.060", "time")]
|
||||
public void Editor_AppliesRfc3339(string dataTypeName, string editFormatString, string expectedFormat, string expectedType)
|
||||
{
|
||||
// Arrange
|
||||
var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("DateTimeOffset");
|
||||
|
|
@ -834,8 +879,8 @@ Environment.NewLine;
|
|||
"<input class=\"HtmlEncode[[text-box single-line]]\" data-val=\"HtmlEncode[[true]]\" " +
|
||||
$"data-val-required=\"HtmlEncode[[{requiredMessage}]]\" id=\"HtmlEncode[[FieldPrefix]]\" " +
|
||||
"name=\"HtmlEncode[[FieldPrefix]]\" type=\"HtmlEncode[[" +
|
||||
dataTypeName +
|
||||
"]]\" value=\"HtmlEncode[[" + expected + "]]\" />";
|
||||
expectedType +
|
||||
"]]\" value=\"HtmlEncode[[" + expectedFormat + "]]\" />";
|
||||
|
||||
// Place DateTime-local value in current timezone.
|
||||
var offset = string.Equals(string.Empty, dataTypeName) ? DateTimeOffset.Now.Offset : TimeSpan.FromHours(0);
|
||||
|
|
@ -879,22 +924,22 @@ Environment.NewLine;
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("date", Html5DateRenderingMode.CurrentCulture)]
|
||||
[InlineData("date", Html5DateRenderingMode.Rfc3339)]
|
||||
[InlineData("datetime", Html5DateRenderingMode.CurrentCulture)]
|
||||
[InlineData("datetime", Html5DateRenderingMode.Rfc3339)]
|
||||
[InlineData("datetime-local", Html5DateRenderingMode.CurrentCulture)]
|
||||
[InlineData("datetime-local", Html5DateRenderingMode.Rfc3339)]
|
||||
[InlineData("time", Html5DateRenderingMode.CurrentCulture)]
|
||||
[InlineData("time", Html5DateRenderingMode.Rfc3339)]
|
||||
public void Editor_AppliesNonDefaultEditFormat(string dataTypeName, Html5DateRenderingMode renderingMode)
|
||||
[InlineData("date", Html5DateRenderingMode.CurrentCulture, "date")]
|
||||
[InlineData("date", Html5DateRenderingMode.Rfc3339, "date")]
|
||||
[InlineData("datetime", Html5DateRenderingMode.CurrentCulture, "datetime-local")]
|
||||
[InlineData("datetime", Html5DateRenderingMode.Rfc3339, "datetime-local")]
|
||||
[InlineData("datetime-local", Html5DateRenderingMode.CurrentCulture, "datetime-local")]
|
||||
[InlineData("datetime-local", Html5DateRenderingMode.Rfc3339, "datetime-local")]
|
||||
[InlineData("time", Html5DateRenderingMode.CurrentCulture, "time")]
|
||||
[InlineData("time", Html5DateRenderingMode.Rfc3339, "time")]
|
||||
public void Editor_AppliesNonDefaultEditFormat(string dataTypeName, Html5DateRenderingMode renderingMode, string expectedType)
|
||||
{
|
||||
// Arrange
|
||||
var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("DateTimeOffset");
|
||||
var expectedInput = "<input class=\"HtmlEncode[[text-box single-line]]\" data-val=\"HtmlEncode[[true]]\" " +
|
||||
$"data-val-required=\"HtmlEncode[[{requiredMessage}]]\" id=\"HtmlEncode[[FieldPrefix]]\" " +
|
||||
"name=\"HtmlEncode[[FieldPrefix]]\" type=\"HtmlEncode[[" +
|
||||
dataTypeName +
|
||||
expectedType +
|
||||
"]]\" value=\"HtmlEncode[[Formatted as 2000-01-02T03:04:05.0600000+00:00]]\" />";
|
||||
|
||||
var offset = TimeSpan.FromHours(0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue