Character Count Plug-in

Contents

Introduction

This article introduces the Character Count Plug-in, which is a plug-in version of the sample code introduced in the Count Characters Inside Fields article.
This plug-in counts the number of characters in a Text Area field (excluding spaces and line breaks) and stores the number in the specified Number field upon saving 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 Adding/deleting plug-ins (Kintone administration) (External link) guide in the Kintone Help page. You can then add the plug-in to a specific App by following Adding/deleting plug-ins (App settings) (External link) guide in the Kintone Help page.

Overview

To set up the plug-in, the Kintone App must have a Text Area field and a Number field set in its form.

There are two settings for this plug-in.
For the first setting, select a Text Area field from the drop-down list.
For the second setting, select a Number field from the drop-down list.

After saving the plug-in settings and updating the App, the plug-in's features will run when a record is saved, by counting the number of characters (excluding spaces and line breaks) in the specified Text Area field, and then inserting the number into the specified Number field.
The Number field is also set to be un-editable while the user enters information into the record.

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/
│       └──── characters.png
└── manifest.json

config.html (External link)

This file builds the HTML of the plug-in settings page.
Each <div> tag with the "block" class represents 1 row of related HTML elements.

The first "kintoneplugin-row" div contains the HTML of the first settings, where the user chooses which Text Area field will have their characters counted. 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
<div class="kintoneplugin-row">
  <label for="select_body_field" class="kintoneplugin-label">
    Field to Count
   <span class="kintoneplugin-require">*</span>
  </label>
  <p class="kintoneplugin-desc">Please select a Text Area field</p>
  <div class="kintoneplugin-select-outer">
    <div class="kintoneplugin-select">
      <select id="select_body_field" name="js-select_body_field" required>
        <option value="">-----</option>
      </select>
    </div>
  </div>
</div>

The second "kintoneplugin-row" div contains the HTML of the second settings, where the user chooses which Number field will store the number of counted characters. Similar to the first settings, a select tag is stated in the HTML that creates a drop-down field with a value of "-----". This drop-down field is also later populated by the config.js file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<div class="kintoneplugin-row">
  <label for="select_count_field" class="kintoneplugin-label">
    Field to Store Character Counts
    <span class="kintoneplugin-require">*</span>
  </label>
  <p class="kintoneplugin-desc">Please select a Number field</p>
  <div class="kintoneplugin-select-outer">
    <div class="kintoneplugin-select">
      <select id="select_count_field" name="js-select_count_field" required>
        <option value="">-----</option>
      </select>
    </div>
  </div>
</div>

Both drop-down fields in the blocks have ids allocated to them, so that they can be targeted and populated by the config.js file.

51-modern-default.css (External link)

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.

config.css (External link)

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

config.js (External link)

This file uses the native Kintone JavaScript API method kintone.app.getFormFields().
The function setDropDown is called when the plug-in config page loads.

1
setDropDown();

This function calls the kintone.app.getFormFields() method, which returns an object containing the field information of all fields in the App form.
If the field information cannot be retrieved, the error is handled in the catch() block.

1
2
3
4
5
return kintone.app.getFormFields().then((resp) => {
  // ...
}).catch((err) => {
  return alert('Failed to retrieve field information');
});

The returned object is iterated over to create lists of Text Area fields and Number fields, and are appended to the drop-down stored in $selectBody and $selectCount respectively.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
for (const key in resp) {
  if (!resp.hasOwnProperty(key)) {
    continue;
  }
  const respField = resp[key];
  const $option = $('<option>');
  switch (respField.type) {
    case 'MULTI_LINE_TEXT':
      $option.attr('value', respField.code);
      $option.text(escapeHtml(respField.label));
      $selectBody.append($option.clone());
      break;
    case 'NUMBER':
      $option.attr('value', respField.code);
      $option.text(escapeHtml(respField.label));
      $selectCount.append($option.clone());
      break;
    default:
      break;
  }
}

At the end of the setDropDown function, the code checks 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 saved any settings before in the plug-in (which are stored using Kintone's setConfig API ), then those saved values (the specified Text Area field and Number field) are inserted into the designated plug-in settings.

1
2
3
// Set default values
$selectBody.val(CONF.body);
$selectCount.val(CONF.count);

desktop.js (External link)

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 Count Characters Inside Fields 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 the configuration data that was saved in the plug-in settings page using the setConfig API .

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

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

1
2
const CONFIG_BODY = CONFIG.body;
const CONFIG_COUNT = CONFIG.count;

These variables are used when the app.record.create.submit , app.record.edit.submit or app.record.index.edit.submit events (events triggered when records are saved) are triggered to specify the related properties within the event object.
Overwriting values within the event object and returning the object results in specific fields of the App record to be overwritten - in this case, the Number field is overwritten with new data.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
kintone.events.on(['app.record.create.submit', 'app.record.edit.submit', 'app.record.index.edit.submit'],
  function(event) {
    // Obtain characters in the text field
    const rec = event.record;
    const st = rec[CONFIG_BODY].value;

    // If the number of characters is zero, put zero in number field and return
    if (!st) {
      rec[CONFIG_COUNT].value = 0;
      return event;
    }

    // Remove spaces
    const st2 = st.replace(/\s+/g, '');

    // Enter character count into number field
    rec[CONFIG_COUNT].value = st2.length;

    return event;
  });

manifest.json (External link)

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.7.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": [
  "body",
  "count"
]

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": "Character Count Plug-in"
},
"description": {
  "en": "This sample code counts the total number of characters in a Text Area field. Spaces in the Text Area field are excluded from the count. The final count value is set into a Number field."
},
"homepage_url": {
  "en": "https://kintone.dev/en/plugins/simple-samples/character-count-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)