1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【kintone】ユーザーが所属する組織を取得する

Last updated at Posted at 2025-08-15

対象がログインユーザーの場合

2025年8月10日のアップデートで追加された kintone.user.getOrganizations() という
APIを利用できるが、以下の仕様に留意が必要。

「別言語での表示名」を設定できる項目の値は、
このAPIを実行するユーザーが設定した言語で返ります。

この仕様のせいで

の二条件を両方とも満たしている状態で kintone.user.getOrganizations()
実行すると、戻り値organization.name にも空文字が返ってしまう。

以下のAPI使用例では、空文字が返った場合は organization.code から
アンダースコア以降を消したものを、画面に表示する組織名とすることで対策している。


フォームで、組織選択の右にスペースを二つ置く。
要素IDは左から space1 space2 とする。

タイトルなし.png

下記のJavaScriptを適用すると、組織選択の右にボタンが設置される。
押下するボタンに応じて、ログインユーザーの所属する組織が組織選択へ入力される。

Animation.gif

(() => {
  'use strict';

  // ログインユーザーの全所属組織と優先する組織を格納する変数
  let orgs = [], primary = null;

  // organizationオブジェクトにnameが無いときは、codeから_以降を消したものを画面に表示する関数
  const formatOrg = org => ({
    code: org.organization.code,
    name: org.organization.name || org.organization.code.replace(/_[A-Za-z0-9]+$/, '')
  });

  // ボタンの背景色と文字色を組織選択の値に応じて変更する関数
  const updateBtnColors = sel => {
    // 優先する組織ボタンと全組織ボタンのDOM要素を取得
    const [pBtn, aBtn] = ['priority-org-button', 'all-org-button']
      .map(id => document.getElementById(id));
    // ボタンが存在しない場合は処理を中止
    if (!pBtn || !aBtn) return;

    // 優先する組織のみ選択されているか判定
    const onlyPrimary = sel.length === 1 && primary &&
      sel[0].code === primary.organization.code;
    // 全所属組織のみが選択されているか判定
    const allSelected = sel.length === orgs.length &&
      orgs.every(org => sel.some(s => s.code === org.organization.code));

    // 上記の条件に合致するボタンを青背景、白文字に変更
    [pBtn, aBtn].forEach((btn, i) => {
      const active = [onlyPrimary, allSelected][i];
      btn.style.backgroundColor = active ? '#3498db' : '';
      btn.style.color = active ? '#fff' : '';
    });
  };

  // スペースにボタンを設置する関数
  const makeBtn = (spaceId, id, label, getVal) => {
    const space = kintone.app.record.getSpaceElement(spaceId);
    // スペースが存在しないか、既にスペースの子要素がある場合は処理を中止
    if (!space || space.hasChildNodes()) return;

    // ボタンを作成してプロパティを設定
    const btn = Object.assign(document.createElement('button'), {
      id,
      type: 'button',
      textContent: label,
      className: 'button',
      style: 'margin:4px'
    });

    // ボタンクリック時の処理
    btn.onclick = () => {
      const record = kintone.app.record.get();
      // 組織選択の値をgetVal引数の戻り値で更新
      record.record.組織選択.value = getVal();
      kintone.app.record.set(record);
      // ボタンの色を現在の組織選択の値に応じて更新
      updateBtnColors(kintone.app.record.get().record.組織選択.value || []);
    };

    // 作成したボタンをスペースに追加
    space.appendChild(btn);
  };

  // 追加画面と編集画面を表示したときの処理
  kintone.events.on(['app.record.create.show', 'app.record.edit.show'],
    async () => {
    // ログインユーザーが所属する全組織を取得
    orgs = await kintone.user.getOrganizations();
    // 取得した組織から優先する組織を検索
    primary = orgs.find(org => org.organization.primary) || null;

    // 要素IDがspace1のスペースに優先する組織ボタンを設置
    makeBtn('space1', 'priority-org-button', '優先する組織',
      () => primary ? [formatOrg(primary)] : []);
    // 要素IDがspace2のスペースに全所属組織ボタンを設置
    makeBtn('space2', 'all-org-button', '全所属組織', () => orgs.map(formatOrg));

    // レンダリング完了の次のフレームでボタンのスタイルを設定
    requestAnimationFrame(() => {
      updateBtnColors(kintone.app.record.get().record.組織選択.value || []);
    });
  });

  // 組織選択の値が変更されたときにボタンのスタイルを更新
  kintone.events.on(['app.record.edit.change.組織選択', 'app.record.create.change.組織選択'],
    event => {
    updateBtnColors(event.record.組織選択.value || []);
  });
})();

対象がログインユーザーとは限らない場合

User API の /v1/user/organizations.json を使う。

User API は非同期処理だが、changeイベントはPromise非対応なので
フィールドの値を変更したタイミングで発火させるには一工夫要る。


ユーザー選択に入力されたユーザーが所属する組織を、組織選択に入れる。

Animation.gif

(() => {
  'use strict';

  kintone.events.on([
    'app.record.create.show',
    'app.record.edit.show',
    'app.record.create.change.ユーザー選択',
    'app.record.edit.change.ユーザー選択',
    'app.record.create.submit',
    'app.record.edit.submit'
  ], (event) => {

    const record = event.record;
    const isSubmitEvent = event.type.includes('.submit');
    const userValue = record.ユーザー選択.value;

    // 組織選択を編集不可にする
    record.組織選択.disabled = true;

    // ユーザー選択に複数人入力したらフィールドにエラーを表示
    if (userValue && userValue.length > 1) {
      record.ユーザー選択.error = '一人しか入力できません';

      // レコード保存時は画面上部にもエラーを表示
      if (isSubmitEvent) {
        event.error = 'ユーザー選択には一人しか入力できません。';
      }
      return event;

    // ユーザー選択に入力されているのが1人以下ならフィールドのエラーをクリア
    } else {
      record.ユーザー選択.error = null;
    }

    let userCode = '';

    // ユーザー選択に値がある場合はユーザーのログイン名を取得
    if (userValue && userValue.length > 0) {
      userCode = userValue[0].code;
    }

    // ユーザー選択に値がない場合は組織選択をクリア
    if (!userCode) {
      setTimeout(() => {
        record.組織選択.value = [];
        kintone.app.record.set({ record });
      }, 0);
      return event;
    }

    // 上記ログイン名と紐づく組織を取得
    kintone.api(kintone.api.url('/v1/user/organizations', true),
      'GET', { code: userCode }
    ).then((resp) => {
      const organizationTitles = resp.organizationTitles || [];

      // 取得した組織を組織選択に設定
      const values = organizationTitles.map(item => ({
        code: item.organization.code,
        name: item.organization.name
      }));
      record.組織選択.value = values;
      kintone.app.record.set({ record });
    });

    return event;

  });
})();
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?