MENU

ブログ

BLOG ブログ BLOG ブログ
  • Home
  • ブログ
  • kintone javascript入門|できることと実装方法をサンプルコード付きで初心者も安心
2025/07/11

kintone javascript入門|できることと実装方法をサンプルコード付きで初心者も安心

kintone javascript入門|できることと実装方法をサンプルコード付きで初心者も安心
  • facebook
  • x
  • line
  • はてなブックマーク

kintoneをもっと便利に使いたい」「標準機能では物足りない」と感じている方にとってjavascriptによるカスタマイズは非常に魅力的な選択肢です。しかしkintone javascriptと検索しても「何ができるのか」「どこにどう書けばいいのか」とわからず戸惑ってしまう方も多いのではないでしょうか。

本記事ではkintoneをjavascriptで拡張する際に押さえるべき基本知識から代表的なカスタマイズ手法までを体系的に解説します。表示制御や入力チェック、自動処理の追加といった実用的なサンプルコードも紹介しており、初心者の方でも安心して読み進められる構成になっています。

さらに、開発に必要な準備やエラー発生時の対処法、実際の導入事例など、現場で役立つノウハウも満載です。これからkintoneのjavascriptカスタマイズを始める方に向けて最適なスタートガイドとしてぜひご活用ください。

また、まずはkintoneについて詳しく知りたい方はこちらの記事をまずはご覧ください。

kintone javascriptの基礎知識

javascriptによるkintoneカスタマイズは、業務アプリの柔軟な拡張を可能にする手段として多くの企業や現場で活用されています。

本章ではkintoneとjavascriptの関係や基本的な記述方法、カスタマイズを始めるために必要な準備について初学者でも理解しやすいよう順を追って解説していきます。

 

kintone javascriptとは

javascriptを用いたkintoneのカスタマイズは、標準機能では実現できない柔軟な業務フローの構築やユーザー体験の向上を可能にします。

本セクションではkintoneにjavascriptを導入することで得られる機能拡張の具体例や、その特徴について詳しく解説します。

 

javascriptで拡張できる機能とは

kintoneにおいてjavascriptで実装できる主な拡張機能には、画面要素の表示・非表示制御やフィールドの値の自動設定、入力内容のバリデーション(検証)、さらにはkintone REST APIとの連携処理などが含まれます。具体的にはチェックボックスやラジオボタンの動作制御、数値や文字列の入力制限、ボタンの動的生成などユーザーの操作性を高める工夫を施すことが可能です。

 

また、アプリ間でのデータ連携や外部システムとの情報連携を行うことでkintoneを企業内システムのハブとして活用する拡張も行えます。このような多彩な表現力と自由度の高さがjavascriptによるkintoneカスタマイズの大きな魅力です。

 

標準機能とJSカスタマイズの違い

kintoneの標準機能でもドラッグ&ドロップによるフォーム作成や計算式によるフィールド処理など、基本的な業務アプリは十分に構築できます。ただこれらの機能はテンプレート的な設計が多く、細やかな業務要件やUX向上といった面では限界があります。

一方javascriptを用いたカスタマイズでは、標準機能で不可能な条件分岐や非同期通信などを柔軟に実装できる点が特徴です。

例えば「担当者がログインしている場合だけ表示する」「選択内容に応じてフィールド構成を変更する」といった動的な処理も、コードによって自在に設計できます。標準機能とjavascriptカスタマイズを適切に使い分けることで、より高度で実務に即したアプリを構築できるようになります。

機能 標準機能 javascriptカスタマイズ
フィールドの表示制御 一部可(条件付き書式) 柔軟に対応可
入力チェック(バリデーション) 一部可(必須・文字数) 条件式による自由なチェック
ボタン追加・独自アクション 不可 任意のボタン追加+処理可能
外部システムとの連携 限定的(CSV連携など) REST API等を用いて自由に実装可

 

基本の記述方法とカスタマイズ場所

kintoneでjavascriptを使ったカスタマイズを行うには、まずjavascriptファイルをkintoneアプリに読み込ませる必要があります。カスタマイズの種類に応じて設定場所や記述方法も異なるため、初めに構造を理解しておくことが重要です。

kintoneカスタマイズで記述する場所

javascriptは各アプリの「設定」画面から「javascript/CSSでカスタマイズ」項目を開き、ファイルとしてアップロードすることで適用されます。複数ファイルを登録することも可能で、記述内容によっては外部ライブラリの読み込みやCDN指定もできます。

記述するコードは通常kintoneのイベントハンドラを用いた形式となり、kintone.events.on(‘app.record.create.show’, function(event){…})のような形で、画面表示やレコード操作のタイミングに合わせて処理を挿入します。この構造を理解することで、目的に応じたカスタマイズがしやすくなります。

 

イベント処理とそのタイミング

kintoneでのjavascriptカスタマイズは特定のユーザー操作やシステムイベントの発生時に処理を行う「イベント駆動型」が基本です。

例えばレコード新規作成画面の表示時には「app.record.create.show」、編集画面表示時には「app.record.edit.show」、保存直前には「app.record.create.submit」など、さまざまなイベントが用意されています。

こうしたイベントの活用により、「画面を表示したときに自動でフィールドを入力する」「保存時に特定条件をチェックしてバリデーションを行う」といった実装が可能になります。

各イベントがどのタイミングで発火するかを正しく把握することで、狙い通りのカスタマイズを実現できます。

 

開発前に整えるべき環境と前提

javascriptでの開発を始める前には、基本となる作業環境の整備や、kintoneの設定への理解が必要不可欠です。ここでは開発前に準備すべき要素について確認します。

JavaScriptファイルのアップロード手順

javascriptファイルをアプリに反映するにはkintoneの管理画面から該当アプリの設定を開き「javascript/CSSでカスタマイズ」から「PC用のjavascriptファイル」に対象ファイルを追加します。

ファイルはローカルからアップロードする方法とURLを指定してCDNなど外部から読み込む方法の2種類があります。

アップロード後は保存を行い、アプリを更新することで設定が反映されます。ファイルの順序や重複読み込みには注意が必要で、依存関係のあるライブラリがある場合は読み込み順にも気を配る必要があります。

 

テスト環境とプレビュー活用方法

開発したjavascriptをいきなり本番環境で動かすのはリスクが大きいため、kintoneではテストやプレビュー機能を活用するのが推奨されます。具体的には、テスト用にコピーしたアプリで動作確認を行う方法やアプリの動作テスト機能を活用してUIや挙動を事前に確認する方法があります。

また、Chromeの開発者ツールやkintone APIのレスポンス確認機能を併用することでエラー発生時のデバッグや原因特定もしやすくなります。こうした検証環境を整えることで安全かつ効率的な開発フローを実現できます。

 

kintone javascriptで入力ミス防止・ユーザー操作の最適化

javascriptを活用することでkintoneアプリの入力操作をより直感的かつ効率的にすることが可能になります。

本章では入力補助機能の実装やユーザーの操作に応じた動的制御によってミスを防ぎ業務品質を高める手法について紹介します。

フォーム入力の制御と自動補完

kintoneのフォームにおいてユーザーの操作ミスや入力忘れを防ぐためには、入力ルールの明確化と補完機能の整備が欠かせません。javascriptを使えば条件に応じたフィールドの制御や自動入力を柔軟に実現できます。

例えば特定のフィールドに入力があった場合に他のフィールドを自動で補完したり、選択肢によって表示項目を切り替えるような動的なフォーム構成が可能です。また、ユーザーの操作負荷を軽減するために、初期値の設定や既存データの自動読み込みといった処理を加えることで、より快適な入力体験を提供できます。

こうした工夫は日々の業務におけるヒューマンエラーの削減だけでなく、作業時間の短縮にも寄与します。

チェックボックスのON/OFF制御

チェックボックスの制御もjavascriptで柔軟に行えます。例えばある条件を満たす場合に自動的にチェックをONにしたり、選択肢に応じてチェック状態をクリアするといった処理を実装することで入力の手間やミスを最小限に抑えられます。

具体的には数値やテキストの入力内容に応じて事前に定義したルールでチェック状態を設定し、ユーザーが意識せずとも正確な値が保持されるようになります。このような自動制御は特に申請書や確認項目が多い業務で有効です。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

/**
 * 顧客ステータス変更時に「フォロー必要」チェックボックスを自動設定
 * - 新規レコード画面・編集画面両方に対応
 * - フィールドコードが異なる場合は下記配列/オブジェクトのキーを修正してください
 */

(function () {
  'use strict';
  // 対象イベント(PC用)

  const EVENTS = [
    'app.record.create.change.顧客ステータス', // 新規登録画面
    'app.record.edit.change.顧客ステータス'   // 編集画面
  ];




  kintone.events.on(EVENTS, function (event) {
    const record = event.record;




    if (record['顧客ステータス'].value === '契約済み') {
      // チェックを付ける(checkbox は配列で値を設定)
      record['フォロー必要'].value = ['はい'];
    } else {
      // チェックを外す
      record['フォロー必要'].value = [];
    }
    return event;
  });

  // --- モバイル対応(必要な場合はコメントアウト解除) ---
  /*
  kintone.mobile.events.on(EVENTS, function (event) {
    const record = event.record;
    if (record['顧客ステータス'].value === '契約済み') {
      record['フォロー必要'].value = ['はい'];

    } else {
      record['フォロー必要'].value = [];
    }
    return event;
  });
  */
})();

このスクリプトは「顧客ステータス」フィールドが「契約済み」の場合に「フォロー必要」のチェックを自動ONにし、それ以外ではOFFにします。

 

ラジオボタンの初期値設定

ラジオボタンの選択肢に初期値を設定しておくことも操作の効率化と入力漏れの防止に効果的です。javascriptを用いれば画面表示時に自動で特定の値を選択状態にする処理が簡単に実装できます。

例えば申請種別が「新規」である場合に「個人」をデフォルトとして選択させるといった設定を行うことでユーザーが毎回選び直す手間を省けます。条件に応じた初期値の出し分けを行うことで、より状況に合った入力画面の提供が可能になります。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function() {
  'use strict';
  kintone.events.on('app.record.create.show', function(event) {
    const record = event.record;
    if (!record['申請種別'].value) {
      record['申請種別'].value = '新規';
    }
    return event;
  });
})();

このコードはレコード作成画面の表示時に「申請種別」フィールドに値が未設定なら「新規」を自動で選択します。

 

フィールドの表示/非表示制御

入力フォームにおけるフィールドの表示・非表示も、javascriptを用いることで動的に制御できます。例えば、ある選択肢が選ばれたときだけ関連する詳細項目を表示し、そうでない場合は非表示にするといった設計が可能です。

このような表示切り替えによってユーザーは必要な情報だけに集中でき、視認性や操作性が大きく向上します。また不要なフィールドの存在による誤入力や混乱を防ぐ効果もあり、入力の正確性向上にも貢献します。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';
  const EVENTS = [
    'app.record.create.show',
    'app.record.edit.show',
    'app.record.detail.show',
    'app.record.create.change.商品カテゴリ',
    'app.record.edit.change.商品カテゴリ'
  ];

  kintone.events.on(EVENTS, function (event) {
    const record = event.record;
    const isOther = record['商品カテゴリ'].value === 'その他';
    kintone.app.record.setFieldShown('商品詳細', isOther);
    return event;
  });
})();

「商品カテゴリ」が「その他」のときのみ「商品詳細」フィールドを表示する例です。

 

ユーザー選択フィールドの自動設定

kintoneではログインユーザーの情報を取得して自動でフィールドに設定することも可能です。これにより担当者の選択を手動で行う必要がなくなり、誤選択のリスクを防ぐことができます。

例えば、kintoneのAPI「kintone.getLoginUser()」を活用してレコード作成時に現在ログインしているユーザーの名前や所属部署をフィールドへ自動入力することができます。これにより、操作負担を軽減しながら記録の正確性を保つことができます。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function() {
  'use strict';

  // ここを実際の文字列(1行)フィールドコードに変更してください
  const STRING_FIELD_CODE = '担当者名';

  // レコード作成画面表示時にログインユーザーの氏名を自動入力
  function setLoginUserName(event) {
    const record = event.record;
    const user   = kintone.getLoginUser();
    record[STRING_FIELD_CODE].value = user.name; // 氏名のみ
    return event;
  }
  kintone.events.on('app.record.create.show', setLoginUserName);
})();

この例ではレコード作成時に「担当者」フィールドにログインユーザーを自動で設定します。

 

バリデーション処理による入力チェック

入力チェックを実装することで不正な値の登録や必須項目の入力漏れを事前に防止できます。本セクションでは代表的なバリデーションの方法について紹介します。

数値制限とエラーメッセージ表示

計算フィールドに対して入力可能な桁数や範囲を指定し、それを超える場合にはメッセージを表示して保存をブロックすることができます。数値フィールドには元から値の範囲指定ができますが、計算フィールドはできません。しかし、JavaScriptを利用すれば、制御することが可能です。

例えば「0〜100の間で入力してください」といった条件を設定し、計算フィールドに条件外の値が入力された際にはその場でメッセージを表示して再入力を促す設計がよく用いられます。このような処理により、データの正確性と整合性を担保できます。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';

  // 作成・編集時の保存イベント
  kintone.events.on(
    ['app.record.create.submit', 'app.record.edit.submit'],
    function (event) {
      var cVal = parseFloat(event.record.C.value);

      // 0~100の範囲外なら保存を中止し、上部にエラーメッセージ表示
      if (isNaN(cVal) || cVal < 0 || cVal > 100) {
        event.error = '評価点数は0~100の範囲で入力してください。';
        return event;  // 保存中止
      }
      return event;    // 正常時は保存
    }
  );
})();

このスクリプトは「評価点数」が0〜100以外の値だった場合、保存処理を止めてエラーを表示します。

 

未入力チェックとアラート通知

必須項目が未入力のまま保存されることを防ぐためには、保存前イベントにてチェック処理を加えることが有効です。例えば、氏名やメールアドレスなどの重要項目に対して入力の有無を確認し、空欄であればアラートを表示して保存を中断させることができます。

このようなバリデーションはユーザーの操作ミスを未然に防ぐだけでなく、後工程における確認作業の負担を大きく減らすことにもつながります。特に申請業務やデータ管理系アプリにおいては高い効果を発揮します。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';

  // 氏名フィールドのフィールドコード(必要に応じて変更)
  var FIELD_CODE = 'Name';

  // レコード保存(作成・編集)時イベント
  kintone.events.on(
    ['app.record.create.submit', 'app.record.edit.submit'],
    function (event) {
      var record = event.record;
      var nameVal = (record[FIELD_CODE] || {}).value || '';

      // 空欄(空白のみ含む)ならエラー表示して保存中止
      if (nameVal.trim() === '') {
        record[FIELD_CODE].error = '氏名は必ず入力してください。';
        return event;          // 保存キャンセル
      }

      // 正常ならエラーをクリアして保存
      if (record[FIELD_CODE].error) {
        record[FIELD_CODE].error = null;
      }

      return event;            // 保存継続
    }
  );
})();

このコードでは「氏名」フィールドが空の場合にエラーメッセージを表示し、保存を中断させます。

 

javascriptの画面カスタマイズによる使いやすさの向上

kintoneはシンプルなUIが特徴ですが現場の運用に即した見た目や操作性を実現するにはjavascriptやCSSを活用したカスタマイズが有効です。

本章では一覧画面や入力画面の操作性を改善する方法を実装コードとあわせて紹介します。

一覧画面の機能拡張

一覧ビューはkintoneの中でも使用頻度の高い画面のひとつです。操作ボタンを追加したり見やすいレイアウトに変更したりすることで、日常業務の効率が格段に向上します。

ボタン追加とクリックイベントの処理

kintoneの一覧画面にオリジナルのボタンを追加し、クリックイベントを通じて任意の処理を実行できます。

例えば、一覧画面から「承認依頼」や「ステータス更新」などの処理をワンクリックで行えるようにすることで、担当者の作業負荷を減らし、処理ミスも防止できます。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';
  /* ---------- 設定 ---------- */
  var FIELD_CODE  = 'status';  // チェックボックスのフィールドコード
  var CHECK_VALUE = '確定';    // 付与する選択肢

  /* ---------- 一覧画面にボタン ---------- */
  kintone.events.on('app.record.index.show', function (event) {
    if (document.getElementById('bulkUpdateBtn')) return event;   // 二重生成防止
    var space =
      kintone.app.getHeaderMenuSpaceElement() ||
      kintone.app.getHeaderSpaceElement();
    if (!space) return event;
    var btn = document.createElement('button');
    btn.id = 'bulkUpdateBtn';
    btn.textContent = '一括更新';
    btn.className = 'kintoneplugin-button-normal';
    btn.style.marginLeft = '8px';
    space.appendChild(btn);

    btn.addEventListener('click', function () {
      fetchAllIdsInView(function (ids) {
        if (ids.length === 0) {
          alert('更新対象のレコードがありません。');
          return;
        }

        if (!confirm(ids.length + ' 件を「' + CHECK_VALUE + '」に更新しますか?')) return;
        runBulkUpdate(ids);
      });
    });
    return event;
  });

  /* ---------- 表示中ビュー全件の $id を取得 ---------- */
  function fetchAllIdsInView(callback) {
    var appId  = kintone.app.getId();
    var ids    = [];
    var LIMIT  = 500;
    var offset = 0;

    // 現在のビュー条件(limit/offset を除去)
    var base = (kintone.app.getQuery && kintone.app.getQuery()) || '';
    base = base.replace(/limit\\s+\\d+/i, '').replace(/offset\\s+\\d+/i, '').trim();
    if (base) base += ' ';

    (function loop () {
      var query = base + 'limit ' + LIMIT + ' offset ' + offset;
      kintone.api(
        kintone.api.url('/k/v1/records', true),
        'GET',
        { app: appId, query: query, fields: ['$id'] },
        function (resp) {
          for (var i = 0; i < resp.records.length; i++) {
            ids.push(resp.records[i].$id.value);
          }
          if (resp.records.length === LIMIT) {
            offset += LIMIT;
            loop();        // さらに取得
          } else {
            callback(ids); // 全件取得完了
          }
        },

        function (err) {
          console.error(err);
          alert('レコード取得に失敗しました。');
        }
      );
    })();
  }


  /* ---------- 一括更新処理 ---------- */
  function runBulkUpdate(idArray) {
    var CHUNK = 100;
    var appId = kintone.app.getId();
    var idx   = 0;

    (function update () {
      var slice = idArray.slice(idx, idx + CHUNK).map(function (id) {
        var rec = { id: id, record: {} };
        rec.record[FIELD_CODE] = { value: [CHECK_VALUE] };
        return rec;
      });

      kintone.api(
        kintone.api.url('/k/v1/records', true),
        'PUT',
        { app: appId, records: slice },
        function () {
          idx += CHUNK;
          if (idx < idArray.length) {
            update();      // 次の 100 件
          } else {
            alert('更新が完了しました。');
            location.reload();
          }
        },
        function (err) {
          console.error(err);
          alert('更新に失敗しました。\\n権限やフィールド設定をご確認ください。');
        }
      );
    })();
  }
})();

このコードは一覧画面表示時に「まとめて完了」ボタンを追加し、クリック時に処理を実行する基本構造です。実際の運用では選択されたレコードに対してAPIを使ってステータスを更新するなどの処理を加えることができます。

 

一覧画面のレイアウト調整(CSS活用)

一覧画面のレイアウトをCSSで調整することで視認性の向上や重要情報の強調表示が可能になります。

例えば特定の条件に該当するレコード行を太字にしたり背景色を変更することで、ユーザーが注意すべき情報にすぐ気づけるようにする工夫ができます。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';

  // 一覧表示完了時
  kintone.events.on('app.record.index.show', function (event) {

    // 一覧の status フィールド要素をすべて取得
    var cells = kintone.app.getFieldElements('status'); // フィールドコード

    cells.forEach(function (el) {

      // “確定” が含まれていたら装飾
      if (el && el.textContent.trim() === '確定') {
        el.style.color = '#ff0000';   // 赤
        el.style.fontWeight = 'bold'; // 太字
      }
    });

    return event;
  });
})();

このコードでは一覧画面上で「国籍」フィールドが「海外」の場合、その行の背景を薄黄色にし、太字表示にしています。視認性を高め、対象レコードの把握を迅速に行えるようになります。

 

入力画面の初期設定強化

kintoneの入力画面はシンプルでわかりやすい反面、業務内容に応じた初期値の設定や視認性の工夫がなければ、ユーザーの入力負荷が高まり入力ミスや操作ミスの原因にもなりかねません。javascriptによる事前設定やレイアウトの調整を行うことでより快適でミスのない入力体験を提供できます。

初期値の動的設定

レコード作成時に条件に応じて特定のフィールドに初期値を自動で設定することができます。これにより入力の手間を削減し、記入漏れや誤入力のリスクを低減できます。

例えばユーザーの部署情報に応じて「申請種別」や「フラグ項目」の初期値を変えるといった対応が可能です。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';

  /**
   * 作成画面で、ログインユーザーが「営業部」に所属していれば
   * 「申請種別」を「訪問申請」、「優先度」を「高」に設定。
   * それ以外は「通常申請」「中」に設定。
   */

  kintone.events.on('app.record.create.show', function (event) {
    var record   = event.record;
    var userCode = kintone.getLoginUser().code;

    // ユーザー所属組織を取得 (Users API)

    var param = { code: userCode };
    return kintone.api('/v1/user/organizations', 'GET', param)
      .then(function (resp) {
        var isSales = resp.organizationTitles &&
                      resp.organizationTitles.some(function (item) {
                        return item.organization &&
                               item.organization.name === '営業部';
                      });


        if (isSales) {
          record['申請種別'].value = '訪問申請';
          record['優先度'].value   = '高';
        } else {
          record['申請種別'].value = '通常申請';
          record['優先度'].value   = '中';
        }
        return event;
      })

      .catch(function (error) {
        console.error('組織取得に失敗:', error);
        return event;  // 取得失敗時は既定値を変更しない
      });
  });
})();

このコードではログインユーザーが「営業部」所属の場合に限り「申請種別」を「訪問申請」「優先度」を「高」に設定し、それ以外は通常申請として処理を分けています。ユーザーの属性に応じた初期値を設定することで入力の標準化とミス防止につながります。

 

フィールド構成の見やすさ改善

フォーム画面において、フィールドが多く並ぶ場合には、順序や表示/非表示の切り替えによって視認性を高めることが可能です。javascriptでは、フィールドの表示状態や順番を動的に調整できます。

例えば、申請種別に応じて表示するフィールド群を変えることでユーザーにとって不要な入力欄を非表示にし、入力の集中力を高めるといった使い方ができます。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function() {
  'use strict';

  function toggleFields(event) {
    const record = event.record;
    const isSpecial = record['申請種別'].value === '特別申請';
    kintone.app.record.setFieldShown('特別対応理由', isSpecial);
    kintone.app.record.setFieldShown('通常備考欄', !isSpecial);
    return event;
  }
  kintone.events.on([
    'app.record.create.show',
    'app.record.edit.show',
    'app.record.create.change.申請種別',
    'app.record.edit.change.申請種別'
  ], toggleFields);
})();

このコードは「申請種別」フィールドが「特別申請」の場合にのみ「特別対応理由」フィールドを表示し、それ以外の場合は「通常備考欄」を表示する仕組みです。これにより、画面上に常にすべてのフィールドを表示せず、ユーザーにとって必要な情報だけを見せることができ、操作性と視認性を大きく向上させることができます。

 

アプリ間連携と高度な拡張性の確保

kintoneは単体でも強力な業務アプリですが、javascriptとAPIを活用することで、アプリ同士の連携や外部サービスとの統合が可能となり、業務全体の効率化・スケーラビリティ向上を実現できます。本章では、アプリ間でデータを受け渡す方法や、kintone APIを活用した拡張方法を紹介します。

レコード取得・登録処理の連携

kintoneのjavascript APIを使うことで、別アプリから情報を取得して表示したり、条件に応じて自動でレコードを登録するといった処理が可能です。これにより、手動での転記作業が不要になり、情報の一貫性も保たれます。

他アプリからのデータ取得実装

例えば、申請画面で選択した取引先コードを元に、別アプリに保存されている取引先情報(会社名、所在地など)を自動で取得・表示することができます。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';

  /* 参照先アプリとフィールドコード */
  var REF_APP_ID = 2083;
  var CODE_F = '取引先コード';
  var NAME_F = '会社名';
  var ADDR_F = '所在地';

  /* ---- 参照アプリから取引先情報を取得 ---- */
  function fetchCustomer(code) {
    var q = CODE_F + ' = "' + code.replace(/"/g, '\\"') + '"';
    return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', {
      app: REF_APP_ID,
      query: q,
      fields: [NAME_F, ADDR_F]
    });
  }

  /* ---- フィールドクリア ---- */
  function clearFields() {
    var rec = kintone.app.record.get().record;
    if (rec[NAME_F]) rec[NAME_F].value = '';
    if (rec[ADDR_F]) rec[ADDR_F].value = '';
    kintone.app.record.set({ record: rec });
  }

  /* ---- フィールドに値をセット ---- */
  function setFields(name, addr) {
    var rec = kintone.app.record.get().record;
    if (rec[NAME_F]) rec[NAME_F].value = name;
    if (rec[ADDR_F]) rec[ADDR_F].value = addr;
    kintone.app.record.set({ record: rec });
  }

  /* ---- 取引先コード変更ハンドラ ---- */
  function handler(event) {
    var code = event.record[CODE_F].value;
    if (!code) {
      clearFields();
      return event;                // 同期で終了
    }

    fetchCustomer(code)
      .then(function (resp) {
        if (resp.records.length > 0) {
          var data = resp.records[0];
          setFields(data[NAME_F].value, data[ADDR_F].value);
        } else {
          clearFields();
        }
      })
      .catch(function (err) {
        console.error('顧客情報取得失敗:', err);
      });

    return event;                  // Thenable を返さない
  }

  // 作成・編集画面で取引先コード変更時に実行
  kintone.events.on(
    ['app.record.create.change.' + CODE_F,
     'app.record.edit.change.'  + CODE_F],
    handler
  );
})();

このコードは「取引先コード」入力時に、別アプリから関連情報を取得して表示フィールドに反映する仕組みです。手入力による情報転記を減らすことで、作業の正確性と効率が向上します。

 

一括レコード登録の自動化処理

複数のレコードを一括で自動登録する処理もjavascriptとkintone APIを活用することで実現可能です。例えば、見積アプリの明細を別アプリにレコードとして自動生成するといったシーンで役立ちます。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function() {
  'use strict';

  kintone.events.on('app.record.create.submit', async function(event) {
    const itemList = event.record['商品一覧'].value;
    if (!itemList.length) return event;
    const records = itemList.map(row => {
      return {
        app: 456, // 登録先アプリID
        record: {
          '商品名': { value: row.value['商品名'].value },
          '単価': { value: row.value['単価'].value },
          '数量': { value: row.value['数量'].value }
        }
      };
    });

    try {
      for (const rec of records) {
        await kintone.api(kintone.api.url('/k/v1/record', true), 'POST', rec);
      }
    } catch (e) {
      console.error('一括登録エラー:', e);
    }
    return event;
  });
})();

このスクリプトは、レコード保存時にサブテーブル「商品一覧」の各行をもとに、別アプリへ1件ずつレコードを登録する処理です。注文処理や申請内容の分配など、業務ごとの再利用性も高く連携の自動化が進みます。

 

kintone APIによる操作の具体例

kintoneにはレコード操作やユーザー情報取得をはじめとする多様なAPIが用意されています。これらをjavascriptから活用することで、標準機能だけでは対応しきれない細やかな処理を補完できます。

kintone.api()の記述パターン

kintone.api()はGET・POST・PUT・DELETEといったHTTPメソッドを用いてレコードやアプリ情報を操作する関数です。例えばレコードの更新処理は以下のように記述します。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function() {
    'use strict';

    // 設定エリア - 必要に応じて変更してください
    const CONFIG = {
        // 見積明細アプリのID(現在のアプリ)
        QUOTATION_APP_ID: 2093,

        // 注文明細アプリのID(転記先アプリ)
        ORDER_APP_ID: 2096,
       
        // サブテーブルのフィールドコード
        SUBTABLE_FIELD: 'subtable', // サブテーブルのフィールドコード
      
        // サブテーブル内のフィールドコード
        SUBTABLE_FIELDS: {
            MODEL_NUMBER: 'model_number',    // 型番
            PRODUCT_NAME: 'product_name',    // 商品名
            UNIT_PRICE: 'unit_price',        // 単価
            QUANTITY: 'quantity',            // 数量
            SUBTOTAL: 'subtotal'             // 小計
        },
       
        // 注文明細アプリのフィールドコード
        ORDER_FIELDS: {
            MODEL_NUMBER: 'model_number',    // 型番
            PRODUCT_NAME: 'product_name',    // 商品名
            UNIT_PRICE: 'unit_price',        // 単価
            QUANTITY: 'quantity',            // 数量
            SUBTOTAL: 'subtotal'             // 小計
        }
    };

    // レコード詳細画面表示時のイベント
    kintone.events.on('app.record.detail.show', function(event) {
        const record = event.record;
        
        // 転記ボタンを作成
        const transferButton = document.createElement('button');
        transferButton.id = 'transfer-to-order-button';
        transferButton.innerText = '注文明細に転記';
        transferButton.className = 'kintoneplugin-button-normal';
        transferButton.style.marginLeft = '10px';
      
        // ボタンクリックイベント
        transferButton.addEventListener('click', function() {
            showConfirmModal(record);
        });    

        // ボタンを配置
        const menuSpace = kintone.app.record.getHeaderMenuSpaceElement();
        menuSpace.appendChild(transferButton);    
        return event;
    });

    // 確認モーダルを表示する関数
    function showConfirmModal(record) {
        // サブテーブルのデータを取得
        const subtableField = record[CONFIG.SUBTABLE_FIELD];      
        if (!subtableField || !subtableField.value) {
            alert('サブテーブルのフィールドが見つかりません。\nフィールドコード「' + CONFIG.SUBTABLE_FIELD + '」を確認してください。');
            return;
        }       
        const subtableData = subtableField.value;    
        if (!subtableData || subtableData.length === 0) {
            alert('転記する明細データがありません。');
            return;
        }

        // モーダルの背景を作成
        const modalOverlay = document.createElement('div');
        modalOverlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 10000;
            display: flex;
            justify-content: center;
            align-items: center;
        `;

        // モーダルコンテンツを作成
        const modalContent = document.createElement('div');
        modalContent.style.cssText = `
            background-color: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
            max-width: 500px;
            width: 90%;
            text-align: center;
        `;

        // モーダル内容を設定
        modalContent.innerHTML = `
            <h3 style="margin-top: 0; color: #333;">転記確認</h3>
            <p style="margin: 20px 0; color: #666; line-height: 1.6;">
                サブテーブルの明細データ(${subtableData.length}件)を<br>
                注文明細アプリに転記します。<br><br>
                実行してもよろしいですか?
            </p>
            <div style="margin-top: 25px;">
                <button id="cancel-btn" style="
                    background-color: #ccc;
                    color: #333;
                    border: none;
                    padding: 10px 20px;
                    margin-right: 10px;
                    border-radius: 4px;
                    cursor: pointer;
                ">キャンセル</button>
                <button id="execute-btn" style="
                    background-color: #3498db;
                    color: white;
                    border: none;
                    padding: 10px 20px;
                    border-radius: 4px;
                    cursor: pointer;
                ">実行</button>
            </div>
        `;
        modalOverlay.appendChild(modalContent);
        document.body.appendChild(modalOverlay);

        // キャンセルボタンのイベント
        document.getElementById('cancel-btn').addEventListener('click', function() {
            document.body.removeChild(modalOverlay);
        });

        // 実行ボタンのイベント
        document.getElementById('execute-btn').addEventListener('click', function() {
            document.body.removeChild(modalOverlay);
            executeTransfer(subtableData);
        });

        // モーダル背景クリックで閉じる
        modalOverlay.addEventListener('click', function(e) {
            if (e.target === modalOverlay) {
                document.body.removeChild(modalOverlay);
            }
        });
    }

    // 転記実行関数
    function executeTransfer(subtableData) {
        // ローディング表示
        showLoading(true);
        try {
            // サブテーブルの各行を注文明細アプリのレコードとして作成
            const records = subtableData.map(function(row) {
                const record = {};      

                // 行データの存在確認
                if (!row || !row.value) {
                    throw new Error('サブテーブルの行データが不正です');
                }
               
                const rowData = row.value;
               
                // 各フィールドのデータを設定(存在確認付き)
                record[CONFIG.ORDER_FIELDS.MODEL_NUMBER] = {
                    value: (rowData[CONFIG.SUBTABLE_FIELDS.MODEL_NUMBER] && 
                           rowData[CONFIG.SUBTABLE_FIELDS.MODEL_NUMBER].value) || ''
                };
                record[CONFIG.ORDER_FIELDS.PRODUCT_NAME] = {
                    value: (rowData[CONFIG.SUBTABLE_FIELDS.PRODUCT_NAME] && 
                           rowData[CONFIG.SUBTABLE_FIELDS.PRODUCT_NAME].value) || ''
                };

                record[CONFIG.ORDER_FIELDS.UNIT_PRICE] = {
                    value: (rowData[CONFIG.SUBTABLE_FIELDS.UNIT_PRICE] && 
                           rowData[CONFIG.SUBTABLE_FIELDS.UNIT_PRICE].value) || 0
                };
                record[CONFIG.ORDER_FIELDS.QUANTITY] = {
                    value: (rowData[CONFIG.SUBTABLE_FIELDS.QUANTITY] && 
                           rowData[CONFIG.SUBTABLE_FIELDS.QUANTITY].value) || 0
                };
                record[CONFIG.ORDER_FIELDS.SUBTOTAL] = {
                    value: (rowData[CONFIG.SUBTABLE_FIELDS.SUBTOTAL] && 
                           rowData[CONFIG.SUBTABLE_FIELDS.SUBTOTAL].value) || 0
                };
                return record;
            });

            // 一括でレコードを追加
            const params = {
                app: CONFIG.ORDER_APP_ID,
                records: records
            };

            kintone.api(kintone.api.url('/k/v1/records', true), 'POST', params)
                .then(function(resp) {
                    showLoading(false);
                    alert(`${records.length}件のレコードを注文明細アプリに転記しました。`);
                })
                .catch(function(error) {
                    showLoading(false);
                    console.error('転記エラー:', error);
                    alert('転記中にエラーが発生しました。\n詳細はコンソールを確認してください。');
                });           
        } catch (error) {
            showLoading(false);
            console.error('データ処理エラー:', error);
            alert('データの処理中にエラーが発生しました。\nフィールドコードの設定を確認してください。\n詳細: ' + error.message);
        }
    }

    // ローディング表示/非表示
    function showLoading(show) {
        const existingLoader = document.getElementById('transfer-loader');   
        if (show) {
            if (existingLoader) return; // 既に表示中の場合は何もしない            
            const loader = document.createElement('div');
            loader.id = 'transfer-loader';
            loader.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background-color: rgba(255, 255, 255, 0.8);
                z-index: 10001;
                display: flex;
                justify-content: center;
                align-items: center;
                flex-direction: column;
            `;
            
            loader.innerHTML = `
                <div style="
                    border: 4px solid #f3f3f3;
                    border-top: 4px solid #3498db;
                    border-radius: 50%;
                    width: 40px;
                    height: 40px;
                    animation: spin 1s linear infinite;
                "></div>
                <p style="margin-top: 20px; color: #666;">転記中...</p>
                <style>
                    @keyframes spin {
                        0% { transform: rotate(0deg); }
                        100% { transform: rotate(360deg); }
                    }
                </style>
            `;        
            document.body.appendChild(loader);
        } else {
            if (existingLoader) {
                document.body.removeChild(existingLoader);
            }
        }
    }
})();

このようにレコードの更新や削除、検索もAPIで柔軟に実行できるため、他アプリや外部システムとの連携にも応用可能です。

 

kintone.getLoginUser()でのユーザー操作制御

ログイン中のユーザー情報を取得して、画面制御やデータ制限に活用することも可能です。例えば、ユーザーごとに表示するフィールドを切り替えるといった処理が代表的です。

■サンプルコード
※以下サンプルコードはそのままコピーしても動作しない可能性がございます。実際にご利用されている環境に合わせて調整してご利用ください。

(function () {
  'use strict';
  const TARGET_ORG = '管理部';      // 表示対象の組織名
  const FIELD_CODE  = 'inner_memo'; // 表示/非表示を切り替えるフィールドコード
  const EVENTS = [
    'app.record.create.show',
    'app.record.edit.show',
    'app.record.detail.show'
  ];

  // 所属組織を REST API で取得
  function fetchUserOrganizations(userCode, callback) {
    const param = { code: userCode };
    kintone.api(kintone.api.url('/v1/user/organizations', true), 'GET', param)
      .then(function (resp) {
        const orgs = (resp.organizationTitles || []).map(function (title) {
          return title.organization;
        });
        callback(orgs);
      })
      .catch(function () {
        callback([]); // エラー時は空配列
      });
  }
  kintone.events.on(EVENTS, function (event) {
    const user = kintone.getLoginUser();
    // 初期状態で非表示
    kintone.app.record.setFieldShown(FIELD_CODE, false);
    fetchUserOrganizations(user.code, function (orgs) {
      const isTarget = orgs.some(function (org) {
        return org && org.name === TARGET_ORG;
      });
      if (isTarget) {
        kintone.app.record.setFieldShown(FIELD_CODE, true);
      }
    });
    return event;
  });
})();

このコードはログインユーザーの部署が「管理部」の場合のみ「内部メモ」フィールドを表示し、それ以外では非表示にする処理です。閲覧制御をコードベースで行うことで、より柔軟な権限設計が可能になります。

トラブル対応・参考事例による学習支援

javascriptを活用したkintoneカスタマイズは非常に柔軟ですが、その分エラーの原因が複雑化しやすい傾向にあります。また、他社の導入事例や参考コードから学ぶことも多くあります。本章では、カスタマイズがうまく動作しないときの原因特定のヒントや、活用事例を学べる情報源について紹介します。

JSカスタマイズが動作しないときの対処法

javascriptが思った通りに動かないときは基本的な原因の洗い出しとチェックリストの活用が有効です。特に読み込み順やファイルの場所、フィールドコードの設定ミスなどがよくある原因です。

読み込み順序やファイル配置の確認

javascriptが正しく適用されていない場合、まず確認すべきはファイルの読み込み順と配置場所です。

例えば複数のスクリプトを読み込んでいる場合、依存関係のあるライブラリ(jQueryなど)が先に読み込まれていないと、スクリプトが正しく動作しません。

■サンプルコード

// 誤りのある例(jQueryの後に依存コードを読み込むべき)
<script src="custom.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

このような場合は、jQueryの読み込みを先に配置する必要があります。また、kintoneの設定画面でモバイルとPCで別々のファイル設定になっていないか、キャッシュのクリアが必要ではないかも合わせて確認しましょう。

フィールドコード/権限設定の見直し

フィールドの表示や値の取得ができない原因の多くは、「フィールドコード」の設定ミスによるものです。例えば、フォーム上では「お客様名」と表示されていても、コードが customer_name など別名になっている場合、正確に参照できません。

さらに、フィールドに対する「閲覧・編集権限」がユーザーに付与されていないと、スクリプトで値を取得しようとしてもundefinedとなることがあります。

■サンプルコード

console.log(event.record['customer_name']); // undefinedとなる例

このような場合、アプリのフォーム設定とユーザーのアクセス権限を確認・調整することで改善されます。

質問カテゴリー別のよくあるエラー

フィールドの値が取得できない

kintoneのjavascriptで「値が取得できない」「undefinedになる」といった相談は非常に多く見られます。多くの場合、フィールドコードと表示名が混同されていることが原因です。フォームの設定画面でフィールドコードを確認し、コード側に正しいIDを使用しているかチェックしましょう。

■サンプルコード

// フィールド名ではなくフィールドコードを指定
console.log(event.record['customer_name'].value);

カスタマイズが反映されない

javascriptのカスタマイズが反映されないとき、よくある原因は「ファイル更新忘れ」や「キャッシュの影響」です。ファイルをアップロードしただけでは反映されないため、アプリ設定画面で『アプリの更新』を必ず実行してください。

また、動作確認時はCtrl+F5でキャッシュをクリアして再読み込みすることで、反映状況を正確に確認できます。

kintone.apiでエラーになる

API通信でエラーが出る場合、主な原因は以下の3つです。

  • リクエストに必要なappidなどのパラメータが不足している
  • クエリの書式が正しくない(例:=の両端にスペースがない)
  • アクセス権限が不足している(APIを叩ける権限がない)

■サンプルコード

// 正しい形式でのGET例
kintone.api(kintone.api.url('/k/v1/record', true), 'GET', {
  app: 123,
  id: 456
});

jQueryが効かない/$が使えない

kintoneではjQueryが標準では読み込まれていないため、CDNから明示的に読み込む必要があります。また、jQueryの読み込み順が他のスクリプトより先でないと、$ is not definedというエラーが発生します。

■サンプルコード

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="custom_script.js"></script>

まとめ

kintoneのjavascriptカスタマイズは標準機能では実現できない柔軟な操作性と業務効率化を可能にします。

入力補助やバリデーションによるミス防止、サブテーブルの自動計算、アプリ間連携など、目的に応じて多様な拡張が実現できます。また、kintone APIやユーザー情報の動的取得を組み合わせれば、現場のニーズに合わせた精度の高い業務アプリが構築できます。

本記事を通じて、基本的なカスタマイズ方法から自動化・連携までの全体像をつかんでいただけたと思います。今後更に実際の業務フローに応じてコードを応用し、自社に最適なアプリへと育てていきましょう。

弊社ではkintoneの初期導入支援からカスタム開発、外部システム連携、kintoneを強化するためのプラグイン「Smart atシリーズ」を提供しています。業務にフィットした使い方を一緒に設計したいとお考えの方、具体的な支援内容や価格についてご興味・ご関心がある方は、ぜひお気軽にお問い合わせください。

 

資料ダウンロードはこちら 無料トライアルはこちら お問い合わせはこちら

 

プロフィール

  • M-SOLUTIONSメディア編集部

    10年以上kintoneに携わっているkintoneのスペシャリストチーム。 kintoneだけでなく、サイボウズ関連製品や最新テクノロジーにも精通。 kintoneをより便利にする情報をお届けします。 kintone認定アソシエイト・アプリデザインスペシャリスト・カイゼンマネジメントエキスパート取得者所属。

Other recommended articles その他おすすめ記事 Other recommended articles

ブログ ありません。