2010-01-25 24 views
8

Trong trang web tôi đang xây dựng, tôi cần có các thuộc tính datetime được chia thành các kết hợp khác nhau tùy thuộc vào thuộc tính. Ví dụ:ASP.NET MVC 2 Các mẫu biên tập tùy chỉnh để chia các trường datetime

Chế độ xem thành viên có ngày sinh sản cần được hiển thị trên chế độ xem dưới dạng danh sách thả xuống ngày/tháng/năm riêng biệt.

Chế độ xem thẻ tín dụng có thuộc tính ngày hết hạn cần được hiển thị dưới dạng danh sách thả xuống tháng/năm riêng biệt.

Chế độ xem tham quan chỉ có thuộc tính thời gian trong đó cần có giờ và phút riêng biệt làm hộp văn bản.

Mỗi trường hợp này đều yêu cầu xác thực hợp lệ và xác thực phía khách hàng lý tưởng.

Tôi đã xem xét các tùy chọn khác nhau như ràng buộc tùy chỉnh, thuộc tính tùy chỉnh và bây giờ tôi đang tìm kiếm các mẫu trình chỉnh sửa tùy chỉnh nhưng cho đến nay tôi đã có rất ít may mắn trong việc tìm kiếm các giải pháp phù hợp.

Nó có vẻ giống như một nhiệm vụ phổ biến nhưng tìm kiếm trên mạng đã cho thấy ít bao gồm tất cả mọi thứ (đặc biệt là với các yếu tố xác nhận).

Vì vậy, câu hỏi của tôi là có ai khác đã quản lý để thực hiện điều này không?

(ngón tay được chuyển!)

+0

"nhưng cho đến nay tôi đã có rất ít may mắn trong việc tìm kiếm các giải pháp phù hợp". Điều đó có nghĩa là gì? – jfar

+0

Hi jfar, tôi khá mới với C# và mvc và do đó đã được dựa vào tìm kiếm google để tìm một điểm khởi đầu tốt đẹp của một giải pháp. Một trong những chính đã được http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx nhưng tôi không thể tìm ra cách để thêm xác nhận (phía máy chủ hoặc phía khách hàng). –

+0

Ồ, tôi nghĩ đó là thứ khác. Trừ khi ai đó khác trả lời tôi sẽ đăng câu trả lời tối nay. Tôi làm điều này mọi lúc. – jfar

Trả lời

13

Ok, tôi sẽ cố gắng và giúp bạn có được 90% con đường ở đó. Đây thực sự là một phần rất lớn và phức tạp của MVC 2 và hầu như không thể trả lời chỉ trong hộp câu trả lời này.

Bây giờ đầu tiên bạn nên vào blog của Brad Wilsons và đọc sâu về cách tùy chỉnh các mẫu MVC 2 mặc định. Điều đó sẽ cung cấp cho bạn một sự hiểu biết rõ ràng hơn tất cả các bộ phận chuyển động.

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

Bây giờ tôi sẽ bắt đầu một ví dụ đơn giản về cách để tạo ra một mô hình điểm hẹn giả tạo mà chúng tôi muốn chắc chắn các giá trị cung cấp không đi ngược thời gian. Đừng chú ý đến các thuộc tính ngay bây giờ, chúng ta sẽ đến đó.

Đây là ViewModel Tôi đang sử dụng:

public class AppointmentViewModel 
{ 
    [Required] 
    public string Name { get; set; } 

    [CantGoBackwardsInTime] 
    public DateRange DateRange { get; set; } 
} 

public class DateRange 
{ 
    public DateTime Start { get; set; } 
    public DateTime End { get; set; } 

    [Required] 
    public int Price { get; set; } 
} 

Và tôi đã thêm này đến HomeController mặc định (không có gì lạ mắt):

public ActionResult Appointment() 
    { 
     return View(new AppointmentViewModel()); 
    } 

    [HttpPost] 
    public ActionResult Appointment(AppointmentViewModel appointment) 
    { 
     return View(appointment); 
    } 

Và đây là quan điểm của tôi:

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
Appointment 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
    <h2>Add Appointment</h2> 
    <%= Html.ValidationSummary() %> 
    <% using(Html.BeginForm()) { %> 
    <%= Html.EditorForModel() %> 
    <input type="submit" value="Save Changes" /> 
    <%} %> 
</asp:Content> 

Bước 1: Đặt giai đoạn

Điều đầu tiên bạn muốn làm là lấy "mẫu mặc định" từ mục nhập blog. Một trong những quan trọng trong trường hợp này là một trong đó sẽ ngồi trong /Views/Shared/EditorTemplates/Object.asxc Object.ascx là keystone cho toàn bộ hoạt động. Tất cả các phương thức Html.Editor ***** sẽ gọi điều này cuối cùng.

Bây giờ phần đầu tiên của chức năng mặc định chúng ta phải thay đổi là dòng này bên trong Object.ascx

<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %> 
    <%= ViewData.ModelMetadata.SimpleDisplayText%> 
<% } 

gì thats nói là "không hiển thị bất kỳ loại phức tạp lồng nhau" và chúng tôi không muốn cái đó. Thay đổi điều đó> 1 thành a> 2. Bây giờ, xem các mô hình trong biểu đồ đối tượng của bạn sẽ có các mẫu được tạo cho chúng thay vì chỉ tạo văn bản trình giữ chỗ.

Chỉ cần giữ mọi thứ khác mặc định ngay bây giờ.

* Bước 2: Overriding Templates **

Nếu bạn đọc những entry hy vọng bạn sẽ hiểu bây giờ như thế nào Editor *** và phương pháp hiển thị sẽ tự động gọi các mẫu trong Xem/Shared/EditorTemplates và DisplayTemplates . Hãy suy nghĩ của họ như gọi Html.RenderPartial ("TYPENAME", MyType) họ không phải là nhưng đủ gần của nó trong khái niệm.

Vì vậy, nếu bạn chạy giải pháp này đến nay và đi đến đúng url bạn sẽ nhận thấy rằng MVC 2 sẽ gọi Object.ascx hai lần, một lần cho AppointmentViewModel của bạn và một lần nữa cho DateRange thuộc tính. Hết hộp chỉ hiển thị cùng một bộ sưu tập các trường biểu mẫu.

Cho phép nói rằng chúng tôi muốn tạo mẫu của chúng tôi bao quanh trình chỉnh sửa DateRange với hộp có viền màu đỏ. Những gì chúng tôi muốn làm là ngắn mạch MVC 2 để gọi một mẫu DateTime.ascx tùy chỉnh thay vì Object.ascx và đó là dễ dàng như thêm mẫu riêng của chúng tôi trong View/Shared/EditorTemplates/DateRange.ascx. Trong trường hợp này, tôi đã mang theo những gì được tạo ra bởi Object.ascx làm việc với mô hình datarange của chúng tôi và chỉ cần dán mã vào một DateRange.ascx mới:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 
<div style="border: 1px solid #900"> 
    <div class="editor-label"><label for="DateRange">DateRange</label></div>    
     <div class="editor-field">    
      <div class="editor-label"><label for="DateRange_Start">Start</label> 
     </div> 


     <div class="editor-field"> 
      <input class="text-box single-line" id="DateRange_Start" name="DateRange.Start" type="text" value="" />    
     </div> 

     <div class="editor-label"><label for="DateRange_End">End</label></div> 

     <div class="editor-field"> 
      <input class="text-box single-line" id="DateRange_End" name="DateRange.End" type="text" value="" />    
     </div> 

     <div class="editor-label"><label for="DateRange_Price">Price</label></div> 

     <div class="editor-field"> 
      <input class="text-box single-line" id="DateRange_Price" name="DateRange.Price" type="text" value="" /> 

     </div>  
    </div> 
</div> 

Wala!

Bây giờ khi bạn chạy giải pháp, bạn sẽ thấy một hộp màu đỏ xung quanh DateRange của chúng tôi. Phần còn lại của các tùy chỉnh tùy thuộc vào bạn! Bạn có thể thêm các hộp datepicker jQuery. Trong trường hợp của bạn, bạn có thể đặt cả hai trường trong một div duy nhất để chúng xếp hàng theo chiều ngang. Bầu trời là giới hạn vào thời điểm này.

Bước 3: Xác nhận:

Validation hoạt động khá nhiều chỉ là cách mà bạn mong đợi. Thuộc tính [Bắt buộc] bên trong loại 01RDateRange của bạn hoạt động giống như bất kỳ thuộc tính xác thực nào khác.

Bây giờ bạn thấy tôi đã thực hiện không thể chuyển ngược thuộc tính thời gian mà tôi đã đặt vào thuộc tính DateRange của AppointmentViewModel. Tất cả bạn phải làm gì để tạo ra những loại xác nhận cụ thể các thuộc tính được kế thừa và thực hiện các ValidationAttribute cơ sở:

public class CantGoBackwardsInTime : ValidationAttribute 
{ 
    public override string FormatErrorMessage(string name) 
    { 
     return "Your date range can't go backwards in time"; 
     //return base.FormatErrorMessage(name); 
    } 

    public override bool IsValid(object value) 
    { 
     if (!(value is DateRange)) 
      throw new InvalidOperationException("This attributes can only be used on DateRange types!"); 

     var dateRange = value as DateRange; 

     return dateRange.End > dateRange.Start; 
    } 
} 

Bây giờ nếu bạn thêm này và trang trí tài sản của bạn, bạn sẽ thấy thông báo lỗi được cung cấp trong các thuộc tính xác nhận tùy chỉnh CantGoBackwardsInTime.

Tôi sẽ cập nhật và làm rõ thêm về điều này nếu bạn có bất kỳ vấn đề nào nhưng điều này sẽ giúp bạn bắt đầu và trên con đường của bạn. Chỉ cần một cảnh báo: Editor mới cho các phần của MVC 2 là điều tuyệt vời nhất trên thế giới và có tiềm năng rất lớn để cung cấp cho MVC 2 siêu RAD khả năng; nhưng có rất ít thông tin bên cạnh blog của Brad Wilsons. Chỉ cần giữ nó và đừng ngại nhìn vào mã nguồn MVC 2 nếu bạn cần.

+0

Cảm ơn jfar này, nó chắc chắn cho tôi một cái gì đó để làm việc với tuy nhiên tôi đang hướng tới chia tách các đối tượng datetime thực tế trong thành phần đầu vào của nó (một đầu vào riêng biệt cho năm, tháng và ngày ví dụ) thay vì nhiều datetime đầy đủ trường hợp. Bạn có nghĩ đây vẫn là con đường đúng đắn không? Làm thế nào bạn có thể thêm xác nhận hợp lệ phía khách hàng như là một phần của giải pháp này? –

+0

Đúng vậy. Bạn sẽ chỉ cần tạo mẫu DateTime của riêng bạn để chia nhỏ giao diện người dùng. Theo như xác nhận phía khách hàng chỉ đơn giản là bao gồm javascript trong mẫu DateTime.ascx tùy chỉnh của bạn. – jfar

+0

Ok, tôi có nó làm việc với một trong những kết hợp tôi đã sau (tháng và năm chỉ trong hai đầu vào riêng biệt) vì vậy một cảm ơn bạn đã giúp đỡ của bạn và tôi sẽ gắn cờ này như đã trả lời. Một điều tôi tự hỏi bây giờ là tôi có nó để một xác nhận hợp lệ tùy chỉnh có một đối tượng CardDate (int tháng và năm int) và cố gắng để tạo thành một ngày hợp lệ. nếu nó thất bại nó trả về false nói rằng thẻ nhớ không hợp lệ. Một điều, là nó có thể từ bên trong thuộc tính để làm cho cả hai trường trong đối tượng cardtype không hợp lệ để chúng hiển thị ở trạng thái không hợp lệ trên khung nhìn? Hy vọng rằng có ý nghĩa! –

0

Bạn đang cố gắng thực hiện việc này trên một trang? Hoặc một phương pháp? Tôi không thực sự chắc chắn làm thế nào bạn muốn làm điều này vì vậy đây là bắn của tôi nếu tôi hiểu bạn phải.

Vì vậy, ví dụ: bạn có thể làm điều gì đó tương tự như vậy cho ngày sinh.

Theo quan điểm của bạn

<%= Html.DropDownList("Birthday")%> 
<%= Html.DropDownList("BirthMonth")%> 
<%= Html.DropDownList("BirthYear")%> 

Trong điều khiển của bạn ở đâu đó có một cái gì đó như thế này. Có lẽ bạn có thể kết hợp tất cả thành một vòng lặp hoặc một cái gì đó như thế.

List<int> month = new List<int>() 
for(int i = 0; i < 12, i++) 
{ 
    month.add(i + 1); 
} 

ViewData["BirthMonth"] = new SelectList(month); 


int days = DateTime.DaysInMonth(Year, Month); 

    // do a another for loop add it to viewsData = ViewData["Birthday"] . 
    // do a another for loop for years and add it do another viewdata = ViewData["BirthYear"]. 

Vì vậy, những gì tôi nhận được là bạn có thể thực hiện một số nội dung trên máy chủ để lấy ngày bạn muốn và thêm nó vào ViewData vào danh sách thả xuống.

+0

Hi chobo2, cảm ơn cho đầu vào nhưng điều này không thực sự đi đúng hướng. Tôi đang tìm một cách để liên kết với một tài sản datetime trên một mô hình và vẫn còn xác nhận, vv Liên kết trong bình luận ở trên nên cung cấp cho một ý tưởng tốt hơn về những gì tôi đang cố gắng để thực hiện. –

Các vấn đề liên quan