通过数据验证将小时数输入时间表

时间:2013-08-14 05:20:21

标签: c# asp.net-mvc

我需要用户能够在表格中输入小时数,可能包含小数,如下所示:

Timetable

我已声明以下类来保存模型数据:

public class WeeklyTimes
{
    public decimal Week1 { get; set; }
    public decimal Week2 { get; set; }
    public decimal Week3 { get; set; }
    public decimal Week4 { get; set; }
    public decimal Week5 { get; set; }
}

public class MonthlyReport
{
    public WeeklyTimes TimeSpentTutoring { get; set; }
    public WeeklyTimes TimeSpentOnPreparation { get; set; }
    public WeeklyTimes TimeSpentOnHomework { get; set; }
}

并绑定到以下视图:

<table class="timesheet">
<tr class="timesheet-row">
    <th class="center-align" />
    <th class="center-align">Week 1</th>
    <th class="center-align">Week 2</th>
    <th class="center-align">Week 3</th>
    <th class="center-align">Week 4</th>
    <th class="center-align">Week 5</th>
</tr>
<tr class="timesheet-row">
    <th class="left-align">Tutoring Time</th>
    <td>@Html.TextBoxFor(x => x.TimeSpentTutoring.Week1, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentTutoring.Week2, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentTutoring.Week3, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentTutoring.Week4, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentTutoring.Week5, new { @class = "input-time" })</td>
</tr>
<tr class="timesheet-row">
    <th class="left-align">Learner Homework</th>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnHomework.Week1, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnHomework.Week2, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnHomework.Week3, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnHomework.Week4, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnHomework.Week5, new { @class = "input-time" })</td>
</tr>
<tr class="timesheet-row">
    <th class="left-align">Tutor Prep & Commute</th>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnPreparation.Week1, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnPreparation.Week2, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnPreparation.Week3, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnPreparation.Week4, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.TimeSpentOnPreparation.Week5, new { @class = "input-time" })</td>
</tr>
</table>

这个问题的两个部分:

  1. 我是MVC的新手,并且不确定HTML中的重复数量。有没有更好的方法来构建这个HTML?
  2. 确保适当验证的最佳方法是什么?理想情况下,用户只能输入数字,格式如下:“#。#”。但是,使用十进制数据类型,我似乎无法实现这一点。我也考虑使用字符串数据类型和正则表达式验证,但这对我来说似乎很奇怪。

3 个答案:

答案 0 :(得分:2)

首先:您可以为WeeklyTimes

创建模板

放在EditorTemplates / WeeklyTimes.cshtml

您可能希望将标签添加到WeeklyTimes类

public class WeeklyTimes
{
    public string Name { get; set; }
    public decimal Week1 { get; set; }
    public decimal Week2 { get; set; }
    public decimal Week3 { get; set; }
    public decimal Week4 { get; set; }
    public decimal Week5 { get; set; }
}

WeeklyTimes.cshtml:

@model WeeklyTimes
<tr class="timesheet-row">
    <th class="left-align">@Model.Name</th>
    <td>@Html.TextBoxFor(x => x.Week1, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.Week2, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.Week3, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.Week4, new { @class = "input-time" })</td>
    <td>@Html.TextBoxFor(x => x.Week5, new { @class = "input-time" })</td>
</tr>

您可能需要另一个月度报告,或者只是在视图中按照您的意愿

MonthlyReport:

@model MonthlyReport
<table class="timesheet">
    <tr class="timesheet-row">
        <th class="center-align" />
        <th class="center-align">Week 1</th>
        <th class="center-align">Week 2</th>
        <th class="center-align">Week 3</th>
        <th class="center-align">Week 4</th>
        <th class="center-align">Week 5</th>
    </tr>
    @EditorFor(m=> m.TimeSpentTutoring)
    @EditorFor(m=> m.TimeSpentOnPreparation)
    @EditorFor(m=> m.TimeSpentOnHomework)
</table>

第二:你可以像这样装饰你的小数以进行适当的验证

[DisplayFormat(DataFormatString = "{0:#.#}", ApplyFormatInEditMode = true)]

您可以执行客户端验证:

$('input').on('change', function() {
    // this will add invalid class to the invalid inputs and you can make your css mark them with a red border or something. If you use 'input change' it will validate on every keystroke
    $('#myForm').validate();
});

您可以使用占位符来提高可用性:

@Html.TextBoxFor(x => x.Week1, new { @class = "input-time", placeholder="0.2" });

如果你想为支持html5输入类型的浏览器寻求更好的客户端方法,你可以做到

@Html.TextBoxFor(x => x.Week1, new { @class = "input-time", placeholder="0.2", type="number" });

如果这不能解决您的所有请求,则必须实现自定义验证程序。 查看此博客文章,了解有关如何完成此操作的完整详细信息。 http://www.codeproject.com/Articles/275056/Custom-Client-Side-Validation-in-ASP-NET-MVC3

答案 1 :(得分:1)

@Bart并解决您的第一个问题。

你的第二个问题试试这个

<Script>
    function Numberonly() {
                            alert('hi');
                        var reg = /^((\d{0,9})*(\.\d{0,2})|(\d{0,9})*)$/;

                        if (!reg.test(($("#txtWeek1").val()))) {
                            $("#txtWeek1").val('');
                            return false;
                        }
                    }
</Script>

查看

@Html.TextBoxFor(x => x.Week1, new { @class = "input-time" ,@id="txtWeek1", @onkeyup = "Numberonly()" })

只允许两位数后的十进制数Ex:123.12点。

答案 2 :(得分:-1)

1)你确实可以限制这个Html。你有两个选择。第一种是使用@Html.EditorForModel()为整个模型调用Html帮助器。这可能不是您想要的,因为您在整个模型中有三个子实体。我会建议更多循环遍历每个实体的所有属性。

例如:

@foreach (var property in Model.TimeSpentTutoring.GetType().GetProperties()) {
    ...
}

然后你只需要在每个传递上创建一个文本框。以下a link处理类似情况。


2)DisplayFormat数据属性可用于格式化数字。

前(#。##):

[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
public decimal Week1 { get; set; }
...