[ASP.NET MVC] Form Element의 Disabled, Readonly 처리

2013. 5. 18. 16:43WEB

ASP.NET Web.Form과는 다르게 ASP.NET MVC는 Disabled, ReadOnly처리를 직접 처리해주어야 합니다. 그 방법은 다음과 같이 간단히 수행할 수 있습니다.

<!-- HTML Helper 이용 -->
@Html.TextBoxFor(t => t.UserName, new { @readonly = "readonly", disabled = "disabled" } }

<!--
    [상태에 따라 ReadOnly를 설정하고 해제할 경우]
    Model에 IsReadOnly 속성이 있고 이 값에 따라 ReadOnly를 설정해주거나 해제할 경우
-->
@Html.TextBoxFor(t => t.UserName, new Dictionary<string, object> { { Model.IsReadOnly ? "readonly" : "data-readonly" , "" }, { "disabled", "disabled" } }

<!-- HTML에 지정 -->
<input type="text" value="@Model.UserName" disabled readonly />

ReadOnly와 Disabled를 통해 사용자가 수정을 못하게 막을 수 있지만, Readonly와 달리 Disabled된 컨트롤의 경우에는 Form Submit 시 서버로 정보를 전송하지 않습니다.

<!-- readonly 값은 서버로 전송됩니다 -->
<input name="ServiceName" value="이지비즈 법인설립" readonly />

<!-- disabled 된 값은 Browser가 서버로 정보를 전송하지 않습니다. -->
<input name="CompanyName" value="NS" disabled />

따라서 사용자의 수정을 막으면서, 동시에 서버에 전송되어야 하는 경우에는 readonly를 설정하시면 됩니다. 하지만 Select, Radio, Checkbox 등의 컨트롤의 경우에는 readonly가 적용되지 않는 문제가 있습니다.

[readonly가 적용된 특정 Form Element의 모습 – Readonly는 select, radio, checkbox 컨트롤에 영향을 미치지 않습니다]

이 이유에 관해서는 faq.com에 잘 설명이 되어있습니다. 간단히 요약하자면 Readonly는 사용자가 컨트롤의 Value값만 변경할 수 없게 만드는 속성이며, Checkbox, Radio, Select 등의 컨트롤은 Value가 아니라 checked, selected 등의 속성을 조작하는 것이기에 Readonly는 이러한 컨트롤에 아무런 영향을 미치지 않는다고 합니다.

<!-- Checkbox 컨트롤은 사용자가 Checked 속성값을 바꾸는 것이지 Value를 바꾸는 것이 아니다. 따라서 Value의 변경을 막는 Readonly는 CHeckbox에 아무 영향을 미치지 않는다. -->
<input type='checkbox' value='apple' checked> Apple
<input type='checkbox' value='pineapple' checked> Pineapple

따라서 Checkbox, Radio, Select Form Element를 사용불가 처리하는 방법은 Dsiabled가 유일하다고 볼 수 있습니다. 하지만 이 경우 해당 컨트롤의 값조차 서버로 전송되지 않는 문제가 있습니다. 이에 대해 여러 해결방법이 있지만, 다음과 같이 2가지 해결방법이 존재합니다.

  1. Disabled를 적용시켜뒀다가, Submit Event 발생 시 Disabled를 해제하는 방법
    <!— OnSubmit Evnet 발생 시 disabled를 해제한다 -->
    <form onSubmit=”document.getElementsByTagName(‘select’).disabled = false;”>
        <select name='instrument' disabled='disabled'>
            <option value='piano'>피아노</option>
            <option value='guitar'>기타</option>
        </select>
        <button type='submit'>제출</button>
    </form>
  2. Disabled된 Select를 대신해 값이 전송 될 Hidden Form Element를 두는 방법:
    <!-- 처음부터 다음과 같이 Select, Hiddel Element를 나란히 입력해둔다 -->
    <select name='instrument' disabled='disabled'>
        <option value='piano'>피아노</option>
        <option value='guitar'>기타</option>
    </select>
    <input name='instrument' type='hidden' value='piano' />
    
    <!-- Select Element는 원할때마다 마음대로 disabled 처리 또는 해제를 해도 
         Hidden Field에 의해 서버로 값이 전송이 되게 됨을 보장할 수 있다.
         Select Element가 Disabled 되지 않은 상태라 할 지라도, ASP.NET
         MVC ModelBinder는 중복된 두 Name의 값 중 첫번째 값을 Binding에
         사용하므로 Hidden Field값은 자동으로 무시되게 된다. -->

    ASP.NET MVC의 ModelBinder는 Name이 중복된 값을 수신하면 먼저 수신된 Name을 Binding합니다. 따라서 위와 같이 동일한 Name를 가진 Hidden Form Element를 넣어도 ASP.NET MVC ModelBinder는 Select의 값만 Model에 바인딩하며, Select가 혹여라도 Disabled된다면 HiddelField값이 자동으로 Model에 바인딩됩니다.

위의 방법 외에도 여러 가지 방법이 있을 수도 있으니 괜찮은 방법있으면 서로 공유하였으면 합니다.^^

관련출처

'WEB' 카테고리의 다른 글

[ASP.NET MVC] Partial, RenderPartial, RenderPage  (0) 2013.07.22
[WEB] 403 Forbidden  (0) 2013.05.31
[IE] IE의 호환성보기 설정하기  (1) 2013.03.01
[ASP.NET] 사용자 환경정보 쉽게 얻기  (0) 2013.03.01
[ASP.NET] Global.asax Events  (0) 2012.04.02