ASP.NET MVC에서 Checkbox의 매핑과 바인딩 그리고 getUrlVars()와 knockoutjs에서의 사용법

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (4/12/2012 9:39:18 AM) Viewing : 8827

제목이 좀 길군요..^^;

ASP.NET에서 check박스와 radio는 조금 골칫거리입니다.

radio는 언젠가 기회가 있겠지요..^^;

오늘은 checkbox의 사용법에 대해서 알아 보고자 합니다.

ASP.NET MVC에서는 CheckboxList 같은게 존재하지 않습니다. 뭐 필요하다면 만들수도 있겠지요..^^;

어쨋든 Html에서 사용법은 아래와 같습니다.

<% List<CommonCode> marketTypeCodes = CachedData.GetCodeListInCodeGroup("시장구분"); %>
<% foreach (CommonCode item in marketTypeCodes)
    { %>
<label>
    <input type="checkbox" name='MarketTypeCode' value='<%= item.CodeId %>' data-bind="checked:MarketTypeCode" />
    <%= item.Code%>
</label>
<% } %>

위 코드를 보시면 foreach 문을 사용해서 checkbox를 렌더하는 걸 보실 수 있습니다.

그러면 html에는 MarketTypeCode 라는 name을 가진 checkbox가 여러개가 렌더 될것입니다.

웹 사용자가 이 체크 박스를 Check 하여 서밋을 하게 되면

Browser는 파라메터를 MarketTypeCode=1&MarketTypeCode=2&MarketTypeCode=3 과 같은 형식으로 보내게 됩니다.

이 데이터를 Controller에서 받기 위해서는 Controller의 매개변수를 String[] marketTypeCode 로 선언해야 합니다.

즉 MVC 매핑 엔진은 같은 이름의 key 값을 배열로 만들어 Controller에 전달 하게 됩니다.

서버에서 배열로 값을 받았으니 나름 작업을 하면 될테이고..

이것이 검색과 같은 페이지라면 검색 조건을 유지 시키기 위해 이 값으로 다시 html 을 바인딩 해야 하겠지요?

View 에서 Model 을 지정하MarketTypeCode=1였다면

this.Html.xxxFor 라는 메서드로 정의된 element 들은 자동적으로 바인딩이 됩니다. (MVC 멋지죠..^^;)

그런데 이게 Checkbox는 예외입니다.

Checkbox가 View에 여러 개가 존재할 경우 앞서 말했던 바와 같이 이 개체의 형식은 Array 라서 this.Html.xxxFor 메서드로 표현 할 수가 없습니다.

그래서 jquery 를 이용해서 바인딩을 하곤 하지요..

querystring으로 View를 바인딩 하기위해서는 querystring을 분석하여 key,value로 값을 가져올 수 있어야 하는데 이 도움을 주는 것이 getUrlVars() 라는 플러그인입니다.

http://draeton.github.com/jquery/javascript/library/2011/05/08/jquery-geturlvars.html

위 링크에서 받으 실 수 있습니다..^^;

$.getUrlVar('MarketTypeCode') 혹은 $.getUrlVars()['MarketTypeCode'] 와 같이 사용하여 값을 받을 수 있는 거죠..

그러나 앞서 말한바와 같이 checkbox는 querystring으로 여러개의 같은 key값이 존재하는 형태로 넘어 옵니다.

MarketTypeCode=1&MarketTypeCode=2&MarketTypeCode=3

위 처럼 말이죠. 이 상태에서 $.getUrlVar('MarketTypeCode') 메서드를 호출하면 3 이라는 값만 떨어 집니다.

위 플러그인의 코드를 보시면 알겠지만 그냥 대입해버리기 때문에 마지막꺼만 전달됩니다.

그래서 조금 수정을 해보았습니다.

    getUrlVars: function () {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            var hasKey = false;
            for (var j = 0; j < vars.length; j++) {
                if (vars[j] == hash[0]) {
                    hasKey = true;
                    break;
                }
            }
            if (!hasKey) {
                vars.push(hash[0]);
                vars[hash[0]] = hash[1];
            }
            else {
                var arr = [];
                if (typeof (vars[hash[0]]) == 'string') {
                    arr.push(vars[hash[0]]);
                }
                else {
                    for (var k = 0; k < vars[hash[0]].length; k++) {
                        arr.push(vars[hash[0]][k]);
                    }
                }
                vars[hash[0]] = [];
                for (var k = 0; k < arr.length; k++) {
                    vars[hash[0]].push(arr[k]);
                }
                var hasData = false;
                for (var k = 0; k < vars[hash[0]].length; k++) {
                    if (vars[hash[0]][k] == hash[1]) {
                        hasData = true;
                        break;
                    }
                }
                if (!hasData) {
                    vars[hash[0]].push(hash[1]);
                }
            }
        }
        return vars;
    }

위 코드는 주저리 주저리 길지만..요지는 간단합니다.

키가 존재하지 않으면 기존처럼 , 만약 키가 존재한다면 배열을 만들어서 리턴해주는 형식... 입니다.

이 수정된 플러그인으로 $.getUrlVar('MarketTypeCode')  를 호출하게 되면 [1,2,3] 으로 값이 리턴됩니다. ^^;

자 이제 이 값을 바인딩 하면 되겠습니다.

순수 jQuery로 해도 되겠고 knockoutjs 를 사용한다면 다음과 같이 하면 되겠네요.

if ($.getUrlVars()['MarketTypeCode']) {
    var arr = $.getUrlVars()['MarketTypeCode'];
    for (var i = 0; i < arr.length; i++) {
        viewModel.MarketTypeCode.push(arr[i]);
    }
}

 참 쉽죠잉~~~

참 쉽죠 


마지막 업데이트 : (4/12/2012 9:39:18 AM)

TAG : MVC jquery knockoutjs 



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기