Table Numbering Plug-in

Contents

Introduction

This article introduces the Table Numbering Plug-in, which is a plug-in version of the sample code introduced in the " Insert Row Numbers Into Tables" article.
Upon saving a record, this plug-in will automatically fill in the specified Number field of the specified Table with row numbers. Users will also not be able to edit the specified Number field when entering data into the record.

Plug-in file

The packaged sample plug-in zip file can be downloaded from the Releases page (External link) on GitHub.
Install the plug-in into your domain by following the plug-in installation guide on the Help page (External link) .
You can then add the plug-in to a specific App by following the plug-in adding guide on the Help page (External link) .

Overview

To set up the plug-in, the Kintone App must have a Table that includes a Number field in its form. Check the Kintone Help Pages (External link) to understand how to create tables in the form.

There is only one setting for this plug-in, which is to choose which Number field in the App form will have their values automatically set with row numbers. Number fields that exist outside of Tables will not be listed in the drop-down list.

Save the settings and update the App. When adding new data into a table, the specified Number field will be restricted from being edited. Upon saving the record, the specified Number field will be filled in with their row numbers.

File structure

The sample codes used in the plug-in are listed under the src file in our GitHub repository (External link) .
The plug-in is created with the following file structure:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
plug-in/
├── html/
│       └──── config.html
├── css/
│       ├──── 51-modern-default.css
│       └──── config.css
├── js/
│       ├──── config.js
│       └──── desktop.js
├── image/
│       └──── usericonicon.png
└── manifest.json

The first "kintoneplugin-row" div contains the HTML of the first (and only) settings, where the user chooses which Number field will contain the row number. A select tag is stated in the HTML, that creates a drop-down field with a value of "-----". This drop-down field is later populated by the config.js file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<section>
  <form class="js-submit-settings">
    <div class="kintoneplugin-row">
      <label for="select_number_field" class="kintoneplugin-label">Row Number
        <span class="kintoneplugin-require">*</span>
      </label>
      <p class="kintoneplugin-desc">Please select a Number field that exists in a table.<br />
        Row numbers will automatically be placed into this Number field.</p>
      <div class="kintoneplugin-select-outer">
        <div class="kintoneplugin-select">
          <select id="select-number-field" name="js-select-number-field">
            <option value="">-----</option>
          </select>
        </div>
      </div>
    </div>
    <p class="kintoneplugin-row">
      <button type="button" class="js-cancel-button kintoneplugin-button-dialog-cancel"> Cancel </button>
      <button class="kintoneplugin-button-dialog-ok"> Save </button>
    </p>
  </form>
</section>

The drop-down field has an ID allocated to it, which is later specified by the config.js file so that it can be populated with other drop-down choices.

This CSS file is provided on GitHub (External link) . This file styles HTML elements on the plug-in config page to fit in with Kintone's UI.
We recommend that you do not make changes to 51-modern-default.css. If you need to style additional elements, or over-ride the default styles, those changes should be added into config.css

This supporting CSS file is used to style some areas of the plug-in config page that 51-modern-default.css doesn't cover.

The function setDropDown is called when the plug-in setting page loads. It uses the kintone.api() wrapper from the JavaScript API to call the REST API endpoint Get Form Fields.Get Form Fields returns an object that contains the form fields for the specified App.
Depending on the endpoint called, Get Form Fields can return either the deployed form fields (the user has clicked Update App in the App Settings and the changes have been committed) or the preview form fields (the form has been saved in the App settings, but the user has not clicked Update App and committed them). This function uses the preview endpoint as users may access the plug-in settings page before they are ready to commit their changes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function setDropDown() {
  // Retrieve field information, then set drop-down
  return kintone.api(kintone.api.url('/k/v1/preview/app/form/fields.json', true), 'GET', {'app': kintone.app.getId()}).then(function(resp) {
  // ...
  // run rest of code here after retrieving preview form information from the App
  // resp contains the response data
  // ...
  }, function(resp) {
    return alert('Failed to retrieve field(s) information');
  });
}

This plug-in needs data of the Number fields that exist within Tables from the returned object.
The returned object is passed through 2 for loops - one for identifying fields with type value of SUBTABLE (the Table) and the other for identifying fields within that table with the type value of NUMBER (the Number field). The extracted selections are then appended to the element with the name of js-select-number-field that is contained in the $number variable to create a drop-down list of Number fields (that exist inside tables) in the App.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
for (key in resp.properties) {
  if (!Object.prototype.hasOwnProperty.call(resp.properties, key)) {
    continue;
  }
  prop = resp.properties[key];
  if (prop.type === 'SUBTABLE') {
    for (key2 in prop.fields) {
      if (!Object.prototype.hasOwnProperty.call(prop.fields, key2)) {
        continue;
      }
      field = prop.fields[key2];
      $option = $('<option></option>');
      if (field.type === 'NUMBER') {
        $option.attr('value', prop.code + ',' + field.code); // Set table code and number field code
        $option.text(escapeHtml(field.label));
        $number.append($option.clone());
      }
    }
  }
}

At the end of the setDropDown function, the code looks through the CONF object where any saved setting data are stored. If it's the first time for the user to use the plug-in, there are no saved values, thus no values are placed in the settings of the plug-in settings page. If the user has previously saved any settings before in the plug-in (which are stored using Kintone's setConfig API), then those saved values (the specified Number field) are inserted into the designated plug-in configuration settings.

1
2
// Set default values
$number.val(CONF.table + ',' + CONF.number);

When the Save button is clicked in the plug-in config page, the selected Number field and the related Table data is stored into Kintone using the setConfig API.

1
2
3
4
5
config.table = number.split(',')[0]; // Set table field code
config.number = number.split(',')[1]; // Set number field code
kintone.plugin.app.setConfig(config, function() {
  // ...
});

This file runs on the regular pages of the App, such as the Record List and Record Details pages, but not on the plug-in config page. This file uses the sample code included in the " Insert Row Numbers Into Tables" article. The code used in this plug-in is mostly the same, but it's wrapped in an immediate function with the plug-in ID value as the input parameter. The plug-in ID value is needed for several JavaScript API calls, such as Kintone's getConfig API that retrieves data that was saved in the plug-in config page using the setConfig API.

1
2
// Get plug-in configuration settings
var CONFIG = kintone.plugin.app.getConfig(PLUGIN_ID);

Data retrieved with the kintone.plugin.app.getConfig(PLUGIN_ID) method are allocated to variables.

1
2
3
4
var TABLEFIELD, NUMBERFIELD, disableEvents;
// ...
TABLEFIELD = CONFIG.table; // Field code of the table
NUMBERFIELD = CONFIG.number; // Field code of number field in the table

There are two main pieces to the desktop.js code.
The first piece is the disabling of the Number fields, so that they cannot be edited by the user.
This process occurs in the app.record.edit.show and app.record.create.show events so that the Number fields are disabled as soon as the user opens the Record Create or Record Edit page. The app.record.edit.change.(fieldcode) and app.record.create.change.(fieldcode) events trigger when a user adds a new row to the table - if these events are not stated, the Number fields in the newly added rows will be editable.

1
2
3
4
5
6
var disableEvents = [
  'app.record.edit.show',
  'app.record.create.show',
  'app.record.edit.change.' + TABLEFIELD,
  'app.record.create.change.' + TABLEFIELD
];

When these events are triggered the code looks through the event object, and the disabled property of each Number field in the Table is set to true so that they become un-editable when the event object is returned.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var numberEvents, row;
// ...
kintone.events.on(disableEvents, function(event) {
  var record = event.record;
  // Disable number fields in table rows
  var count = record[TABLEFIELD].value.length;
  for (row = 0; row < count; row++) {
    record[TABLEFIELD].value[row].value[NUMBERFIELD].disabled = true;
  }
  return event;
});

For the second piece, the Number fields are automatically filled in with row numbers when the app.record.create.submit or app.record.edit.submit event triggers.

1
2
3
4
5
6
7
var numberEvents, row;
// ...
// Number table rows at these events
numberEvents = [
  'app.record.create.submit',
  'app.record.edit.submit'
];

When these events are triggered, a for loop processes the event object to overwrite the values of the Number fields. Returning this object overwrites the actual data within the Kintone record with the new values set in the event object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kintone.events.on(numberEvents, function(event) {
  var record = event.record;

  // Auto-number the table rows
  var count = record[TABLEFIELD].value.length;
  for (var row = 0; row < count; row++) {
    record[TABLEFIELD].value[row].value[NUMBERFIELD].value = row + 1;
  }

  return event;
});

The manifest file states the paths of the files that will be used in the plug-in. It also links to the jQuery library hosted on the Kintone CDN, so that it can be called on the config page.

1
2
3
4
5
6
7
"config": {
  "html": "html/config.html",
  "js": [
    "https://js.kintone.com/jquery/3.3.1/jquery.min.js",
    "js/config.js"
  ]
}

The array in the value of the required_params key states which settings in the plug-in config page are required. If these settings are not saved using the setConfig API, errors will be displayed on other pages of the App, stating that the plug-in settings have not been configured yet.

1
2
3
4
"required_params": [
  "number",
  "table"
]

The name, description, and homepage_url key-value pairs are labels and links displayed in the plug-in settings.

1
2
3
4
5
6
7
8
9
"name": {
  "en": "Table Numbering Plug-in"
},
"description": {
  "en": "This sample plug-in automatically adds row numbers to table rows each time the record is saved."
},
"homepage_url": {
  "en": "https://kintone.dev/en/plugins/simple-samples/table-numbering-plug-in/"
}

Finally

Licenses

This plug-in is open sourced under the MIT License (External link) . It allows open- or closed-sourced distribution, including commercial use.
If you would like to add more functionality to the plug-in, you are welcome to clone our repository to make your own changes and redistribute it. We generally do not accept external pull requests for the sample plug-in as this repository exists for educational purposes.
If you have any questions related to building Kintone plug-ins, please post your question in the Kintone Developer Program Community Forum (External link) .

Contribution

This sample plug-in was created with the contribution of Fuji Business International (External link)
Mamoru Fujinoki - LinkedIn (External link)