ASP.NET MVC 3 Razor - การเพิ่มคลาสเข้ากับ EditorFor


189

ฉันกำลังพยายามเพิ่มคลาสให้กับอินพุต

สิ่งนี้ไม่ทำงาน:

@Html.EditorFor(x => x.Created, new { @class = "date" })

1
เฮ้คุณก็มีชื่อเหมือนกันด้วย! - (สำหรับรหัสของฉัน)
หยิก

1
หมายเหตุ: สำหรับคำตอบบางข้อแม้ว่าจะถูกต้องผู้ใช้อาจต้องล้างแคชของเบราว์เซอร์เพื่อให้เป็นจริง นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งถ้าการแก้ปัญหาเป็นไปตาม CSS หรือเกี่ยวข้องกับคลาส CSS! เพิ่งใช้เวลาสักครู่เพื่อให้ทราบว่ามีปัญหาที่แตกต่างออกไปเล็กน้อย ....
JosephDoggie

คำตอบ:


183

การเพิ่มคลาสให้Html.EditorForไม่สมเหตุสมผลเหมือนในเทมเพลตคุณสามารถมีแท็กที่แตกต่างกันมากมาย ดังนั้นคุณต้องกำหนดชั้นเรียนภายในเทมเพลตแก้ไข:

@Html.EditorFor(x => x.Created)

และในเทมเพลตที่กำหนดเอง:

<div>
    @Html.TextBoxForModel(x => x.Created, new { @class = "date" })
</div>

5
มันใช้งานได้ดีขอบคุณ มีปัญหาในการจัดรูปแบบค่าของฟิลด์ต่อหมายเหตุประกอบ DisplayFormat ในโมเดลของฉัน จัดรูปแบบเป็นคำอธิบายประกอบด้วย EditorFor และ DisplayFor แต่ไม่ใช่ TextBoxFor :( ดูเหมือนว่าฉันจะต้องใช้เทมเพลตที่กำหนดเองเว้นแต่ว่าใครบางคนสามารถชี้ให้ฉันเห็นสิ่งที่ฉันขาดหายไปได้?
Sean

มีปัญหาเดียวกันกับที่ TextBoxFor ไม่ให้เกียรติชุด DisplayFormat
jocull

14
นี่คือ GroundController ถึง ModelTom ฉันกำลังส่งมุมมองและฉันกำลังลอยอยู่ในแบบ MVC ที่สุด
เทรนต์สจ๊วต

3
ฉันมีปัญหาเดียวกัน แต่ฉันไม่สามารถใช้ TextBoxFor ได้เพราะฉันต้องการ DisplayFormat ซึ่งทำงานร่วมกับ Editor หรือ Display แต่ในเวลาเดียวกันฉันก็ต้องการคลาสด้วยเช่นกันดังนั้นฉันจึงสามารถแสดงข้อความในรูปแบบอ่านอย่างเดียว
AT

153

ตั้งแต่ ASP.NET MVC 5.1 การเพิ่มคลาสให้EditorForเป็นไปได้ (คำถามเดิมที่ระบุ ASP.NET MVC 3 และคำตอบที่ยอมรับยังดีที่สุดเมื่อพิจารณาแล้ว)

@Html.EditorFor(x=> x.MyProperty,
    new { htmlAttributes = new { @class = "MyCssClass" } })

ดู: มีอะไรใหม่ใน ASP.NET MVC 5.1 สนับสนุน Bootstrap สำหรับเทมเพลตการแก้ไข


ที่น่ากลัว. ขอบคุณ!
Neill

1
ฉันเกือบพลาดเพราะนี่เป็นอันดับที่ 3 ในรายการ มันอาจจะเป็นประโยชน์ในการทำให้มันเป็นคำถามของตัวเองแล้วตอบด้วยตัวคุณเอง
Robb Sadler

ในช่วง MVC 2,3,4 ฉันไม่เข้าท่า ... แต่เนื่องจากมีผู้คนจำนวนมากเริ่มใช้และบ่นเกี่ยวกับการขาดมัน - ในทันใดนั้นใน MVC 5: D +1
Piotr Kula

ตอนนี้ควรเป็นคำตอบที่ยอมรับในความคิดของฉัน
Manfred

101

คุณไม่สามารถกำหนดคลาสสำหรับ EditorFor ทั่วไป หากคุณรู้จักเครื่องมือแก้ไขที่คุณต้องการคุณสามารถใช้งานได้ทันทีคุณสามารถกำหนดคลาสได้ คุณไม่จำเป็นต้องสร้างเทมเพลตที่กำหนดเอง

@Html.TextBoxFor(x => x.Created, new { @class = "date" }) 

5
ข้อเสนอที่ดีมันดีมากที่ไม่จำเป็นต้องสร้างเทมเพลตที่กำหนดเอง
Steve Duitsman

คุณประหยัดเวลาได้มากสำหรับฉัน jo!
Prashanth Benny

40

คุณสามารถใช้ได้:

@Html.EditorFor(x => x.Created, new { htmlAttributes = new { @class = "date" } })

(อย่างน้อยกับ ASP.NET MVC 5 แต่ฉันไม่รู้ว่ามันเป็นอย่างไรกับ ASP.NET MVC 3)


โปรดอ่านชื่อคำถามนี่เป็นปัญหาสำหรับ MVC3 คุณให้บริการโซลูชั่น MVC5 ซึ่งทำให้เข้าใจผิดอย่างสมบูรณ์
Vincent

11
และคุณโปรดอ่านโพสต์ทั้งหมดของฉันที่ฉันเขียนไว้สำหรับ MVC5 นี่เป็นผลลัพธ์แรกจาก Google ดังนั้นหลังจากที่ฉันพบโซลูชันที่ฉันต้องการแชร์ที่นี่บางทีมันอาจช่วยคนบางคนได้
przno

อันนี้ช่วยฉันได้! ขอบคุณ @przno
Joakim M

29

ฉันมีปัญหาที่น่าผิดหวังเหมือนกันและฉันไม่ต้องการสร้าง EditorTemplate ที่ใช้กับค่า DateTime ทั้งหมด (มีหลายครั้งใน UI ของฉันที่ฉันต้องการแสดงเวลาไม่ใช่ปฏิทินดรอปดาวน์jQuery UI ) ในการวิจัยของฉันปัญหารากที่ฉันเจอคือ:

  • ผู้ช่วยTextBoxForมาตรฐานอนุญาตให้ฉันใช้คลาสที่กำหนดเองของ "ตัวเลือกวันที่" เพื่อแสดงปฏิทิน jQuery UI ที่ไม่สร้างความรำคาญ แต่ TextBoxFor จะไม่จัดรูปแบบ DateTime โดยไม่ใช้เวลาจึงทำให้การแสดงปฏิทินล้มเหลว
  • EditorForมาตรฐานจะแสดง DateTime เป็นสตริงที่จัดรูปแบบ (เมื่อตกแต่งด้วยแอตทริบิวต์ที่เหมาะสมเช่น[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]แต่จะไม่อนุญาตให้ฉันใช้คลาส "ตัวเลือกเลือกวันที่" ที่กำหนดเอง

ดังนั้นฉันสร้างคลาส HtmlHelper ที่กำหนดเองที่มีประโยชน์ดังต่อไปนี้:

  • วิธีการแปลง DateTime โดยอัตโนมัติเป็น ShortDateString ที่จำเป็นโดยปฏิทิน jQuery (jQuery จะล้มเหลวหากมีเวลา)
  • ตามค่าเริ่มต้นตัวช่วยจะใช้ htmlAttributes ที่ต้องการเพื่อแสดงปฏิทิน jQuery แต่สามารถแทนที่ได้หากจำเป็น
  • หากวันที่เป็นโมฆะ ASP.NET MVC จะกำหนดวันที่ 1/1/0001 เป็นค่า

เมธอดนี้แทนที่ด้วยสตริงว่าง

public static MvcHtmlString CalenderTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
    var mvcHtmlString = System.Web.Mvc.Html.InputExtensions.TextBoxFor(htmlHelper, expression, htmlAttributes ?? new { @class = "text-box single-line date-picker" });
    var xDoc = XDocument.Parse(mvcHtmlString.ToHtmlString());
    var xElement = xDoc.Element("input");
    if (xElement != null)
    {
        var valueAttribute = xElement.Attribute("value");
        if (valueAttribute != null)
        {
            valueAttribute.Value = DateTime.Parse(valueAttribute.Value).ToShortDateString();
            if (valueAttribute.Value == "1/1/0001")
                valueAttribute.Value = string.Empty;
        }
    }
    return new MvcHtmlString(xDoc.ToString());
}

และสำหรับผู้ที่ต้องการทราบว่าไวยากรณ์ JQuery ที่มองหาวัตถุที่มีการdate-pickerตกแต่งชั้นเรียนแล้วทำให้ปฏิทินที่นี่มันเป็น:

$(document).ready(function () {
    $('.date-picker').datepicker({ inline: true, maxDate: 0, changeMonth: true, changeYear: true });
    $('.date-picker').datepicker('option', 'showAnim', 'slideDown');
});

ที่ช่วยให้ฉันตอนนี้ปัญหาเล็ก ๆ น้อย ๆ กับมัน - คุณต้องตรวจสอบเพื่อให้แน่ใจว่า valueAttribute.Value ไม่ว่างเปล่าหรือช่องว่างก่อนที่จะผ่านมันไปยังวิธีการ DateTime.Parse มิฉะนั้นคุณมีความเสี่ยง FormatException ถูกโยนลงในช่องว่าง
หมู่

ขอบคุณ คุณช่วยฉันมาก
Bronzato

สิ่งนี้ช่วยฉันได้อย่างไรหากคุณกำลังใช้สิ่งนี้และคุณคาดหวังว่าฟิลด์จะทำการตรวจสอบคุณจะต้องใช้ตรรกะนี้: stackoverflow.com/questions/12023970/…
Aaron Newton

งานที่ดี แต่คุณรู้หรือไม่ว่าคุณสามารถควบคุมถ้า DateTime หรือเพียงแค่การควบคุมวันที่ปรากฏเพียงโดยใช้DateTimePickerForและปรับปรุงฟิลด์วันแบบของคุณเป็นตัวแทนด้วย[DataType(DataType.Date)]หรือ[DataType(DataType.DateTime)]? นอกจากนี้คุณยังสามารถใส่ลงไปในรูปแบบพูด mm / dd / yyyy ด้วย.ParseFormats(new string[] { "MM/dd/yyyy" })(หรือปรับเปลี่ยนเป็นสิ่งที่คุณต้องการได้อย่างง่ายดาย) หากเป็นค่าว่างฟิลด์จะแสดงผลว่างเปล่าโดยไม่ต้องใช้รหัสใน
vapcguy

@MyHtmlHelpers.CalenderTextBoxFor(model => model.ExpirationDate)มีดโกนจะไม่รู้จัก มีความคิดเห็นเกี่ยวกับวิธีการนำไปใช้อย่างไร
Mehdiway

15

เป็นไปได้ที่จะจัดเตรียมคลาสหรือข้อมูลอื่น ๆ ผ่านทาง EnhancedViewData - ฉันใช้สิ่งนี้ซึ่งฉันอนุญาตให้ผู้ใช้สร้างฟอร์มตามฟิลด์ฐานข้อมูล (propertyName, editorType และ editorClass)

ตามตัวอย่างเริ่มต้นของคุณ:

@Html.EditorFor(x => x.Created, new { cssClass = "date" })

และในเทมเพลตที่กำหนดเอง:

<div>
    @Html.TextBoxFor(x => x.Created, new { @class = ViewData["cssClass"] })
</div>

8
@ Html.EditorFor (x => x.Created ใหม่ {cssClass = "date"}) ไม่ได้ผลสำหรับฉัน
Alan Macdonald

1
สิ่งนี้ใช้ได้กับฉัน & เป็นคำตอบที่ดีกว่าคำตอบที่ทำเครื่องหมายไว้ มันให้ประโยชน์ของการใช้แม่แบบ แต่ยังอนุญาตให้มีการปรับแต่งบางอย่างโดยไม่ต้องแฮ็ค jQuery
ชาด Hedgcock

TextBoxFor ละเว้นคุณลักษณะอื่นที่อาจมีการตั้งค่าในรูปแบบเช่น 'DataType's เป็นต้น
Markus

8

ไม่มีการEditorForแทนที่ใด ๆที่ช่วยให้คุณส่งผ่านวัตถุที่ไม่ระบุชื่อซึ่งคุณสมบัติจะได้รับการเพิ่มเป็นแอตทริบิวต์ในแท็กบางอย่างโดยเฉพาะอย่างยิ่งสำหรับเทมเพลตในตัวแก้ไข คุณจะต้องเขียนเทมเพลตแก้ไขที่กำหนดเองของคุณเองและส่งผ่านค่าที่คุณต้องการเป็นข้อมูลเพิ่มเติม


2
@Html.EditorFor(m=>m.Created ...) 

ไม่อนุญาตให้มีการส่งผ่านอาร์กิวเมนต์ใด ๆ สำหรับกล่องข้อความ

นี่คือวิธีที่คุณสามารถใช้คุณลักษณะ

@Html.TextBoxFor(m=>m.Created, new { @class= "date", Name ="myName", id="myId" })

2

การใช้ jQuery คุณสามารถทำได้อย่างง่ายดาย:

$("input").addClass("class-name")

นี่คือแท็กอินพุตของคุณ

@Html.EditorFor(model => model.Name)

สำหรับ DropDownlist คุณสามารถใช้สิ่งนี้:

$("select").addClass("class-name")

สำหรับรายการแบบเลื่อนลง:

@Html.DropDownlistFor(model=>model.Name)

2

ในขณะที่คำถามถูกกำหนดเป้าหมายไว้ที่ MVC 3.0 เราพบว่าปัญหายังคงมีอยู่ใน MVC 4.0 เช่นกัน MVC 5.0 ในตอนนี้มีโอเวอร์โหลดสำหรับ htmlAttributes

ฉันถูกบังคับให้ใช้ MVC 4.0 ที่ตำแหน่งงานปัจจุบันของฉันและจำเป็นต้องเพิ่มคลาส css สำหรับการรวม JQuery ฉันแก้ไขปัญหานี้โดยใช้วิธีการขยายเดียว ...

วิธีการขยาย:

using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using System.Xml.Linq;

namespace MyTest.Utilities
{
    public static class MVCHelperExtensionMethods
    {
        public static MvcHtmlString AddHtmlAttributes(this MvcHtmlString input, object htmlAttributes)
        {
            // WE WANT TO INJECT INTO AN EXISTING ELEMENT.  IF THE ATTRIBUTE ALREADY EXISTS, ADD TO IT, OTHERWISE
            // CREATE THE ATTRIBUTE WITH DATA VALUES.

            // USE XML PARSER TO PARSE HTML ELEMENT
            var xdoc = XDocument.Parse(input.ToHtmlString());
            var rootElement = (from e in xdoc.Elements() select e).FirstOrDefault();

            // IF WE CANNOT PARSE THE INPUT USING XDocument THEN RETURN THE ORIGINAL UNMODIFIED.
            if (rootElement == null)
            {
                return input;
            }

            // USE RouteValueDictionary TO PARSE THE NEW HTML ATTRIBUTES
            var routeValueDictionary = new RouteValueDictionary(htmlAttributes);

            foreach (var routeValue in routeValueDictionary)
            {
                var attribute = rootElement.Attribute(routeValue.Key);

                if (attribute == null)
                {
                    attribute = new XAttribute(name: routeValue.Key, value: routeValue.Value);
                    rootElement.Add(attribute);
                }
                else
                {
                    attribute.Value = string.Format("{0} {1}", attribute.Value, routeValue.Value).Trim();
                }
            }

            var elementString = rootElement.ToString();
            var response = new MvcHtmlString(elementString);
            return response;
        }
    }
}

การใช้มาร์กอัป HTML:

@Html.EditorFor(expression: x => x.MyTestProperty).AddHtmlAttributes(new { @class = "form-control" })

(ตรวจสอบให้แน่ใจว่าได้รวมเนมสเปซของเมธอดส่วนขยายในมุมมองมีดโกน)

คำอธิบาย: แนวคิดคือการแทรกลงใน HTML ที่มีอยู่ ฉันเลือกที่จะแยกองค์ประกอบปัจจุบันใช้ LINQ เพื่อ XML XDocument.Parse()ใช้ ฉันผ่าน htmlAttributes objectเป็นประเภท ฉันใช้ MVC RouteValueDictionaryเพื่อแยกวิเคราะห์ htmlAttributes ที่ส่งมาฉันผสานคุณสมบัติที่มีอยู่แล้วหรือเพิ่มแอตทริบิวต์ใหม่หากยังไม่มีอยู่

ในกรณีที่อินพุตไม่สามารถแยกวิเคราะห์ได้โดยXDocument.Parse()ฉันละทิ้งความหวังทั้งหมดและส่งคืนสตริงอินพุตดั้งเดิม

ตอนนี้ฉันสามารถใช้ประโยชน์ของ DisplayFor (การแสดงผลข้อมูลเช่นสกุลเงินที่เหมาะสม) แต่ยังมีความสามารถในการระบุคลาส CSS (และคุณลักษณะอื่น ๆ สำหรับเรื่องนั้น) อาจมีประโยชน์สำหรับการเพิ่มคุณสมบัติเช่นdata-*หรือng-*(เชิงมุม)


1

คุณสามารถสร้างพฤติกรรมเดียวกันกับการสร้างเครื่องมือแก้ไขแบบกำหนดเองอย่างง่าย ๆ ที่เรียกว่า DateTime.cshtml และบันทึกไว้ใน Views / Shared / EditorTemplates

@model DateTime

@{
    var css = ViewData["class"] ?? "";
    @Html.TextBox("", (Model != DateTime.MinValue? Model.ToString("dd/MM/yyyy") : string.Empty), new { @class = "calendar medium " + css});
}

และในมุมมองของคุณ

@Html.EditorFor(model => model.StartDate, new { @class = "required" })

โปรดทราบว่าในตัวอย่างของฉันฉันเข้ารหัส css สองคลาสและรูปแบบวันที่อย่างหนัก แน่นอนคุณสามารถเปลี่ยนแปลงได้ คุณยังสามารถทำเช่นเดียวกันกับแอตทริบิวต์ html อื่น ๆ เช่นอ่านได้อย่างเดียวปิดใช้งานและอื่น ๆ


1

ฉันใช้โซลูชันอื่นโดยใช้ตัวเลือกแอตทริบิวต์ CSS เพื่อให้ได้สิ่งที่คุณต้องการ

ระบุแอตทริบิวต์ HTML ที่คุณรู้จักและใส่สไตล์ที่คุณต้องการ

ชอบด้านล่าง:

input[type="date"]
{
     width: 150px;
}

1

ไม่จำเป็นต้องสร้างเทมเพลตที่กำหนดเองสำหรับ MVC 4. ใช้TextBoxแทนEditForที่นี่ไม่รองรับคุณลักษณะ html พิเศษที่นี่สนับสนุนเฉพาะจาก MVC 5. TextBox ควรรองรับ MVC 4 ฉันไม่รู้เกี่ยวกับเวอร์ชันอื่น

@Html.TextBox("test", "", new { @id = "signupform", @class = "form-control", @role = "form",@placeholder="Name" })


0

ฉันแค่ต้องกำหนดขนาดของหนึ่งช่องในหนึ่งหน้า คุณลักษณะการเข้ารหัสบนแบบจำลองและการสร้างเทมเพลตตัวแก้ไขที่กำหนดเองนั้นเกินความจริงดังนั้นฉันจึงใส่คำสั่ง @ Html.EditorFor ไว้ด้วยแท็ก span ที่เรียกว่าคลาสซึ่งระบุขนาดของกล่องข้อความ

ประกาศคลาส CSS:

.SpaceAvailableSearch input
{
    width:25px;
}

ดูรหัส:

<span class="SpaceAvailableSearch">@Html.EditorFor(model => model.SearchForm.SpaceAvailable)</span>

0

วิธีหนึ่งที่ดีที่สุดในการสมัครเรียนกับ@Html.EditorFor()MVC3 RAzor คือ

@Html.EditorFor(x => x.Created)


<style type="text/css">

#Created
{
    background: #EEE linear-gradient(#EEE,#EEE);   
    border: 1px solid #adadad;
    width:90%;
    }
</style>

มันจะเพิ่มสไตล์ด้านบนให้กับคุณ EditorFor()

มันใช้งานได้กับ MVC3

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.