kintone의 사용자 선택 필드에 중복 금지를 적용했습니다.

소개



kintone의 필드에서 중복 금지 설정을 할 수 있는 것은 「문자열 1행」과 「수치」만!
즉, 다른 필드에서 중복 체크를 하고 싶은 경우는 커스터마이즈를 할 필요가 있습니다.

그래서,
이번에는 「사용자 선택 필드」에 중복 금지 처리를 붙여 보았습니다

데모



같은 사용자가 여러 레코드를 등록하면 오류가 발생합니다.
※ 레코드 편집에도 대응


↓ 복수인에게도 대응시키고 있습니다!


이용 장면



유저 선택 필드를 중복 금지로 하고 싶을 때는 무엇일까~
여러 가지 유스 케이스를 생각했지만 곧 생각할 곳이라고
  • 직원 명부
  • 1인 1일 1레코드의 일보
  • 설문/추첨 앱

  • 정도가 한계였습니다. .
    음, 유스 케이스는 신경 쓰지 않는다! 만들고 싶어서 만든다!

    메커니즘



    kintone REST API를 사용하여 자신의 앱에서
    '사용자 선택 필드에 자신이 등록된 레코드가 있는지'를 확인합니다.

    위의 조건을 쿼리에 쓰고 GET을했을 때의 응답에
  • 레코드 없음 → 레코드 저장 가능
  • 레코드 있음 → 오류 표시

  • 라는 움직임으로하고 있습니다. 복수인 대응시킨 영향으로 쿼리 부분이 약간 복잡하게 되었습니다(;・∀・)

    (18/10/12 추가)
    코멘트를 받고, 간단하게 기술할 수 있었습니다! ! 감사합니다!

    코드



    GitHub 에 있습니다.
    (function() {
      'use strict';
    
      kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) {
        const userField = event.record['userselect'].value;
        const recordId = kintone.app.record.getId();
        let query = '';
    
        // ユーザー選択フィールドが空のときは処理をやめる
        if (!userField.length) {
          return;
        }
    
        // レコード編集時 (=レコードがすでにある時) はクエリ文追加
        if (recordId) {
          query = '$id != ' + recordId + ' and ';
        }
    
        // ユーザー選択フィールド用クエリ(複数人対応)
        query += 'userselect in ("' + userField.join('", "') + '")';
    
        const param = {
          'app': kintone.app.getId(),
          'query': query,
        };
    
        // PromiseでREST(GET)を実行
        return kintone.api(kintone.api.url('/k/v1/records'), 'GET', param)
          .then(function(resp) {
            if (resp.records.length) {
              let errMessage = resp.records[0]['userselect'].value[0].name + 'が重複しています!';
              event.record['userselect'].error = errMessage;
            }
            return event;
          })
          .catch(function() {
            // error
            event.error = '予期せぬエラーが発生しました!';
            return event;
          });
      });
    
      // userselectフィールドが変更されたときはエラー表示を消す
      kintone.events.on(['app.record.create.change.userselect', 'app.record.edit.change.userselect'], function(event) {
        event.record['userselect'].error = null;
        return event;
      });
    }());
    
    

    또, REST API를 이용하면 비동기 처리가 되므로, Promise를 사용해 동기 처리로 하고 있습니다.

    해설



    레코드 편집 결정



    레코드 추가시와 편집시에 중복의 판정이 바뀌어 오기 때문에(편집의 경우는 반드시 1개 응답이 있다), 「편집시」라고 하는 판정이 필요하게 됩니다.

    추가시와 편집시의 차이점은,
    "레코드가 생성되었는지 여부 → 레코드 ID가 있는지 여부"
    로 판단할 수 있습니다!

    그러므로
    레코드 ID가 있는 경우 쿼리에 '그 레코드 ID 제외' 부분을 추가하는 것입니다.
        const recordId = kintone.app.record.getId();
        // ~~~
        // レコード編集時 (=レコードがすでにある時) はクエリ文追加
        if (recordId) {
          query = '$id != ' + recordId + ' and ';
        }
    

    복수인 대응



    여러 사람을 지원하는 경우 사용자 선택 필드(배열)를 반복합니다.
    마지막으로 쉼표가 남아 버리므로 삭제하고 닫는 괄호 ")"를 추가합니다.

    (18/10/12 추가)
    작동 방식은 동일하지만 join 메소드를 사용하면 루프를 간단하게 작성할 수 있습니다.
    query += 'userselect in ("' + userField.join('", "') + '")';
    

    덧붙여서, 루프 시켜서 빡빡하고 있었던 것이 이쪽.
        // ユーザー選択フィールド用クエリ(複数人対応)
        query += 'userselect in (';
    
        for (let i = 0; i <= (userField.length - 1); i++) {
          query += '"' + userField[i].code + '",';
        }
        // 最後のカンマを削除して閉じる
        query = query.slice(0, -1);
        query += ')';
    

    오류 표시



    아래와 같이 작성하면 kintone의 에러 표시를 이용할 수 있습니다!

    필드 하단에 표시하려는 경우
    event.record['フィールドコード'].error = 'エラー';
    

    화면 상단에 표시하고 싶은 경우
    event.error = 'エラー';
    

    ※ 어느쪽이나 return event등을 해 이벤트를 돌려줄 필요가 있습니다!

    결론



    이러한 제한계의 커스터마이즈는 설명 코스트가 내려가므로 꽤 추천입니다!
    (한 명 1레코드!

    kintone의 표준 기능에 없어도, 커스터마이즈를 하면 할 수 있는 것은 산만큼 있습니다!
    우선은 친밀한 고민으로부터 해소해 보는 것은 어떨까요!

    kintone의 커스터마이즈로 곤란한 것이 있으면 cybozu developer network 커뮤니티에서 질문해 보면 좋겠어~!

    그럼! ≧(+・` ཀ・´)≦

    좋은 웹페이지 즐겨찾기