YouTube embed Plug-in

Contents

Introduction

This article introduces the YouTube embed Plug-in. This plug-in reads the URL of a YouTube video entered into either a Text field or a Link field, and displays the video embedded into a Blank Space field.

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 first have a Text field or Link field, and a Blank Space field in its form.

The first setting on the settings page specifies which Text or Link field will hold the URL of the YouTube video. The second setting specifies which Blank Space field to display the embedded YouTube on. The final setting allows the user to change the width and height of the video. There's also an aspect ratio lock check box to specify whether to keep the ratio consistent, and a button to reset the default dimensions.

Entering a YouTube URL into the Text or Link field and saving the record will display the YouTube video embedded into the Blank Space field.

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
13
plug-in/
├── html/
│       └──── config.html
├── css/
│       ├──── 51-modern-default.css
│       └──── config.css
├── js/
│       ├──── config.js
│       ├──── desktop.js
│       └──── kintone-config-helper.js
├── image/
│       └──── play.png
└── manifest.json

config.html (External link)

This file builds the HTML of the plug-in settings page. Each "kintoneplugin-row" div 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 or Link field to hold the YouTube video URL. A select tag is stated, 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
<div class="kintoneplugin-row">
  <label for="select-link-field" class="kintoneplugin-label">Youtube Link Field
    <span class="kintoneplugin-require">*</span>
  </label>
  <p class="kintoneplugin-desc">Select the field that holds the link to the Youtube video. Can be a Link field (URL) or Text field.</p>
  <div class="kintoneplugin-select-outer">
    <div class="kintoneplugin-select">
      <select name="js-select-link-field" id="select-link-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 the Blank Space field to display the YouTube video on. Again, a select tag is stated, 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
<div class="kintoneplugin-row">
  <label for="select-space-field" class="kintoneplugin-label">Blank Space Field
    <span class="kintoneplugin-require">*</span>
  </label>
  <p class="kintoneplugin-desc">Select a Blank Space field to place the embedded video.</p>
  <div class="kintoneplugin-select-outer">
    <div class="kintoneplugin-select">
      <select name="js-select-space-field" id="select-space-field" required>
        <option value="">-----</option>
      </select>
    </div>
  </div>
</div>

The final "kintoneplugin-row" div contains the HTML of the final settings, where the user can change the display dimensions of the embedded video. A checkbox is placed to enable or disable the aspect ratio lock feature, two text input fields are placed to hold the dimensions, and a button element is placed to allow the user to reset the dimensions back to their defaults.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div class="kintoneplugin-row">
  <label class="kintoneplugin-label">
    Video Dimensions:
  </label>
  <p class="kintoneplugin-desc">Aspect ratio lock (16:9):</p>
  <div class="kintoneplugin-input-checkbox">
    <span class="kintoneplugin-input-checkbox-item">
      <input type="checkbox" name="js-ratio-enabled" value="0" id="ratio-checkbox" checked>
      <label for="ratio-checkbox" class="kintoneplugin-label">Enabled</label> 
    </span>
  </div>
  <p class="kintoneplugin-desc">Insert the desired width of the embedded video in pixels.</p>
  <div class="kintoneplugin-input-outer">
    <input type="text" class="kintoneplugin-input-text" name="js-insert-width" value="560">
  </div>
  <p class="kintoneplugin-desc">Insert the desired height of the embedded video in pixels.</p>
  <div class="kintoneplugin-input-outer">
    <input type="text" class="kintoneplugin-input-text" name="js-insert-height" value="315">
  </div>
  <div>
    <button type="button" id="js-reset-dimensions" class="reset-dimensions">Reset default dimsensions</button>
  </div>
</div>

The Text or Link field select element, the Blank Space field select element, and the aspect ratio lock checkbox element have ids allocated to them, so that they can be controlled by the config.js file.

51-modern-default.css (External link)

The CSS file provided on GitHub (External link) . This file styles HTML elements on the plug-in config page to fit in with Kintone's UI. It is recommended that changes are not made to 51-modern-default.css. If additional elements need to be styled, or default styles need to be over-ridden, 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 is used to populate the drop-down fields on the plug-in config page, and to also save the data inputted by the user. The function setDropDown is called when the plug-in setting page loads.

1
setDropDown();

This function calls the KintoneConfigHelper.getFields method from the kintone-config-helper library. By passing 'SINGLE_LINE_TEXT', 'LINK', 'SPACER' as the parameter, an array of field information of all Text, Link, and Blank Space fields is returned.

1
2
3
KintoneConfigHelper.getFields(['SINGLE_LINE_TEXT', 'LINK', 'SPACER']).then(function(resp) {
  // ...
});

The returned array is used to create lists of Text and Link fields, and Blank Space fields which are appended to the elements with the names js-select-link-field and js-select-space-field respectively, stored in the previously defined variables $link and $space.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var $linkDropDown = $link;
var $spaceDropDown = $space;
resp.forEach(function(respField) {
  var $option = $('<option></option>');
  switch (respField.type) {
    case 'SINGLE_LINE_TEXT':
    case 'LINK':
      $option.attr('value', respField.code);
      $option.text(respField.label);
      $linkDropDown.append($option.clone());
      break;
    case 'SPACER':
      if (!respField.elementId) {
        break;
      }
      $option.attr('value', respField.elementId);
      $option.text(respField.elementId);
      $spaceDropDown.append($option.clone());
      break;
    default:
      break;
  }
});

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. If the user has saved any settings before in the plug-in (which is stored using Kintone's setConfig API), then those saved values (the specified Text or Link field and Blank Space field) are inserted into the designated plug-in settings.

1
2
3
4
5
6
if (CONF.link) {
  $linkDropDown.val(CONF.link);
}
if (CONF.space) {
  $spaceDropDown.val(CONF.space);
}

Next, when the document is ready, the code looks through the CONF object again for any stored values for the width and height fields, as well as the aspect ratio lock check box. The current value of the width and height fields is entered into the settings, and if the value of the checkbox is the string, 'true'. If the value of the checkbox is the string, 'true', the variable checkbox_boolean is given the value TRUE. If the value is not the string, 'true', the variable checkbox_boolean is given the value FALSE. This step is necessary because the CONF field values cannot store boolean values. Then, the checked property is added to the checkbox element if the value of the checkbox_boolean variable is TRUE, and is taken off or not added if the value is FALSE.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
if (CONF.width) {
  $width.val(CONF.width);
}

if (CONF.height) {
  $height.val(CONF.height);
}

if (CONF.checkbox === 'true') {
  checkbox_boolean = true;
} else {
  checkbox_boolean = false;
}

$ratio.prop('checked', checkbox_boolean);

The next part of the code waits for the change event of the width and height input fields, changing the other field value to stay within the 16:9 ratio if the aspect ratio lock checkbox has the checked property. It also assigns the variable checkbox_value either the 'true' or 'false' string value depending on whether the checked property exists in the checkbox element or not.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
$width.on('change', function() {
  if ($ratio.prop('checked')) {
    newWidth = Number($width.val());
    newHeight = newWidth * (9 / 16);
    $height.val(Math.round(newHeight));
    checkbox_value = 'true';
  } else {
    checkbox_value = 'false';
  }
});

$height.on('change', function() {
  if ($ratio.prop('checked')) {
    newHeight = Number($height.val());
    newWidth = newHeight * (16 / 9);
    $width.val(Math.round(newWidth));
    checkbox_value = 'true';
  } else {
    checkbox_value = 'false';
  }
});

Finally, the code waits for the click event of the reset button element, and sets the values of the width and height fields to 560 and 315 respectively.

1
2
3
4
$reset.on('click', function() {
  $width.val(560);
  $height.val(315);
});

desktop.js (External link)

This file runs the regular pages of the App, such as the Record List and Record Details pages, but not on the plug-in config page. The code creates a YouTube iframe element and inputs the YouTube URL from the Text or Link field into the iframe element. The code then uses the getSpaceElement API to retrieve the Blank Space element, and appends the iframe to the element. The code also creates a div that holds an error message, and appends the error message to the Blank Space field instead if the YouTube URL could not be read.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var createYTiframe = function() {
  ytiframe.setAttribute('width', VIDEO_WIDTH);
  ytiframe.setAttribute('height', VIDEO_HEIGHT);
  ytiframe.setAttribute('src', 'https://www.youtube.com/embed/' + videoId);
  ytiframe.setAttribute('frameborder', '0');
  ytiframe.setAttribute('allow', 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture');
  ytiframe.setAttribute('allowfullscreen', 'allowfullscreen');
  kintone.app.record.getSpaceElement(VIDEO_BLANK_SPACE).appendChild(ytiframe);
};
var createNoVideoError = function() {
  var noVideoError = document.createElement('div');
  noVideoError.innerHTML = noVideoErrorFirstHalf + urlExampleFull + '</b><br>or <b>' + urlExampleShort + noVideoErrorSecondHalf;
  kintone.app.record.getSpaceElement(VIDEO_BLANK_SPACE).appendChild(noVideoError);
};
// ...
if (fullUrl.slice(0, 32) === 'https://www.youtube.com/watch?v=') {
  videoId = fullUrl.slice(32);
  createYTiframe();
} else if (fullUrl.slice(0, 17) === 'https://youtu.be/') {
  videoId = fullUrl.slice(17);
  createYTiframe();
} else {
  createNoVideoError();
}

This code is 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 settings 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
5
6
var VIDEO_LINK, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_BLANK_SPACE;
// ...
VIDEO_LINK = CONFIG.link;
VIDEO_WIDTH = CONFIG.width;
VIDEO_HEIGHT = CONFIG.height;
VIDEO_BLANK_SPACE = CONFIG.space;

These variables are used to identify the correct property of the event object when the record details page loads (when the app.record.detail.show event triggers).

1
2
3
var fullUrl;
// ...
fullUrl = event.record[VIDEO_LINK].value;

kintone-config-helper.js (External link)

The kintone-config-helper.js file is a library that supports the development of the plug-in config page. View the Introduction to Kintone Config Helper article for more details.

manifest.json (External link)

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

1
2
3
4
5
6
7
8
"config": {
  "html": "html/config.html",
  "js": [
    "https://js.kintone.com/jquery/3.3.1/jquery.min.js",
    "js/kintone-config-helper.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": [
  "link",
  "space"
]

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": "Youtube Embed Plug-in"
},
"description": {
  "en": "This plug-in embeds a Youtube video specified by its link into a Blank Space field in the record details."
},
"homepage_url": {
  "en": "https://kintone.dev/en/plugins/simple-samples/you-tube-embed-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) .