ASP.NET MVC 3 Razor - Menambahkan kelas ke EditorFor

189

Saya mencoba menambahkan kelas ke input.

Ini tidak bekerja:

@Html.EditorFor(x => x.Created, new { @class = "date" })
pengguna137348
sumber
1
hei Anda bahkan mendapatkan nama yang tepat juga! - (untuk kode saya)
Pinch
1
CATATAN: Untuk beberapa jawaban, meskipun benar, seseorang mungkin harus menghapus cache browser agar dapat diaktualisasikan. Ini terutama benar jika solusinya berbasis css atau melibatkan kelas css! Hanya menghabiskan waktu cukup lama menyadari bahwa dengan masalah yang sedikit berbeda ....
JosephDoggie

Jawaban:

183

Menambahkan kelas ke Html.EditorFortidak masuk akal karena di dalam templatnya Anda bisa memiliki banyak tag berbeda. Jadi, Anda perlu menetapkan kelas di dalam template editor:

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

dan di templat khusus:

<div>
    @Html.TextBoxForModel(x => x.Created, new { @class = "date" })
</div>
Darin Dimitrov
sumber
5
Ini bekerja dengan baik, terima kasih. Mengalami kesulitan memformat nilai bidang per anotasi DisplayFormat dalam model saya. Diformat sebagai beranotasi dengan EditorFor dan DisplayFor, tetapi bukan TextBoxFor :( Sepertinya saya harus menggunakan templat khusus, kecuali seseorang dapat mengarahkan saya ke sesuatu yang saya lewatkan.?
Sean
Memiliki masalah yang sama ketika TextBoxFor tidak menghormati set DisplayFormat.
jocull
14
Ini adalah GroundController ke ModelTom, saya mengirimkan Anda View dan saya mengapung dengan cara yang paling MVC.
Trent Stewart
3
saya memiliki masalah yang sama, tetapi saya tidak dapat menggunakan TextBoxFor karena saya memerlukan DisplayFormat, yang berfungsi dengan Editor atau Display, tetapi pada saat yang sama saya perlu kelas juga, sehingga saya dapat menampilkan teks dalam bentuk readonly
AT
153

Pada ASP.NET MVC 5.1, menambahkan kelas ke suatu EditorFordimungkinkan (pertanyaan awal yang ditentukan ASP.NET MVC 3, dan jawaban yang diterima masih yang terbaik dengan yang dipertimbangkan).

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

Lihat: Apa yang Baru di ASP.NET MVC 5.1, dukungan Bootstrap untuk template editor

EF0
sumber
Itu luar biasa. Terima kasih!
Neill
1
Saya hampir melewatkan ini karena ini adalah 3 dalam daftar. Mungkin akan membantu untuk membuatnya menjadi pertanyaannya sendiri dan kemudian menjawabnya sendiri.
Robb Sadler
Selama MVC 2,3,4 saya tidak masuk akal ... tetapi karena lebih banyak orang mulai menggunakan dan mengeluh tentang kurangnya - tiba-tiba masuk akal di MVC 5: D +1
Piotr Kula
Sekarang ini seharusnya jawaban yang diterima menurut saya.
Manfred
101

Anda tidak dapat mengatur kelas untuk EditorFor generik. Jika Anda tahu editor yang Anda inginkan, Anda dapat menggunakannya langsung, di sana Anda dapat mengatur kelas. Anda tidak perlu membuat template khusus apa pun.

@Html.TextBoxFor(x => x.Created, new { @class = "date" }) 
TuomasK
sumber
5
Bagus, itu bagus tidak perlu membuat template khusus.
Steve Duitsman
Anda menghemat banyak waktu untuk saya jo!
Prashanth Benny
40

Kamu bisa memakai:

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

(Setidaknya dengan ASP.NET MVC 5, tapi saya tidak tahu bagaimana itu dengan ASP.NET MVC 3.)

przno
sumber
Silakan baca judul pertanyaan, ini adalah masalah untuk MVC3, Anda memberikan solusi MVC5 yang benar-benar menyesatkan.
Vincent
11
Dan tolong baca seluruh posting saya di mana saya menulisnya untuk MVC5. Ini adalah hasil pertama dari Google, jadi setelah saya menemukan solusi yang saya inginkan jadi bagikan di sini, mungkin itu dapat membantu beberapa orang.
przno
Yang ini membantu saya! Terima kasih @przno
Joakim M
29

Saya memiliki masalah frustasi yang sama, dan saya tidak ingin membuat EditorTemplate yang berlaku untuk semua nilai DateTime (ada waktu di UI saya di mana saya ingin menampilkan waktu dan bukan kalender drop-down jQuery UI ). Dalam penelitian saya, masalah utama yang saya temui adalah:

  • Pembantu TextBoxFor standar memungkinkan saya menerapkan kelas kustom "pemilih tanggal" untuk merender kalender jQuery UI yang tidak mencolok, tetapi TextBoxFor tidak akan memformat DateTime tanpa waktu, sehingga menyebabkan perenderan kalender gagal.
  • EditorFor standar akan menampilkan DateTime sebagai string yang diformat (ketika dihiasi dengan atribut yang tepat seperti [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")], tetapi itu tidak akan memungkinkan saya untuk menerapkan kelas "pemilih tanggal" kustom.

Oleh karena itu, saya membuat kelas HtmlHelper khusus yang memiliki manfaat berikut:

  • Metode ini secara otomatis mengubah DateTime ke ShortDateString yang diperlukan oleh kalender jQuery (jQuery akan gagal jika waktunya tiba).
  • Secara default, helper akan menerapkan htmlAttributes yang diperlukan untuk menampilkan kalender jQuery, tetapi mereka dapat ditimpa jika perlu.
  • Jika tanggalnya nol, ASP.NET MVC akan memberikan tanggal 1/1/0001 sebagai nilai.

Metode ini menggantikannya dengan string kosong.

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());
}

Dan bagi mereka yang ingin mengetahui sintaks JQuery yang mencari objek dengan date-pickerdekorasi kelas untuk kemudian membuat kalender, ini dia:

$(document).ready(function () {
    $('.date-picker').datepicker({ inline: true, maxDate: 0, changeMonth: true, changeYear: true });
    $('.date-picker').datepicker('option', 'showAnim', 'slideDown');
});
bigmac
sumber
Itu membantu saya sekarang, sedikit masalah dengan itu - Anda perlu memeriksa untuk memastikan valueAttribute.Value tidak kosong atau kosong sebelum meneruskannya ke metode DateTime.Parse, jika tidak, Anda berisiko FormatException dilemparkan pada bidang kosong.
Moo
Terima kasih. Anda banyak membantu saya.
Bronzato
Ini membantu saya, namun jika Anda menerapkan ini dan Anda mengharapkan bidang melakukan validasi, Anda perlu menerapkan logika ini: stackoverflow.com/questions/12023970/…
Aaron Newton
Pekerjaan bagus, tetapi tahukah Anda bahwa Anda dapat mengontrol apakah DateTime atau hanya kontrol Tanggal muncul hanya dengan menggunakan DateTimePickerFordan memperbarui bidang tanggal model yang Anda wakili dengan [DataType(DataType.Date)]atau [DataType(DataType.DateTime)]? Anda juga dapat memasukkannya ke, katakanlah, dalam bentuk bb / hh / tttt dengan .ParseFormats(new string[] { "MM/dd/yyyy" })(atau memodifikasinya dengan apa pun yang Anda inginkan, dengan mudah). Jika itu nol, bidang ini akan mengosongkannya tanpa harus
memasukkannya
Razor tidak akan mengenali @MyHtmlHelpers.CalenderTextBoxFor(model => model.ExpirationDate). Ada ide tentang cara mengimplementasikan ini?
Mehdiway
15

Dimungkinkan untuk memberikan kelas atau informasi lain melalui AdditionalViewData - Saya menggunakan ini di mana saya mengizinkan pengguna untuk membuat formulir berdasarkan bidang basis data (propertyName, editorType, dan editorClass).

Berdasarkan contoh awal Anda:

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

dan di templat khusus:

<div>
    @Html.TextBoxFor(x => x.Created, new { @class = ViewData["cssClass"] })
</div>
Brett
sumber
8
@ Html.EditorFor (x => x.Created, new {cssClass = "date"}) tidak berfungsi untuk saya
Alan Macdonald
1
Ini bekerja untuk saya & merupakan jawaban yang lebih baik daripada yang ditandai. Ini memberikan manfaat menggunakan templat, namun memungkinkan beberapa penyesuaian tanpa peretasan jQuery.
Chad Hedgcock
TextBoxFor mengabaikan atribut lain yang mungkin ditetapkan dalam model, seperti 'DataType misalnya.
Markus
8

Tidak ada EditorForoverride yang memungkinkan Anda meneruskan objek anonim yang propertinya entah bagaimana akan ditambahkan sebagai atribut pada beberapa tag, terutama untuk templat editor bawaan. Anda harus menulis template editor khusus Anda sendiri dan memberikan nilai yang Anda inginkan sebagai data view tambahan.

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

tidak mengizinkan argumen apa pun untuk diteruskan ke kotak Teks

Ini adalah bagaimana Anda dapat menerapkan atribut.

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

Menggunakan jQuery, Anda dapat melakukannya dengan mudah:

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

Ini adalah tag input Anda

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

Untuk DropDownlist Anda dapat menggunakan ini:

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

Untuk Dropdownlist:

@Html.DropDownlistFor(model=>model.Name)
Praveen MP
sumber
2

Sementara pertanyaannya ditargetkan pada MVC 3.0, kami menemukan masalah tetap ada di MVC 4.0 juga. MVC 5.0 sekarang termasuk kelebihan bawaan untuk htmlAttributes.

Saya terpaksa menggunakan MVC 4.0 di tempat kerja saya saat ini dan perlu menambahkan kelas css untuk integrasi JQuery. Saya memecahkan masalah ini menggunakan metode ekstensi tunggal ...

Metode ekstensi:

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;
        }
    }
}

Penggunaan Markup HTML:

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

(Pastikan untuk memasukkan namespace metode ekstensi dalam tampilan pisau cukur)

Penjelasan: Idenya adalah untuk menyuntikkan ke HTML yang ada. Saya memilih untuk mem-parsing elemen saat ini menggunakan Linq-to-XML using XDocument.Parse(). Saya melewatkan htmlAttributes sebagai tipe object. Saya menggunakan MVC RouteValueDictionaryuntuk mem-parsing htmlAttribut yang diteruskan. Saya menggabungkan atribut di mana mereka sudah ada, atau menambahkan atribut baru jika belum ada.

Jika input tidak dapat diuraikan oleh XDocument.Parse()saya meninggalkan semua harapan dan mengembalikan string input asli.

Sekarang saya dapat menggunakan manfaat DisplayFor (merender tipe data seperti mata uang secara tepat) tetapi juga memiliki kemampuan untuk menentukan kelas css (dan atribut lainnya dalam hal ini). Dapat membantu untuk menambahkan atribut seperti data-*, atau ng-*(Sudut).

barrypicker
sumber
1

Anda dapat membuat perilaku yang sama dengan membuat editor kustom sederhana bernama DateTime.cshtml, menyimpannya di 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});
}

dan dalam pandangan Anda

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

Perhatikan bahwa dalam contoh saya, saya mengkodekan dua kelas css dan format tanggal. Anda tentu saja dapat mengubahnya. Anda juga dapat melakukan hal yang sama dengan atribut html lainnya, seperti hanya baca, dinonaktifkan, dll.

Alexandre
sumber
1

Saya menggunakan solusi lain menggunakan pemilih atribut CSS untuk mendapatkan apa yang Anda butuhkan.

Tunjukkan atribut HTML yang Anda kenal dan masukkan ke dalam gaya relatif yang Anda inginkan.

Seperti di bawah ini:

input[type="date"]
{
     width: 150px;
}
Max Clapton
sumber
1

Tidak perlu membuat template khusus untuk MVC 4. Gunakan TextBox alih-alih EditUntuk di sini atribut html khusus tidak didukung, hanya didukung dari MVC 5. TextBox harus mendukung untuk MVC 4, saya tidak tahu tentang versi lain.

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

Anda juga bisa melakukannya melalui jQuery:

$('#x_Created').addClass(date);
Scott R. Frost
sumber
0

Saya hanya perlu mengatur ukuran satu kotak teks pada satu halaman. Atribut pengkodean pada model dan membuat templat editor kustom terlalu banyak, jadi saya hanya membungkus panggilan @Html.EditorFor dengan tag rentang yang disebut kelas yang menentukan ukuran kotak teks.

Deklarasi kelas CSS:

.SpaceAvailableSearch input
{
    width:25px;
}

Lihat kode:

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

Salah satu cara terbaik untuk menerapkan kelas ke @Html.EditorFor()dalam MVC3 RAzor adalah

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


<style type="text/css">

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

Ini akan menambah gaya di atas untuk Anda EditorFor()

Ini berfungsi untuk MVC3.

Bilal
sumber