카테고리 보관물: 프로그래밍

jquery로 체크박스와 라디오 제어(자주사용하는 유형 정리)

들어가는 말

jquery로 체크박스와 라디오 제어 관련하여 유형이 정해진  작업을 해야하는 경우가 많습니다. 유형별로 자주 사용하게 되는 작업을 정리해 보도록 하겠습니다.

체크박스

  1. 특정한 이름을 가진 체크박스 모두를 선택하거나 선택해제해야 하는 경우
    자료가 출력된 상단 부분에 체크박스가 있어서 체크되면 아래의 체크박스가 모두 선택되고 해제하면 모두 해제되는 경우의 처리입니다. 한 화면에서 체크박스가 나타나는 영역이 여러개 있을 때 체크박스의 이름을 영역별로 다르게 하여 전체선택/해제가 각각 동작할 수 있도록 작업할 수 있습니다.

    <table class="table table-bordered table-hover displayCategoryTable">
     <thead>
     <tr>
     <th class="text-center"><input type="checkbox" id="checkbox_master" onclick="toggleCheckbox('checkbox_master', 'display_category')" /></th>
     <th>분류</th>
     </tr>
     </thead>
     <tbody id="list">
     <tr>
     <td class="checkboxColumn text-center"><input type="checkbox" name="display_category" value="1/></td>
     <td>1</td>
     </tr>
     <tr>
     <td class="checkboxColumn text-center"><input type="checkbox" name="display_category" value="2/></td>
     <td>1</td>
     </tr>
     </tbody>
    </table>
    
    function toggleCheckbox(checkMasterId, fieldName) {
     if ($('#' + checkMasterId).prop('checked') == true) {
     $('input:checkbox[name=' + fieldName + ']').each(function () { $(this).prop('checked', true) });
     }
     else {
     $('input:checkbox[name=' + fieldName + ']').each(function () { $(this).prop('checked', false) });
     }
    }
    
  2. 체크된 값을 가져와야 하는 경우
    사용자에 의하여 선택된 값을 하나의 문자열로 만들고 그것을 서버에 전달하여 처리할 때 많이 사용하게 되는 유형입니다. 다음의 예는 선택된 체크박스의 값을 컴마로 구분하여 하나의 문자열로 합치는 방법입니다. join(“,”) 부분의 컴마를 다른 구분자로 변경하여도 됩니다.

    var selectDisplayCategory = $('input[name="display_category"]:checked').map(function () {
    	return this.value;
    }).get().join(",");
    

라디오

  1. 임의로 선택해야 하는 경우
    DB에서 값을 가져와서 그에 따라 어떤 것이 선택되었는지 설정을 해 주어야 하는 경우가 많습니다. 그런 경우에 사용되는 방법입니다.

    <input type="radio" name="ownLinkShow" id="ownLinkShowYes" value="1" /> <label for="ownLinkShowYes">예</label>&nbsp;
    <input type="radio" name="ownLinkShow" id="ownLinkShowNo" value="0" checked="checked" /> <label for="ownLinkShowNo">아니오</label>
    
    <script>
    if (detail[0].ownLinkShow == 0)
    {
     $('#ownLinkShowNo').prop('checked', true);
    }
    else
    {
     $('#ownLinkShowYes').prop('checked', true);
    }
    </script>
    
  2. 선택되지 않은 상태로 바꾸어야 하는 경우
    때때로 사용자가 선택 후 초기상태로 변경해야 하는 경우가 있습니다. 그럴 때 아예 선택하지 않은 상태로 전환하는 방법입니다. 라디오 필드에 class를 지정한 후(아래의 보기에서는 ownLinkGroup) 스크립트 부분에서 checked 속성을 false 로 전환하는 방법입니다.

    <input type="radio" name="ownLinkShow" id="ownLinkShowYes" value="1" class="ownLinkGroup" /> <label for="ownLinkShowYes">예</label>&nbsp;
    <input type="radio" name="ownLinkShow" id="ownLinkShowNo" value="0" class="ownLinkGroup" /> <label for="ownLinkShowNo">아니오</label>
    
    <button type="button" onclick="unselect();">초기화</button>
    <script>
    function unselect()
    {
     $('.ownLinkGroup').prop('checked', false);
    }
    </script>
    

     

이상으로 간략하게 jquery로 체크박스와 라디오 제어 하는 몇 가지 자주 사용하는 유형에 대하여 살펴보았습니다.

BackgroundWorker 클래스 사용

WinForm을 이용한 프로그램을 작업할 때 종종 오랜시간 반복적인 작업을 처리하여야 하는 경우가 있습니다. 진행되는 상태를 표시해 주고 일시 중지 혹은 작업이 마무리 되었을 때 사용자에게 알림 메시지를 보여주는 형식으로 작업을 하게 됩니다. 여기서 문제가 반복문안에 UI 를 갱신하는 코드를 넣으면 의도한 대로 동작하지 않게 됩니다. 특히 버튼 이벤트는 반응을 하지 않게되고 작업이 끝난 후 버튼이 눌려지는 듯한 현상을 보이게 됩니다. 이럴 때 BackgroundWorker 클래스 를 사용하여 작업하면 의도한 대로 버튼 이벤트가 발생되도록 할 수 있습니다. 이 클래스는 .Net 2.0 부터 추가되었고 자세한 설명은 다음의 링크에서 확인할 수 있습니다.

MSDN 설명 보기

사용자가 설정한 키워드 목록을 OpenAPI 를 이용하여 검색 결과를 가져오는 간단한 예제를 구성해 보겠습니다. 먼저 Form 을 아래와 같이 디자인 합니다. 처리되는 키워드와 진행 상황을 표시해 줄 Text, Label 컨트롤을 추가합니다.

폼 디자인

폼 디자인

BackgroundWorker 클래스 변수를 선언합니다. 그리고 폼이 초기화될 때 BackgroundWorker 클래스가 동작할 사항을 정의해 줍니다.

private BackgroundWorker bwWrite;

bwWrite = new BackgroundWorker();
bwWrite.WorkerSupportsCancellation = true;
bwWrite.DoWork += new DoWorkEventHandler(doWrite);
bwWrite.RunWorkerCompleted += new RunWorkerCompletedEventHandler(write_RunWorkerCompleted);

5번째 행에 doWrite 라는 메소드를 실행하도록 설정하고 6번째 행에 작업이 종료되면 write_RunWorkerCompleted 메소드가 실행되도록 설정하였습니다. doWrite 메소드에서는 시간이 오래 걸리는 루프 등의 루틴을 추가하면 됩니다. OpenAPI 를 통하여 검색결과를 가져오는 부분이 될 것입니다. write_RunWorkerCompleted 메소드에서는 doWrite 메소드의 호출이 완료되었을 때 원하는 동작을 하도록 작업하면 됩니다.

각 버튼 이벤트를 다음과 같이 정의합니다.

private void btnStart_Click(object sender, EventArgs e)
{
	btnStart.Enabled = false;
	btnStop.Enabled = true;

	bwWrite.RunWorkerAsync();
}

private void btnStop_Click(object sender, EventArgs e)
{
	bwWrite.CancelAsync();
	btnStart.Enabled = true;
	btnStop.Enabled = false;
}

6번째 행에서 이전에 정의한 대로 doWrite 메소드를 실행하도록 RunWorkerAsync 메소드를 호출합니다. 중지 버튼을 클릭하면 CancelAsync 메소드를 호출하여 취소되도록 합니다. 여기서 유의해야 할 것은 CancelAsync 메소드가 호출되었다고 해서 바로 종료되는 것이 아니라는 것 입니다. doWrite메소드 내에서 다음과 같은 방식으로  취소여부를 판단하여 종료하여야 합니다.

private void doWrite(object sender, DoWorkEventArgs e)
{
.
.
.
	for (var i = keywordIndex; i &lt; keyword.Length; i++)
	{
		if (bwWrite.CancellationPending == true)
		{
			e.Cancel = true;
			return;
		}
		.
		.
		.
	}
}

작업진행 사항을 Text, Label의 속성을 변경시키는 방법으로 doWrite 메소드내에 코드를 작성하면 “자신이 만들어진 스레드가 아닌 스레드에서 액세스되었습니다” 라는 오류가 발생합니다. 메시지 내용대로 별도의 스레드에서 폼에 생성된 컨트롤에 접근하려고 하여 발생되는 오류 입니다. 이럴때는 다음과 같이 Invoke 메소드를 호출하는 방식으로 처리합니다. 이렇게 하면 오류가 발생하지 않고 의도한 대로 진행상황을 Label 컨트롤에 나타낼 수 있습니다.

delegate void delegateSetProgressLabel(string text);

private void setProgressLabel(string text)
{
	if (lblProgressStatus.InvokeRequired)
	{
		var delegateCall = new delegateSetProgressLabel(setProgressLabel);

		this.Invoke(delegateCall, text);
	}
	else
	{
		lblProgressStatus.Text = text;
	}
}

간략하게  BackgroundWorker 클래스 사용 방법에 대하여 알아보았습니다.