ASP.NET MVC 3 Razor - EditorFor için sınıf ekleme


189

Bir girdiye bir sınıf eklemeye çalışıyorum.

Bu çalışmıyor:

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

1
hey adı bile doğru buldun! - (kodum için)
Tutam

1
NOT: Bazı yanıtlar için, doğru olsalar bile, bunun gerçekleştirilebilmesi için tarayıcı önbelleğini temizlemeniz gerekebilir. Bu, özellikle çözüm css tabanlıysa veya bir css sınıfı içeriyorsa geçerlidir! Sadece biraz farklı bir konu ile bunu fark oldukça uzun bir süre geçirdim ....
JosephDoggie

Yanıtlar:


183

Bir sınıf eklemek Html.EditorFor, şablonunun içinde olduğu gibi bir anlam ifade etmez, birçok farklı etikete sahip olabilirsiniz. Bu yüzden sınıfı editör şablonunun içine atamanız gerekir:

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

ve özel şablonda:

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

5
Harika çalışıyor, teşekkürler. Modelimdeki DisplayFormat ek açıklaması başına alan değerini biçimlendirme konusunda sorun yaşıyorum. EditorFor ve DisplayFor ile açıklamalı olarak biçimlendirilmiş, ancak TextBoxFor :( Görünüşe göre birisi beni eksik bir şeye işaret edemezse, özel bir şablon kullanmalıyım.?
Sean

TextBoxFor, DisplayFormat kümesini onurlandırmazsa aynı sorunu yaşıyoruz.
Kasım'da jocull

14
Bu ModelTom için GroundController, size Görünüm gönderiyorum ve en MVC şekilde yüzen.
Trent Stewart

3
Ben aynı sorunu var, ama ben EditorBox veya Display ile çalışan DisplayFormat, ihtiyacım olarak TextBoxFor kullanamazsınız, ama aynı zamanda ben de sınıf gerekir, böylece ben salt okunur biçimde metin görüntüleyebilir
AT

153

ASP.NET MVC 5.1'den itibaren, sınıfına bir sınıf eklemek EditorFormümkündür (asıl soru ASP.NET MVC 3'ü belirtmiştir ve kabul edilen cevap yine de dikkate alınan en iyisidir).

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

Bkz: ASP.NET MVC 5.1'deki Yenilikler, Düzenleyici şablonları için Bootstrap desteği


Bu harika. Teşekkürler!
Neill

1
Listede 3. olduğu için bunu neredeyse özledim. Muhtemelen kendi sorusunu sormak ve sonra kendiniz cevaplamak yararlı olacaktır.
Robb Sadler

MVC 2,3,4 sırasında mantıklı gelmedim ... ama daha fazla insan eksikliğinden yararlanmaya ve şikayet etmeye başladığında - MVC 5: D +1
Piotr Kula

Bu benim görüşüme göre kabul edilen cevap olmalı.
Manfred

101

Genel EditorFor için sınıf ayarlayamazsınız. İstediğiniz editörü biliyorsanız, hemen kullanabilirsiniz, orada sınıfı ayarlayabilirsiniz. Herhangi bir özel şablon oluşturmanıza gerek yoktur.

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

5
İyi bir anlaşma, özel bir şablon oluşturmaya gerek duymamak güzeldi.
Steve Duitsman

benim için çok zaman kazandın jo!
Prashanth Benny

40

Kullanabilirsiniz:

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

(En azından ASP.NET MVC 5 ile, ama ASP.NET MVC 3 ile nasıl olduğunu bilmiyorum.)


Lütfen soru başlığını okuyun, bu MVC3 için sorun, tamamen yanıltıcı olan MVC5 çözümü sağlarsınız.
Vincent

11
Ve lütfen yazdığım tüm yazımı okudunuz, MVC5 için. Bu Google'ın ilk sonucuydu, bu yüzden burada bulduğum çözümü buldum, belki bazı insanlara yardımcı olabilir.
przno

Bu bana yardımcı oldu! Teşekkürler @przno
Joakim M

29

Aynı sinir bozucu sorun vardı ve tüm DateTime değerlerine uygulanan bir EditorTemplate oluşturmak istemiyordu (zaman zaman göstermek istiyorum, bir jQuery UI açılan takvim değil benim UI zamanlar vardı ). Araştırmamda karşılaştığım temel konular şunlardı:

  • Standart TextBoxFor yardımcısı, göze çarpmayan jQuery UI takvimini oluşturmak için özel bir "tarih seçici" sınıfı uygulamama izin verdi, ancak TextBoxFor, bir DateTime'ı zaman olmadan biçimlendirmediğinden takvim oluşturma işleminin başarısız olmasına neden oldu.
  • Standart EditorFor , DateTime'ı biçimlendirilmiş bir dize olarak görüntüler (örneğin, uygun özniteliklerle süslendiğinde [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")], ancak özel "tarih seçici" sınıfını uygulamama izin vermez.

Bu nedenle, aşağıdaki yararları olan özel HtmlHelper sınıfı oluşturdum:

  • Yöntem otomatik olarak DateTime'ı jQuery takviminin gerektirdiği ShortDateString öğesine dönüştürür (saat mevcutsa jQuery başarısız olur).
  • Varsayılan olarak, yardımcı bir jQuery takvimi görüntülemek için gerekli htmlAttributes uygular, ancak gerekirse geçersiz kılınabilir.
  • Tarih null ise, ASP.NET MVC değer olarak 1/1/0001 tarihini koyacaktır.

Bu yöntem, bunu boş bir dize ile değiştirir.

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

Ve date-pickersonra takvimi oluşturmak için sınıf süslemeli nesneleri arayan JQuery sözdizimini bilmek isteyenler için işte burada:

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

Bu bana şimdi yardımcı oldu, küçük bir sorun - DateTime.Parse yöntemine geçmeden önce valueAttribute.Value boş veya boşluk olmadığından emin olmak için kontrol etmeniz gerekir, aksi takdirde boş bir alana atılmış bir FormatException riski vardır.
Moo

Teşekkürler. Bana çok yardımcı oldun.
Bronzato

Bu bana yardımcı oldu, ancak bunu uyguluyorsanız ve alanın doğrulama yapmasını bekliyorsanız, bu mantığı uygulamanız gerekir: stackoverflow.com/questions/12023970/…
Aaron Newton

İyi iş, ancak bir DateTime ya da sadece bir Tarih denetimi görünürse sadece kullanarak kontrol edebilirsiniz bildin DateTimePickerForve birlikte temsil ettiğiniz modelin tarih alanı güncelleme [DataType(DataType.Date)]veya [DataType(DataType.DateTime)]? Ayrıca, diyelim, aa / gg / yyyy formuna da yerleştirebilirsiniz .ParseFormats(new string[] { "MM/dd/yyyy" })(veya istediğiniz her şeyi kolayca değiştirebilirsiniz).
Boşsa

Ustura tanımıyor @MyHtmlHelpers.CalenderTextBoxFor(model => model.ExpirationDate). Bunu nasıl uygulayacağınız konusunda herhangi bir fikriniz var mı?
Mehdiway

15

AdditionalViewData aracılığıyla bir sınıf veya diğer bilgileri sağlamak mümkündür - ben bir kullanıcı veritabanı alanlarına (propertyName, editorType ve editorClass) dayalı bir form oluşturmak için izin veriyorum.

İlk örneğinize dayanarak:

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

ve özel şablonda:

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

8
@ Html.EditorFor (x => x.Created, yeni {cssClass = "date"}) benim için çalışmadı
Alan Macdonald

1
Bu benim için çalıştı & işaretli olandan daha iyi bir cevaptır. Bir şablon kullanmanın avantajını sağlar, ancak jQuery saldırıları olmadan bazı özelleştirmelere izin verir.
Chad Hedgcock

TextBoxFor, modelde ayarlanabilecek diğer nitelikleri yoksayar; örneğin 'DataType'.
Markus

8

EditorForÖzellikle yerleşik düzenleyici şablonları için, özellikleri bir şekilde etikete eklenecek olan anonim bir nesneye geçmenize izin veren herhangi bir geçersiz kılma yoktur. Kendi özel düzenleyici şablonunuzu yazmanız ve istediğiniz değeri ek görünüm verileri olarak iletmeniz gerekir.


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

Metin kutusu için herhangi bir argümanın iletilmesine izin vermez

Nitelikleri bu şekilde uygulayabilirsiniz.

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

2

JQuery kullanarak kolayca yapabilirsiniz:

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

İşte giriş etiketiniz

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

DropDownlist için bunu kullanabilirsiniz:

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

Açılır Liste için:

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

2

Soru MVC 3.0'ı hedeflerken, sorunun MVC 4.0'da da devam ettiğini görüyoruz. MVC 5.0 artık htmlAttributes için yerel bir aşırı yük içeriyor.

Mevcut iş yerimde MVC 4.0 kullanmak zorunda kaldım ve JQuery entegrasyonu için bir css sınıfı eklemem gerekiyor. Bu sorunu tek bir uzantı yöntemi kullanarak çözdüm ...

Genişletme Yöntemi:

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 İşaretleme Kullanımı:

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

(Genişletme yönteminin ad alanını ustura görünümüne eklediğinizden emin olun)

Açıklama: Fikir, mevcut HTML'ye enjekte etmektir. Linq-to-XML kullanarak geçerli öğeyi ayrıştırmak için seçti XDocument.Parse(). HtmlAttributes türünü iletiyorum object. Ben RouteValueDictionaryhtmlAttributes geçirilen ayrıştırmak için MVC kullanın. Ben zaten var olan öznitelikleri birleştirmek veya henüz yoksa yeni bir öznitelik ekleyin.

Tarafından durumunda giriş ayrıştırılabilir değil XDocument.Parse()tüm umudunu terk edip orijinal giriş dizesi döndürür.

Şimdi DisplayFor (para birimi gibi veri türlerini uygun şekilde işleme) yararını kullanabilirsiniz ama aynı zamanda css sınıfları (ve bu konuda başka bir öznitelik) belirleme yeteneğine sahip. data-*Veya ng-*(Açısal) gibi özellikler eklemek için yardımcı olabilir .


1

Aynı davranışı, DateTime.cshtml adlı basit bir özel düzenleyici oluşturarak oluşturabilir ve Görünümler / Paylaşılan / Düzenleyici Şablonları'na kaydedebilirsiniz.

@model DateTime

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

ve senin görüşlerine göre

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

Örneğimde iki css sınıfını ve tarih formatını sabit kodladığımı unutmayın. Elbette bunu değiştirebilirsiniz. Aynı şeyi salt okunur, devre dışı bırakılmış vb.Gibi diğer html özellikleriyle de yapabilirsiniz.


1

İhtiyacınız olanı elde etmek için CSS özellik seçicileri kullanarak başka bir çözüm kullandım.

Bildiğiniz ve istediğiniz göreceli stile yerleştirdiğiniz HTML özelliğini belirtin.

Aşağıdaki gibi:

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

1

MVC 4 için özel şablon oluşturmaya gerek yok . EditFor yerine TextBox kullanın Burada özel html öznitelikleri desteklenmez, sadece MVC 5'den desteklenir. TextBox MVC 4 için desteklemelidir, diğer sürüm hakkında bilmiyorum.

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


0

Sadece bir sayfada bir metin kutusunun boyutunu ayarlamam gerekiyordu. Modeldeki kodlama nitelikleri ve özel editör şablonları oluşturmak aşırıya kaçmıştı, bu yüzden @ Html.EditorFor çağrısını, metin kutusunun boyutunu belirten bir sınıf adı verilen bir span etiketi ile tamamladım.

CSS sınıfı bildirimi:

.SpaceAvailableSearch input
{
    width:25px;
}

Kodu görüntüle:

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

0

@Html.EditorFor()MVC3 RAzor'da sınıf uygulamasının en iyi yolu

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


<style type="text/css">

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

Bu yukarıdaki stil katacak EditorFor()

MVC3 için çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.