Добавление строковой переменной в качестве атрибута html helper [duplicate]

Я реализовал как:

public interface Constants{
    Integer PAGE_SIZE = 20;
}

-

public class JspConstants extends HashMap<String, String> {

        public JspConstants() {
            Class c = Constants.class;
            Field[] fields = c.getDeclaredFields();
            for(Field field : fields) {
                int modifier = field.getModifiers();
                if(Modifier.isPublic(modifier) && Modifier.isStatic(modifier) && Modifier.isFinal(modifier)) {
                    try {
                        Object o = field.get(null);
                        put(field.getName(), o != null ? o.toString() : null);
                    } catch(IllegalAccessException ignored) {
                    }
                }
            }
        }

        @Override
        public String get(Object key) {
            String result = super.get(key);
            if(StringUtils.isEmpty(result)) {
                throw new IllegalArgumentException("Check key! The key is wrong, no such constant!");
            }
            return result;
        }
    }

Следующий шаг поместить экземпляр этого класса в servlerContext

public class ApplicationInitializer implements ServletContextListener {


    @Override
    public void contextInitialized(ServletContextEvent sce) {
        sce.getServletContext().setAttribute("Constants", new JspConstants());
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

добавить слушателя в web.xml

<listener>
    <listener-class>com.example.ApplicationInitializer</listener-class>
</listener>
Доступ к

в jsp

${Constants.PAGE_SIZE}
60
задан tereško 1 December 2012 в 08:19
поделиться

6 ответов

Определите это где-нибудь в вашем представлении / помощниках

@functions {
 object getHtmlAttributes (bool ReadOnly, string CssClass) 
 {
     if (ReadOnly) {
         return new { @class = CssClass, @readonly = "readonly" };
     }
     return new { @class = CssClass };
 }
}

Затем используйте:

@Html.TextBox("name", "value", @getHtmlAttributes(Model.ReadOnly, "test"))
47
ответ дан BigMike 18 August 2018 в 07:33
поделиться
  • 1
    Хороший ответ. Я закончил делать ту же логику, за исключением одной строки (тройной, я думаю) условия как часть вызова Html.CheckBox. Ваше решение намного приятнее, спасибо;) – musefan 2 November 2011 в 17:40
  • 2
    Спасибо, для информации, я подозреваю, что лучший способ - определить EditorTemplate для модели, определить внутреннюю функцию и предоставить также некоторую магию jQuery на стороне клиента для выполнения всего. Например, в событии Load содержащего DIV. – BigMike 2 November 2011 в 17:48
  • 3
    mmm .. приведенный выше пример не работает, когда я использую его с .TextBoxFor () (Вместо .TextBox ()). Инициализатор инициализации анонимного типа должен быть простым именем или выражением доступа к членству ... – user1025852 19 February 2014 в 22:51
  • 4
    Как вы делаете то же самое для добавления disable опционально? – Juan Carlos Oropeza 24 April 2018 в 20:28
  • 5
    Просто добавьте параметр bool в функцию и соответственно установите значение @readonly. Я потерял связь с .NET MVC, поэтому не знаю, действительно ли этот ответ применяется с последней версией (я надеюсь, что они добавили лучший способ сделать это). – BigMike 26 April 2018 в 07:02
@Html.TextBoxFor(m => m.FieldName, Html.FixBoolAttributes(new {
    @class = "myClass",
    @readonly = myFlag  
}))


public static class BooleanAttributeFix
{
    /// <summary>
    /// Normalises HTML boolean attributes so that readonly=true becomes readonly="readonly" and
    /// readonly=false removes the attribute completely.
    /// </summary>
    /// <param name="htmlHelper"></param>
    /// <param name="htmlAttributes"></param>
    /// <returns></returns>
    public static RouteValueDictionary FixBoolAttributes(this HtmlHelper htmlHelper, object htmlAttributes)
    {
        var attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

        foreach(var attrName in new[] { "disabled", "readonly" })
        {
            object value;
            if(attrs.TryGetValue(attrName, out value))
            {
                if(isTruthy(value))
                {
                    // Change from readonly="true" to readonly="readonly"
                    attrs[attrName] = attrName; 
                }
                else
                {
                    // Remove attribute entirely
                    attrs.Remove(attrName); 
                }
            }
        }
        return attrs;
    }

    /// <summary>
    /// Apply similar loose rules like javascript does for whether a value is true or not.
    /// e.g. 1 = true, non-empty string = true and so on.
    /// </summary>
    /// <param name="val"></param>
    /// <returns></returns>
    private static bool isTruthy(object val)
    {   
        if(val == null)
            return false;

        if(val is string)
        {
            return !String.IsNullOrEmpty((string)val);
        }

        Type t = val.GetType();

        if(t.IsValueType && Nullable.GetUnderlyingType(t) == null)
        {
            // If a non-nullable value type such as int we want to check for the
            // default value e.g. 0.
            object defaultValue = Activator.CreateInstance(t);

            // Use .Equals to compare the values rather than == as we want to compare
            // the values rather than the boxing objects.
            // See http://stackoverflow.com/questions/6205029/comparing-boxed-value-types
            return !val.Equals(defaultValue);
        }

        return true;
    }
}
1
ответ дан Alan Singfield 18 August 2018 в 07:33
поделиться

Вот мой ответ по этому аналогичному вопросу: https://stackoverflow.com/a/13922813/495000


Создал следующий Помощник - он берет boolean и анонимный объект. Если значение отключено, оно добавляет отключенный атрибут анонимному объекту (который фактически является словарем) со значением «отключено», в противном случае он вообще не добавляет свойство.

public static RouteValueDictionary ConditionalDisable(
   bool disabled, 
   object htmlAttributes = null)
{
   var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

   if (disabled)
      dictionary.Add("disabled", "disabled");

   return dictionary;
}

пример этого в действии:

@Html.TextBoxFor(m => m.SomeProperty,    
   HtmlHelpers.ConditionalDisable(true, new { @class = "someClass"))

. Огромное преимущество для этого подхода для меня заключалось в том, что он работает практически со всеми MVC HtmlHelpers, поскольку все они имеют Overloads, которые принимают RouteValueDictionary вместо анонимного объекта.

Предостережения: HtmlHelper.AnonymousObjectToHtmlAttributes() использует некоторую работу ниндзя причудливого кода, чтобы все было сделано. Я не совсем уверен, насколько он эффективен ... но этого было достаточно для того, для чего я его использую. Ваш пробег может отличаться.

Мне не особенно нравится его название, но я не мог придумать ничего лучшего. Переименование очень просто.

Я также не люблю синтаксис использования, но опять-таки я не мог придумать ничего лучшего. Это не должно быть трудно изменить. Метод расширения на объекте - это одна идея ... в итоге вы получите new { @class = "someClass" }.ConditionalDisable(true), но если вам нужен только атрибут disable и у вас нет ничего лишнего, чтобы добавить вас в нечто вроде грубого, как new {}.ConditionalDisable(true);, а вы также заканчивается методом расширения, который отображается для всех object ... что, вероятно, нежелательно.

28
ответ дан Community 18 August 2018 в 07:33
поделиться
  • 1
    умная. элегантный. – Dave Alperovich 14 September 2013 в 18:35
  • 2
    (добро пожаловать до 300) – Dave Alperovich 14 September 2013 в 18:36
  • 3
    Самое элегантное решение. Это лучшее, что я нашел. Раньше я рассматривал метод расширения, но он был бы слишком общим. – Anon343224user 23 April 2014 в 14:42
  • 4
    Это отличное решение, но я не могу заставить его работать с Html.ActionLink – Ciaran Gallagher 27 March 2018 в 09:12

Выполнение добавления отключенной клиентской стороны атрибута работает для меня. Обратите внимание, что вы должны проверить, какие поля разрешены для редактирования на стороне сервера, но это верно для того, где атрибут disabled объявлен также декоративно.

В этом примере я отключил все элементы формы, используя jQuery.

    if (Model.CanEdit)
    {
        <script type="text/javascript">

            $(document).ready(function() {

                $('#editForm *').attr('disabled', true);
            });

        </script>
    }
1
ответ дан gb2d 18 August 2018 в 07:33
поделиться

Что вы думаете о моем простом решении? Он легко работает с обоими возможными типами HtmlAttributes:

  • Dictionary<string, object>
  • Anonymous Object:

Сначала добавьте следующее простой extension class к вашему проекту:

public static class HtmlAttributesExtensions
{
    public static IDictionary<string, object> AddHtmlAttrItem(this object obj, string name, object value, bool condition)
    {
        var items= !condition ? new RouteValueDictionary(obj) : new RouteValueDictionary(obj) {{name, value}};
        return UnderlineToDashInDictionaryKeys(items);
    }
    public static IDictionary<string, object> AddHtmlAttrItem(this IDictionary<string, object> dictSource, string name, object value, bool condition)
    {
        if (!condition)
            return dictSource;

        dictSource.Add(name, value);
        return UnderlineToDashInDictionaryKeys(dictSource);
    }
    private static IDictionary<string, object> UnderlineToDashInDictionaryKeys(IDictionary<string,object> items)
    {
        var newItems = new RouteValueDictionary();
        foreach (var item in items)
        {
            newItems.Add(item.Key.Replace("_", "-"), item.Value);
        }
        return newItems;
    }
}

Теперь в режиме просмотра:

Пример1 (HtmlAttributes type as Anonymous Object)

@{
  var hasDisabled=true; 
}

@Html.CheckBox("CheckBox1"
              , true
              , new { @class = "Class1"}
               .AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.

Пример 2 (HtmlAttributes type as Dictionary<string, object>)

@Html.CheckBox("CheckBox1"
              , true
              , new Dictionary<string, object> { { "class", "Class1" }
               .AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.

Теперь просто измените значение hasDisabled к true или false!


Example3 (Несколько условных свойств)

@{
  var hasDisabled=true;
  var hasMax=false ;
  var hasMin=true ;
}

@Html.CheckBox("CheckBox1"
              , true
              , new { @class = "Class1"}
               .AddHtmlAttrItem("disabled", "disabled", hasDisabled)
               .AddHtmlAttrItem("data-max", "100", hasMax)
               .AddHtmlAttrItem("data-min", "50", hasMin))
.
1
ответ дан Rami A. 18 August 2018 в 07:33
поделиться
  • 1
    Это здорово, спасибо! Один комментарий: я рекомендую использовать HtmlHelper.AnonymousObjectToHtmlAttributes вместо UnderlineToDashInDictionaryKeys, потому что он уже встроен. ;) – Rami A. 23 June 2018 в 01:09

Если вам нужен более краткий синтаксис, не требующий вспомогательной функции, вы можете использовать трехмерный оператор при определении словаря, используемого для html-атрибутов @ HTML.Checkbox helper ...

@Html.CheckBox("CheckBox1", true, Model.ReadOnly 
       ? new { @class = "Class1", @disabled = Model.ReadOnly } 
       : null)

В этом случае Model.ReadOnly является false, null передается как словарь атрибутов html.

9
ответ дан SteveC 18 August 2018 в 07:33
поделиться
  • 1
    Это может быть довольно многословным, если вы устанавливаете другие атрибуты. – ScottE 9 April 2014 в 19:21
  • 2
    @ScottE не могли бы вы просто настроить свойство на вашем представлении [model], которое делает все тяжелые вычисления для вас? Затем в cshtml это так же просто, как в примере выше. – ganders 25 February 2017 в 06:46
  • 3
    Это не работает, если вы все еще хотите установить свойство @class в ложном состоянии. – Jaxidian 13 September 2017 в 03:13
Другие вопросы по тегам:

Похожие вопросы: