2021년 목표설정

이미지
기본적으로 작년에 달성하지 못한 것들을 하려고 생각중인데..코로나가 언제까지 이어질지, 한국이나 북해도는 갈 수 있을지..자격증은 응시 가능할지..여러가지가 불확실하다. 2021년은 무엇보다 정신적인 부분과 경제적인 부분에 중점을 두고 조금 더 치열하게 지내보고 싶다. 일본나이로도 30대 마지막 해, 이제 불혹에 접어드는 나이..복잡하지만 심플하게. 육체적목표 : 트라이에슬론 스탠다드 도전하기 정신적 : 자격증2개 도전 + 자체개발 서비스 론칭 가족적 : 가정의 평화를 유지하기 경제적 : 외식과 유흥비를 줄이고 부수입을 늘려서 결과적으로 저축하기 사회적 : 목표세미나를 포함해서 민단과 개인인맥의 활성화와 교류를 촉진하기

cakephp3 에서 다중 체크박스 다루는 방법 + 체크박스에서 값 여러개 넘기는 편법

단순히 테이블 그리고 체크박스 넣고 끝나면 편할테지만 값을 넘기고 받는 게 없으면 아무런 동작을 안 하므로 값을 전송해야 한다.
문제는 여러가지 있었는데 뭐 대충 이런거다.
1. 체크박스가 여러개 있는 경우 어찌 컨트롤 할 것인가? 예를 들어서 데이터 받는 것과 데이터베이스에 있는 값 불러서 체크박스를 체크하고 싶은 경우 등등.. -> 클라이언트사이드 언어로 하면 좋은데..모르므로 패스!! 
2. 체크박스 하나에 값을 두 개 이상 넘기려면 어찌 해야하나? 예를 들어서 체크박스 하나 눌렀을 때 요일과 교시를 같이 넘기고 싶은 경우..체크박스는 기본 체크 되었나 안되었나 값을 가지므로 value를 사용해야 하는데 그게 말은 쉽더라 ㅋ
 
Cakephp에서는 FormHelper라는 것이 있어서 쉽게 폼 요소를 만들 수 있다. 또한 값을 넘길 때 텍스트로 값을 붙인 후 서버에서 쪼개는 방법으로 여러가지 값을 한 번에 넘길 수 있다. 예를 들어서 월요일 3교시라고 하면, M3 혹은 13 등으로 넘긴 후, substr() 등등으로 값을 쪼개서 쓰는 것이다. 나는 요일과 교시를 숫자로 표현해서 한 글자씩 쪼개기로 했다. 

여기서는 선생님이 수업불가능한 요일과 교시를 체크박스로 받는다고 가정하고 적어보겠다.
우선 컨트롤러에서 데이터베이스를 읽는 등등 해서 필요한 정보를 배열로 가공해서 뷰로 넘긴다.
> teacherController.php
// controller에서 체크박스로 표시할 배열을 생성해서view로 넘긴다.        
 $options = [];
        foreach($weeks as $weekIdx=>$week)
        {
          foreach($periods as $periodIdx=>$period)
          {
            $options[$week][$period] = [
              "text" =>  "{$week}曜日{$period}時限",
              "value" => $weekIdx . $periodIdx, // 요일값과 교시값을 문자욜로 붙인다.
            ];
          }
        }
        unset($week);
        unset($period);

// 디비에 저장된 값을 불러내서 체크박스에 체크할 값을 넣은 배열을 생성해서view로 넘긴다.
 $teacher_assigns = $this->TeacherAssigns->find()->toArray(); // 배열에서 값을 가져온다.
 $values = [];
        foreach($teacher_assigns as $teacher_assign)
        {
            $val = $teacher_assign->week_idx . $teacher_assign->period_idx; // 요일값과 교시값을 문자열로 붙인다.
            $values[] = (int)$val;
        }
        unset($teacher_assign);

        $this->set(compact('teacher','users','departments','weeks','periods','options'));
        $this->set('_serialize', ['teacher','users','departments','weeks','periods','options']);

// 사용할 때는 이렇게
if(isset($this->request->data['assigns_idx'])) // 폼 값을 받아와서
{
 $assigns_array = $this->request->data['assigns_idx'];
   if(!is_null($assigns_array))
    {
     foreach((array)$assigns_array as $assign)
      {
// 폼에서 넘어온 value값을 요일과 교시로 다시 나눈다..
        $week_idx = substr($assign,0 ,1);
        $period_idx = substr($assign,1 ,1);
// 기타 코드 생략..내 경우에는 여기서 데이터베이스에 insert 했다.
       }
    }
}
뷰에서는 그 배열을 받아서 다음과 같이 FormHelper에 파라메터 형식으로 options (배열 생성시 키와 값을 정의) value (값이 선택된 경우 폼을 활성화) 에 할당해서 사용하면 끝난다.
> teacher/edit.ctp
<div class="form-group">
 <div class="col-lg-12">
  <?= $this->Form->label('講義不可の曜日・時限'); ?>
  <?= $this->Form->input('assigns_idx',[
              'options' => $options,
              'type'=>'select',
              'multiple' => 'checkbox',
              'label' => false,
              'hiddenField' => false,
              'value' => $values,
              ]);
     ?>
  </div>
</div>

이러면 체크박스 여러개를 단 한 줄로(보기 편하게 개행을 했지만..) 만들고 값도 뿌려줄 수 있다.
문제는...화면에 이렇게 표시가 된다.

너무 길다...디자인을 수정하고 싶었는데 cakephp에서 수정이 꽤 쉽지 않은 듯 하다...FormHelper의 템플렛을 수정해야 한다고 하는데  예시도 거의 없고 기본적으로 DIV 태그로 줄을 죽죽 바꾸어 나가게끔 되어 있어서...이래저래 고민을 하다가 결국 FormHelper에서 Options와 Multiple checkbox를 포기하고 체크박스를 하나하나 foreach로 생성하기로 했다.
이 경우, 컨트롤러에서 options 배열을 만들 필요 없이, 반복문으로 요일과 교시 정보를 돌려서 테이블을 만든 후, 요일과 교실값을 다시 문자열로 붙여서 value값으로 지정하면 컨트롤러 수정 거의 없이 같은 결과를 얻을 수 있다.

> teacher/edit.ctp
<?php foreach((array)$periods as $periodkey => $period): ?>
 <tr>
  <td>
   <?= $period ?>時限
  </td>
 <?php foreach((array)$weeks as $weekkey => $week): ?>
  <td>
   <?php
    $option = $weekkey . $periodkey;
    $flag = false;

    foreach($values as $value)
    {
     if($option == $value)
     {
      $flag = true;
     }
    }

    echo $this->Form->checkbox('assigns_idx[]',[
     'id' => 'assign-'.$option, 
     'value' => $option,
     'label' => false,
     'hiddenField' => false,
     'multiple' => true,
     'checked' => $flag,
    ]);
    unset($value);
   ?>
  </td>
 <?php endforeach; ?>
</tr>
<?php endforeach; ?>

이렇게 하면 요런 테이블이 되더라. 아무래도 이쪽이 보기도 쉽고 익숙해서 좋은 듯.

댓글

이 블로그의 인기 게시물

[메모] PostgreSQL에서 Insert 하는 경우 자동채번 PK가 중복에러 나는 경우

[C# & LINQ] 랜덤으로 데이터를 한 개 추출하는 방법

[react-native] uuid 생성이 에러가 날 때 대처법