Jak utworzyć pole tekstowe tylko do odczytu w programie ASP.NET MVC3 Razor


118

Jak utworzyć pole tekstowe tylko do odczytu w ASP.NET MVC3 za pomocą aparatu widoku Razor?

Czy jest do tego dostępna metoda HTMLHelper?

Coś takiego jak poniżej?

@Html.ReadOnlyTextBoxFor(m => m.userCode)

Odpowiedzi:


246
@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })

Zapraszamy do stworzenia pomocnika HTML do tego, ale jest to po prostu atrybut HTML, jak każdy inny. Czy stworzyłbyś pomocnika HTML dla pola tekstowego, które ma inne atrybuty?


1
@Shyju Przepraszamy, brakowało mi @przedrostka readonlywłaściwości. Zobacz moją edycję.

7
W przyszłości, jeśli pojawią się jakiekolwiek błędy podczas dodawania właściwości do argumentu obiektu dynamicznego, można poprzedzić je rozszerzeniem @. Zwykle zobaczysz go tylko ze słowami kluczowymi pasującymi do atrybutów HTML (takich jak tylko do odczytu, klasa itp.)
Brad Christie,

10
@BradChristie: Nie; potrzebujesz tylko @atrybutów, które pasują do słów kluczowych C # .
SLaks

1
@BradChristie: Źle odczytałem twój komentarz („słowa kluczowe” były niejednoznaczne)
SLaks

1
Jeśli masz wiele atrybutów html, możesz zrobić na przykład:@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly", @class="form-control" })
benscabbia

32

AKTUALIZACJA: Teraz bardzo łatwo jest dodać atrybuty HTML do domyślnych szablonów edytora. Neans zamiast robić to:

@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })

po prostu możesz to zrobić:

@Html.EditorFor(m => m.userCode, new { htmlAttributes = new { @readonly="readonly" } })

Korzyści: nie musisz dzwonić .TextBoxForitp. Po szablony. Po prostu zadzwoń .EditorFor.


Chociaż rozwiązanie @ Shark działa poprawnie i jest proste i przydatne, moim rozwiązaniem (którego używam zawsze) jest to: Utwórz atrybut, editor-templatektóry może obsługiwać readonlyatrybut :

  1. Utwórz folder o nazwie EditorTemplatesw~/Views/Shared/
  2. Utwórz brzytwę PartialViewo nazwieString.cshtml
  3. Wypełnij String.cshtmlten kod:

    @if(ViewData.ModelMetadata.IsReadOnly) {
        @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
            new { @class = "text-box single-line readonly", @readonly = "readonly", disabled = "disabled" })
    } else {
        @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
            new { @class = "text-box single-line" })
    }
  4. W klasie modelu umieść [ReadOnly(true)]atrybut na właściwościach, którymi chcesz być readonly.

Na przykład,

public class Model {
    // [your-annotations-here]
    public string EditablePropertyExample { get; set; }

    // [your-annotations-here]
    [ReadOnly(true)]
    public string ReadOnlyPropertyExample { get; set; }
}

Teraz możesz po prostu użyć domyślnej składni Razor:

@Html.EditorFor(m => m.EditablePropertyExample)
@Html.EditorFor(m => m.ReadOnlyPropertyExample)

Pierwsza renderuje normalność w text-boxten sposób:

<input class="text-box single-line" id="field-id" name="field-name" />

A drugi odda;

<input readonly="readonly" disabled="disabled" class="text-box single-line readonly" id="field-id" name="field-name" />

Można korzystać z tego rozwiązania dla każdego rodzaju danych ( DateTime, DateTimeOffset, DataType.Text, DataType.MultilineTexti tak dalej). Po prostu utwórz plik editor-template.


2
+1, ponieważ użyłeś „ViewData.ModelMetadata.IsReadOnly”. Spodziewałem się, że MVC weźmie pod uwagę te rzeczy w wersji 4.
cleftheris

@cleftheris no cóż, jesteśmy teraz w wersji 5, a MVC nadal ich nie zabrał;)
ravy amiry

2
@Javad_Amiry - świetna odpowiedź - zaimplementowałem to i wydawało się, że działa świetnie, dopóki nie kliknąłem Zapisz na stronie edycji rusztowania. Następnie okazuje się, że właściwości z wartością [ReadOnly (true)] spowodują wysłanie do bazy danych wartości NULL zamiast rzeczywistej wartości właściwości. Czy spotkałeś się z tym?
Percy

5

Rozwiązanie z TextBoxFor jest w porządku, ale jeśli nie chcesz widzieć pola takiego jak EditBox stylowy (może to być trochę mylące dla użytkownika), wprowadź następujące zmiany:

  1. Kod Razor przed zmianami

    <div class="editor-field">
         @Html.EditorFor(model => model.Text)
         @Html.ValidationMessageFor(model => model.Text)
    </div>
  2. Po zmianach

    <!-- New div display-field (after div editor-label) -->
    <div class="display-field">
        @Html.DisplayFor(model => model.Text)
    </div>
    
    <div class="editor-field">
        <!-- change to HiddenFor in existing div editor-field -->
        @Html.HiddenFor(model => model.Text)
        @Html.ValidationMessageFor(model => model.Text)
    </div>

Generalnie to rozwiązanie uniemożliwia edycję pola, ale pokazuje jego wartość. Nie ma potrzeby wprowadzania modyfikacji związanych z kodem.


1
Myślę, że posiadanie CSS dla klas edytora pola i pola wyświetlania może być naprawdę pomocne.
DOK

Co masz na myśli , mówiąc „to rozwiązanie uniemożliwia wniesienie sprzeciwu wobec edycji” (wydaje się niezrozumiałe)? Prosimy o odpowiedź, edytując swoją odpowiedź , a nie w komentarzach (w stosownych przypadkach).
Peter Mortensen

3

Z napisami do poprzedniej odpowiedzi autorstwa @Bronek i @Shimmy:

To jest tak, jakbym zrobił to samo w ASP.NET Core:

<input asp-for="DisabledField" disabled="disabled" />
<input asp-for="DisabledField" class="hidden" />

Pierwsze wejście jest tylko do odczytu, a drugie przekazuje wartość do sterownika i jest ukryte. Mam nadzieję, że przyda się komuś pracującemu z ASP.NET Core.


0
 @Html.TextBox("Receivers", Model, new { @class = "form-control", style = "width: 300px", @readonly = "readonly" })

1
Wytłumaczenie byłoby w porządku.
Peter Mortensen

0
@Html.TextBoxFor(model => model.IsActive, new { readonly= "readonly" })

To jest dobre dla pola tekstowego. Jeśli jednak spróbujesz zrobić to samo dla, checkboxspróbuj użyć tego, jeśli go używasz:

@Html.CheckBoxFor(model => model.IsActive, new { onclick = "return false" })

Ale nie używaj disable, ponieważ disable zawsze wysyła wartość domyślną falsedo serwera - albo był w stanie zaznaczonym, albo niezaznaczonym. A readonlynie działa w przypadku pola wyboru i radio button. readonlydziała tylko dla textpól.


A co z listami rozwijanymi?
user3020047


0

Możesz użyć poniższego kodu do utworzenia TextBox jako tylko do odczytu.

Metoda 1

 @Html.TextBoxFor(model => model.Fields[i].TheField, new { @readonly = true })

Metoda 2

@Html.TextBoxFor(model => model.Fields[i].TheField, new { htmlAttributes = new {disabled = "disabled"}})
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.