Conditional Record Count Plug-in

Contents

Introduction

This article introduces the Conditional Record Count Plug-in, which is a plug-in version of the sample code introduced in the " Display the Total Records that Contain a Specific Value " article.
This plug-in counts the total number of records that have Drop-down fields that hold specific values, and displays the total count in the header of the Record List. The query of the record list is also taken into account when counting the number of records.

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 Drop-down field in its form.

There are two settings for this plug-in.
For the first setting, select a field from the drop-down list that stores the conditional value.
This sample allows only the Drop-down field to be populated in the drop-down list.
For the second setting, select a value that the field in the first setting may hold.

When the plug-in runs, the plug-in will count the number of records where the field selected in the first setting stores the value selected in the second setting. The name of the selected value and the total number of records will be displayed in the header of the record list in the format of: {Selected value} : {total count}

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

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 Drop-down field holds the conditional value. 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_dropdown_field" class="kintoneplugin-label">
    Field with Conditional Value
    <span class="kintoneplugin-require">*</span>
  </label>
  <p class="kintoneplugin-desc">Please select a drop-down field that stores the conditional value.</p>
  <div class="kintoneplugin-select-outer">
    <div class="kintoneplugin-select">
      <select name="js-select_dropdown_field" id="select_dropdown_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 value will be the condition for records to be counted. 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, and the populated content will change depending on what Drop-down field was selected in the first "block".

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<div class="kintoneplugin-row">
  <label for="" class="kintoneplugin-label">
    Conditional Value
    <span class="kintoneplugin-require">*</span>
  </label>
  <p class="kintoneplugin-desc">
    Please select a value that exists in the drop-down selected in the previous setting.<br />
    The number of records that hold this value will be counted by the plug-in.<br />
    The total count will be displayed in the header of the record list.
  </p>
  <div class="kintoneplugin-input-outer">
    <div class="kintoneplugin-select">
      <select name="js-select_dropdown_value" id="select_dropdown_value" 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.

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. The results obtained by this function are then passed on to the next function setDropdownValue.

1
2
3
// Set drop-down list
setDropDown()
  .then(setDropdownValue);

The setDropDown function 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');
  });
}

As this plug-in needs to use the Drop-down fields to populate the drop-down fields in the first settings, the fields with type value of DROP_DOWN (the Drop-down field) are extracted from the returned object. The extracted selections are then appended to the element with the id of js-select_dropdown_field (stored in the $selectDropdown variable) to create a drop-down list of Drop-down fields in the App.
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 Drop-down field) are inserted into the designated plug-in configuration settings.

1
2
// Set default values
$selectDropdown.val(CONF.dropdown_field);

The following function, setDropdownValue, is used to populate the drop-down of the second settings.

1
2
3
4
5
function setDropdownValue() { // Set drop-down values based on drop-down selected.
  // ...
  // rest of the function
  // ...
}

It first checks the value of the first settings.
If it's the first time for the settings to be used, or if "-----" is selected, the value of the first setting will be "" (an empty string). If the user has previously used the plug-in, and has selected a value for the first setting, then that value will be retrieved.
There are rare cases though, where users would select a value, then proceed to delete the field in their App form settings. In this case, a null value is obtained, and no more codes are processed in this setDropdownValue function (the drop-down selection of the second settings will be left empty).

1
2
3
4
var dropdown_field = $selectDropdown.val();
if (!dropdown_field) {
  return; // Return if the first drop-down is not yet selected.
}

If values exist, the drop-down list is cleared using jQuery's empty() (External link) method, and repopulated with drop-down values that are inside the DROPDOWN_VALUES object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$selectDropdownValue.empty();
opt = DROPDOWN_VALUES[dropdown_field];
Object.keys(opt).forEach(function(key) {
  var prop = opt[key];
  var $option = $('<option>');

  $option.attr('value', prop.label);
  $option.text(escapeHtml(prop.label));
  $selectDropdownValue.append($option.clone());
});

At the end of the setDropdownValue function, if plug-in configuration settings were previously saved by the user, these values are extracted from the CONF object and applied to the second drop-down settings. If not, the first value of the drop-down is selected.

1
2
3
4
5
// Set default values
$selectDropdownValue.val(CONF.dropdown_choice);
if ($selectDropdownValue.val() === null) { // Set first option if no value is selected.
  $('select[name="js-select_dropdown_value"] option:first').attr('selected', 'selected');
}

When the user hits the save button on the plug-in config page, the values in the first and second settings are stored into Kintone using the setConfig API .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$form.on('submit', function(e) {
  var config = [];
  var dropdown_field = $selectDropdown.val();
  var dropdown_choice = $selectDropdownValue.val();
  e.preventDefault();
  config.dropdown_field = dropdown_field;
  config.dropdown_choice = dropdown_choice;
  kintone.plugin.app.setConfig(config, function() {
    alert('The plug-in settings have been saved. Please update the app!');
    window.location.href = '/k/admin/app/flow?app=' + kintone.app.getId();
  });
});

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 " Display the Total Records that Contain a Specific Value " 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
DROPDOWN = CONFIG.dropdown_field; // Field code of drop-down field
DROPDOWN_CHOICE1 = CONFIG.dropdown_choice; // Name of drop-down choice

These variables are used in the app.record.index.show event, which is triggered when the Record List page loads.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// Record List Event
kintone.events.on('app.record.index.show', function(event) {
  // Gets records based on the current filter of the list
  var query = kintone.app.getQueryCondition();
  if (query === '') {
    query += ' ' + DROPDOWN + ' in ("' + DROPDOWN_CHOICE1 + '")';
  } else {
    query += ' and ' + DROPDOWN + ' in ("' + DROPDOWN_CHOICE1 + '")';
  }
  kintone.api('/k/v1/records', 'GET', {
    app: kintone.app.getId(),
    query: query,
    totalCount: true
  }, function(resp) {
    kintone.app.getHeaderMenuSpaceElement().innerHTML = escapeHtml(DROPDOWN_CHOICE1) + ':' + resp.totalCount;
  });
});

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": [
  "dropdown_field",
  "dropdown_choice"
]

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": "Conditional Record Count Plug-in"
},
"description": {
  "en": "This sample plug-in calculates the total number of records with a given value, and displays the total at the top of the record list page."
},
"homepage_url": {
  "en": "https://kintone.dev/en/plugins/simple-samples/conditional-record-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)