Html.TextBoxFor के लिए एक शर्त के आधार पर अक्षम विशेषता सेट करें


81

मैं नीचे asp.net MVC में Html.TextBoxFor के लिए एक शर्त के आधार पर अक्षम विशेषता सेट करना चाहता हूं

@Html.TextBoxFor(model => model.ExpireDate, new { style = "width: 70px;", maxlength = "10", id = "expire-date" disabled = (Model.ExpireDate == null ? "disable" : "") })

इस सहायक में दो आउटपुट अक्षम हैं = "अक्षम" या अक्षम = ""। दोनों विषय टेक्स्टबॉक्स को अक्षम कर देते हैं।

यदि मैं Model.ExpireDate == नल को सक्षम करना चाहता हूं, तो मैं टेक्स्टबॉक्स को अक्षम करना चाहता हूं


मेरे जवाब पर एक नज़र डालें: stackoverflow.com/a/43131930/6680521
एक्सग्रेगोरि

जवाबों:


85

मान्य तरीका है:

disabled="disabled"

ब्राउज़र भी स्वीकार कर सकते हैं disabled=""लेकिन मैं आपको पहले दृष्टिकोण की सिफारिश करूंगा।

अब यह कहा जा रहा है कि मैं आपको कस्टम HTML सहायक को लिखने की सलाह दूंगा ताकि इस अक्षम कार्यक्षमता को पुन: प्रयोग करने योग्य कोड में कूटबद्ध किया जा सके:

using System;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

public static class HtmlExtensions
{
    public static IHtmlString MyTextBoxFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression, 
        object htmlAttributes, 
        bool disabled
    )
    {
        var attributes = new RouteValueDictionary(htmlAttributes);
        if (disabled)
        {
            attributes["disabled"] = "disabled";
        }
        return htmlHelper.TextBoxFor(expression, attributes);
    }
}

जो आप इस तरह उपयोग कर सकते हैं:

@Html.MyTextBoxFor(
    model => model.ExpireDate, 
    new { 
        style = "width: 70px;", 
        maxlength = "10", 
        id = "expire-date" 
    }, 
    Model.ExpireDate == null
)

और आप इस सहायक में और भी बुद्धिमत्ता ला सकते हैं :

public static class HtmlExtensions
{
    public static IHtmlString MyTextBoxFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        object htmlAttributes
    )
    {
        var attributes = new RouteValueDictionary(htmlAttributes);
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        if (metaData.Model == null)
        {
            attributes["disabled"] = "disabled";
        }
        return htmlHelper.TextBoxFor(expression, attributes);
    }
}

ताकि अब आपको अक्षम स्थिति निर्दिष्ट करने की आवश्यकता न हो:

@Html.MyTextBoxFor(
    model => model.ExpireDate, 
    new { 
        style = "width: 70px;", 
        maxlength = "10", 
        id = "expire-date" 
    }
)

यदि मॉडल Model.ExpireDate == मैं इसे सक्षम करना चाहता हूं, तो मैं टेक्स्टबॉक्स को अक्षम करना चाहता हूं
Guti Farangi

4
यह समाधान बहुत अच्छा है - जहाँ तक यह जाता है ... लेकिन एक अच्छा समाधान खोजना अच्छा होगा जिसे प्रत्येक HtmlHelper के चारों ओर एक आवरण लगाने की आवश्यकता नहीं है जिसका हम उपयोग करते हैं जिसमें एक निष्क्रिय विशेषता हो सकती है (TextBoxFor, TextAreaFor, CheckBoxFor, आदि। ।) आदर्श रूप से कुछ ऐसा है जो मौजूदा लोगों के साथ इनलाइन काम करता है। मैंने एक ऐसा समाधान बनाया है जो मूल रूप से सिर्फ अनाम वस्तु को लपेटता है और एक रूटवैल्यूडॉर रिटर्न देता है - लेकिन यह विशेष रूप से साफ महसूस नहीं करता है।
मीर

3
"अक्षम", "अक्षम = ''" और "अक्षम = 'अक्षम'" सभी HTML में समान रूप से मान्य हैं, और यह कहना भ्रामक (और गलत) है कि छोटे लोगों को केवल विभिन्न ब्राउज़रों द्वारा स्वीकार किया जा सकता है। सी एफ dev.w3.org/html5/markup/syntax.html#syntax-attr-empty
Shautieh

53

दरअसल, आंतरिक व्यवहार एक शब्दकोश में अनाम वस्तु का अनुवाद कर रहा है। इसलिए मैं इन परिदृश्यों में एक शब्दकोश के लिए जा रहा हूँ:

@{
  var htmlAttributes = new Dictionary<string, object>
  {
    { "class" , "form-control"},
    { "placeholder", "Why?" }        
  };
  if (Model.IsDisabled)
  {
    htmlAttributes.Add("disabled", "disabled");
  }
}
@Html.EditorFor(m => m.Description, new { htmlAttributes = htmlAttributes })

या, स्टीफन ने यहाँ टिप्पणी की :

@Html.EditorFor(m => m.Description,
    Model.IsDisabled ? (object)new { disabled = "disabled" } : (object)new { })

@ Html.EditorFor (m => m.Description, Model.IsDisabled? (ऑब्जेक्ट) नया {अक्षम = "अक्षम"}: (ऑब्जेक्ट) नया {}) => यह सबसे अच्छा तरीका लगता है। धन्यवाद
चेकर

23

मुझे डारिन विधि पसंद है। लेकिन इसे हल करने का त्वरित तरीका,

Html.TextBox("Expiry", null, new { style = "width: 70px;", maxlength = "10", id = "expire-date", disabled = "disabled" }).ToString().Replace("disabled=\"disabled\"", (1 == 2 ? "" : "disabled=\"disabled\""))

1
मुझे लगता है कि आपको @ Html.Raw ()
Shadi Namrouti

14

मैंने जो एक सरल तरीका इस्तेमाल किया है वह सशर्त प्रतिपादन है:

@(Model.ExpireDate == null ? 
  @Html.TextBoxFor(m => m.ExpireDate, new { @disabled = "disabled" }) : 
  @Html.TextBoxFor(m => m.ExpireDate)
)

13

यदि आप html सहायकों का उपयोग नहीं करते हैं, तो आप इस तरह की सरल टर्नरी अभिव्यक्ति का उपयोग कर सकते हैं:

<input name="Field"
       value="@Model.Field" tabindex="0"
       @(Model.IsDisabledField ? "disabled=\"disabled\"" : "")>

13

मैंने इसे कुछ विस्तार विधियों का उपयोग करके हासिल किया

private const string endFieldPattern = "^(.*?)>";

    public static MvcHtmlString IsDisabled(this MvcHtmlString htmlString, bool disabled)
    {
        string rawString = htmlString.ToString();
        if (disabled)
        {
            rawString = Regex.Replace(rawString, endFieldPattern, "$1 disabled=\"disabled\">");
        }

        return new MvcHtmlString(rawString);
    }

    public static MvcHtmlString IsReadonly(this MvcHtmlString htmlString, bool @readonly)
    {
        string rawString = htmlString.ToString();
        if (@readonly)
        {
            rawString = Regex.Replace(rawString, endFieldPattern, "$1 readonly=\"readonly\">");
        }

        return new MvcHtmlString(rawString);
    }

और फिर....

@Html.TextBoxFor(model => model.Name, new { @class= "someclass"}).IsDisabled(Model.ExpireDate == null)

काम करता है अगर आप rawstring.Length - 7 के लिए 2 बदलते हैं और "" अंतिम के बाद "जोड़ते हैं।
जोज़ेफ कृशिव

TextAreaFor के साथ काम नहीं करता है, सभी प्रकार के इनपुट के लिए एक समाधान की आवश्यकता है
erhan355

10

यह देर हो चुकी है, लेकिन कुछ लोगों के लिए मददगार हो सकती है।

मैंने @ DarinDimitrov का उत्तर दूसरी वस्तु को पारित करने की अनुमति देने के लिए दिया है जो बूलियन HTML विशेषताओं की किसी भी संख्या को लेती है disabled="disabled" checked="checked", selected="selected"

यह गुण केवल तभी प्रस्तुत करेगा जब संपत्ति का मूल्य सही है, और कुछ भी और विशेषता बिल्कुल भी प्रदान नहीं की जाएगी।

कस्टम पुन: उपयोग HtmlHelper:

public static class HtmlExtensions
{
    public static IHtmlString MyTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                                Expression<Func<TModel, TProperty>> expression,
                                                                object htmlAttributes,
                                                                object booleanHtmlAttributes)
    {
        var attributes = new RouteValueDictionary(htmlAttributes);

        //Reflect over the properties of the newly added booleanHtmlAttributes object
        foreach (var prop in booleanHtmlAttributes.GetType().GetProperties())
        {
            //Find only the properties that are true and inject into the main attributes.
            //and discard the rest.
            if (ValueIsTrue(prop.GetValue(booleanHtmlAttributes, null)))
            {
                attributes[prop.Name] = prop.Name;
            }                
        }                                

        return htmlHelper.TextBoxFor(expression, attributes);
    }

    private static bool ValueIsTrue(object obj)
    {
        bool res = false;
        try
        {
            res = Convert.ToBoolean(obj);
        }
        catch (FormatException)
        {
            res = false;
        }
        catch(InvalidCastException)
        {
            res = false;
        }
        return res;
    }

}

जिसका आप इस तरह उपयोग कर सकते हैं:

@Html.MyTextBoxFor(m => Model.Employee.Name
                   , new { @class = "x-large" , placeholder = "Type something…" }
                   , new { disabled = true})

10

रूटवैल्यूडॉर का उपयोग करके इसे हल किया गया है (htmlAttributes के रूप में ठीक काम करता है क्योंकि यह IDEDIA पर आधारित है) और एक एक्सटेंशन विधि:

public static RouteValueDictionary AddIf(this RouteValueDictionary dict, bool condition, string name, object value)
{
    if (condition) dict.Add(name, value);
    return dict;
}

उपयोग:

@Html.TextBoxFor(m => m.GovId, new RouteValueDictionary(new { @class = "form-control" })
.AddIf(Model.IsEntityFieldsLocked, "disabled", "disabled"))

इसका श्रेय https://stackoverflow.com/a/3481969/40939 पर जाता है


IMHO, यह सबसे अच्छा जवाब है
JenonD

6

यदि आप Html हेल्पर्स का उपयोग नहीं करना चाहते हैं तो इसे मेरे समाधान के लिए देखें

disabled="@(your Expression that returns true or false")"

बस यही है

@{
    bool isManager = (Session["User"] as User).IsManager;
}
<textarea rows="4" name="LetterManagerNotes" disabled="@(!isManager)"></textarea>

और मुझे लगता है कि ऐसा करने का बेहतर तरीका यह है कि नियंत्रक में जांच करें और इसे एक चर के भीतर सहेजें जो कि दृश्य (रेजर इंजन) के अंदर पहुंचाने के लिए है the view free from business logic


7
यदि आप किसी नियंत्रण में अक्षम विशेषता का उपयोग करते हैं, तो नियंत्रण को निष्क्रिय कर दिया जाएगा चाहे वह विशेषता किसी भी मूल्य का हो। यहां तक ​​कि एक मूल्य के बिना विशेषता की उपस्थिति नियंत्रण को अक्षम कर देगी।
गीकी गाय

2
यह समाधान वास्तव में अच्छी तरह से काम करता है, और मुझे संदेह है कि डाउनवोटर्स ने अनदेखी की है कि अभिव्यक्ति बूलियन है। जब अभिव्यक्ति बूलियन होती है, तो अक्षम विशेषता अक्षम = "अक्षम" के रूप में प्रस्तुत करेगी यदि अभिव्यक्ति सही है, या गलत होने पर पूरी तरह से छोड़ा जा सकता है। जो जैसा चाहता है वैसा ही होता है।
कार्स्टन

यह या तो अक्षम = "झूठा" या अक्षम = "सही" रेंडर करेगा, नहीं?
एंडिज

4

फिर भी एक और उपाय यह होगा Dictionary<string, object>कि आप कॉल करने से पहले एक TextBoxForडिक्शनरी बनाएं और उस शब्दकोश को पास करें। डिक्शनरी में, "disabled"कुंजी तभी जोड़ें जब टेक्स्टबॉक्स को डिसेबल करना हो। सबसे साफ समाधान नहीं बल्कि सरल और सीधा।


2

एक अन्य तरीका क्लाइंट साइड पर टेक्स्ट बॉक्स को अक्षम करना है।

आपके मामले में आपके पास केवल एक टेक्स्टबॉक्स है जिसे आपको अक्षम करने की आवश्यकता है लेकिन उस मामले पर विचार करें जहां आपके पास कई इनपुट, चयन, और टेक्सटेरिया फ़ील्ड हैं जिन्हें आपको अक्षम करने की आवश्यकता है।

इसे jquery + के माध्यम से करना बहुत आसान है (क्योंकि हम क्लाइंट से आने वाले डेटा पर भरोसा नहीं कर सकते हैं) नियंत्रक को कुछ तर्क जोड़ते हैं ताकि इन क्षेत्रों को बचाया जा सके।

यहाँ एक उदाहरण है:

<input id="document_Status" name="document.Status" type="hidden" value="2" />

$(document).ready(function () {

    disableAll();
}

function disableAll() {
  var status = $('#document_Status').val();

  if (status != 0) {
      $("input").attr('disabled', true);
      $("textarea").attr('disabled', true);
      $("select").attr('disabled', true);
  }
}

0

मैं विस्तार विधि दृष्टिकोण पसंद करता हूं ताकि आपको सभी संभावित मापदंडों से गुजरना न पड़े।
हालाँकि रेगुलर एक्सप्रेशन का उपयोग करना काफी मुश्किल (और कुछ धीमा) हो सकता है इसलिए मैंने XDocumentइसके बजाय इसका इस्तेमाल किया:

public static MvcHtmlString SetDisabled(this MvcHtmlString html, bool isDisabled)
{
    var xDocument = XDocument.Parse(html.ToHtmlString());
    if (!(xDocument.FirstNode is XElement element))
    {
        return html;
    }

    element.SetAttributeValue("disabled", isDisabled ? "disabled" : null);
    return MvcHtmlString.Create(element.ToString());
}

विस्तार विधि का उपयोग इस तरह करें:
@Html.EditorFor(m => m.MyProperty).SetDisabled(Model.ExpireDate == null)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.