Voog.com

Settings Editor

Edicy.SettingsEditor is a universal tool for returning template's configuration settings as key/value pairs. Returned data can be binded with site, page or article using Custom Data Toolkit.

Saved settings data can be used in layouts by adding state-specific classes, showing/hiding sections etc. See also an example for Binding custom data.

Basic example

Example generates settings popover with radio button type option.

<!DOCTYPE html>
<html>
  <head>
    <!-- Settings popover styles. -->
    {% if editmode %}
      <link rel="stylesheet"
        href="{{ site.static_asset_host }}/libs/edicy-tools/latest/edicy-tools.css"
      >
    {% endif %}
  </head>
  <body>
    <!-- Settings popover toggle button -->
    {% if editmode %}
      <button class="js-settings-btn">Language menu settings</button>
    {% endif %}
    
    {% editorjsblock %}
      <!-- Settings popover javascript. -->
      <script
        src="{{ site.static_asset_host }}/libs/edicy-tools/latest/edicy-tools.js"
      ></script>
      
      <!-- Setings popover initiation. -->
      <script>
        var siteData = new Edicy.CustomData({
          type: 'site'
        });

        {% if site.data.language_menu_options %}
          var valuesObj = {
            menu_style: {{ site.data.language_menu_options | json }}
          };
        {% else %}
          var valuesObj = {};
        {% endif %};

        var settingsBtn = document.querySelector('.js-settings-btn');

        var SettingsEditor = new Edicy.SettingsEditor(settingsBtn, {
          menuItems: [
            {
              "title": "Language menu style", 
              "type": "radio",
              "key": "menu_style",
              "list": [
                {
                  "title": "With flags",
                  "value": "with_flags"
                },
                {
                  "title": "Without flags",
                  "value": "without_flags"
                },
                {
                  "title": "Names only",
                  "value": "names_only"
                }
              ]
            }
          ],

          values: valuesObj,
          
          preview: function(data) {
            var flagsClass;
            if (data.menu_style === 'with_flags') {
              flagsClass = 'lang-menu-flags';
            } else if (data.menu_style === 'without_flags') {
              flagsClass = 'lang-menu-no-flags';
            } else if (data.menu_style === 'names_only') {
              flagsClass = 'lang-menu-names-only';
            }

            document.querySelector('body').classList.add(flagsClass);
          },

          commit: function(data) {
            siteData.set('language_menu_options', data);
          }
        });
      </script>
    {% endeditorjsblock %}
  </body>
</html>

Styles

Settings Editor styles are included in edicy-tools.js toolkit's stylesheet. It should be added into <head> tag.

<link rel="stylesheet" href="{{ site.static_asset_host }}/libs/edicy-tools/latest/edicy-tools.css">

Core

Settings Editor plugin is located in edicy-tools.js toolkit and must be wrapped in {% editorjsblock %}{% endeditorjsblock %}:

{% editorjsblock %}
  <script src='{{ site.static_asset_host }}/libs/edicy-tools/latest/edicy-tools.js'></script>

  <script>
    // Your code here ...
  </script>
{% endeditorjsblock %}

Options

MenuItems (required)

Array of menu item objects that holds data for generating option menu items.

Menu item object

  • title – title of the option.
    • Required
    • Must be a STRING.  
  • type – type of the rendered option.
    • Required
    • Must be a STRING.
    • Possible values:
      • "text"
      • "textarea"
      • "number"
      • "range"
      • "radio"
      • "select"
      • "checkbox"
      • "toggle"
  • key – key for the settable value.
    • Required
    • Must be a STRING
  • tooltip – tooltip of the option.
    • Required
    • Must be a STRING. 
  • states – object with "on" and "off" key/value pairs for "checkbox" & "toggle" type option.
    • Required for "checkbox" & "toggle" type option.
    • Not supported with other type of options.
    • Example:

"states": {
  // Value for checked "checkbox" & "toggle" type option.
  // Can be STRING, NUMBER or BOOLEAN.
  "on": "it is true",
  
  // Value for unchecked "checkbox" & "toggle" type option.
  // Can be STRING, NUMBER or BOOLEAN.
  "off": "it is false"
}

  • list – array of objects containing data about option values and their titles.
    • Required for "select" and "radio" type options.
    • Not supported with other type of options.
    • Example:

"list": [
  {
    // Rendered as selectable option title for user.
    // Must be a STRING
    "title": "Option 1",

    // Settable value
    // Can be STRING, NUMBER or BOOLEAN.
    "value": "option_1_value"
  },
  {
    "title": "Option 2",
    "value": "option_2_value"
  }]

  • class  custom class or classes for the option element.
    • Optional
    • Must be a STRING or an ARRAY of strings.

values (required)

JSON object containing initial key/value pairs for options. In most cases it is an object read from
{{ site.data.__ }} or {{ page.data.__ }} in JSON format:
<script>
  {% if page.data.my_settings %}
    var valuesObj = {{ page.data.my_settings | json }};
  {% else %}
    var valuesObj = {};
  {% endif %};

  var settingsBtn = document.querySelector('.js-settings-btn');

  var SettingsEditor = new Edicy.SettingsEditor(settingsBtn, {
    values: valuesObj
  });
</script>

buttonStyle (optional)

Style setting for toggle button. Possible values:

  • "default" – Uses the same style as other CMS buttons (default value).
  • "none" – Element appears as it is styled in your CSS or as the initial style of the browser.  

buttonTitle (optional)

Settings toggle button title. It overwrites the button element's inner HTML if it is present.

buttonActiveClass (optional)

Class for toggle button active state. .edy-cbtn-active by default.

containerClass (optional)

custom class or classes for settngs editor container element.

  • Must be a STRING or an ARRAY of strings.

preview(data) {} (required)

Function that will be triggered after each option change event. Returns an object containing settings as keys/value pairs.

Function is being triggered if any of the settings is changed or the side-click save confirmation is declined.

In most cases it is used to show changes that option toggles on the page in real time.

commit(data) {} (required)

Function that will be triggered after saving the Settings Editor options. Returns an object containing settings as keys/value pairs.

Function is being triggered when "save" button is clicked or the side-click save confirmation is accepted.

In most cases it is used to save Settings Editor data to {{ site.data.__ }} or {{ page.data.__ }}. Read more about custom data toolkit and binding custom data.

Setting default values

Default values are not saved to custom data by default. The following example will only select default values for the options in the Settings Editor if it is not yet modified (it has to be considered with when using data in the template's code). Default values must be set before initiating the Edicy.SettingsEditor:

{% editorjsblock %}
  <script>
    {% if page.data.my_settings %}
      var valuesObj = {{ page.data.my_settings | json }};
    {% else %}
      var valuesObj = {};
    {% endif %};

    if (!('option_1' in valuesObj)) {
      valuesObj.option_1 = true;
    }

    if (!('option_2' in valuesObj)) {
      valuesObj.option_2 = "option 2 value";
    }

    if (!('option_3' in valuesObj)) {
      valuesObj.option_3 = 600;
    }
  </script>
{% endeditorjsblock %}

Working example with all possible solutions.

Includes saving custom data with custom data toolkit.
<!DOCTYPE html>
<html>
  <head>
    <!-- Settings popover styles. -->
    {% if editmode %}
      <link rel="stylesheet"
        href="{{ site.static_asset_host }}/libs/edicy-tools/latest/edicy-tools.css"
      >
    {% endif %}
  </head>
  
  <body>
    <!-- Settings popover toggle button -->
    {% if editmode %}
      <button class="js-settings-btn"></button>
    {% endif %}

    {% editorjsblock %}
      <!-- Settings editor javascript. -->
      <script
        src='{{ site.static_asset_host }}/libs/edicy-tools/latest/edicy-tools.js'
      ></script>

      <script>
        // Initiate pageData saving function.
        var pageData = new Edicy.CustomData({
            type: "page",
          id: {{ page.id }}
        });

        // Bind data.
        {%if page.data.my_settings %}
          // If page has suitable custom data key, read the data from it.
          var valuesObj = {{ page.data.my_settings | json }};
        {% else %}
          // Else initiate an empty object
          var valuesObj = {};
        {% endif %};

        if (!('text_option' in valuesObj)) {
          valuesObj.text_option = 'text option default value';
        }

        if (!('textarea_option' in valuesObj)) {
          valuesObj.textarea_option = 'textarea option default value';
        }

        if (!('number_option' in valuesObj)) {
          valuesObj.number_option = 10;
        }

        if (!('range_option' in valuesObj)) {
          valuesObj.range_option = 20;
        }

        if (!('radio_option' in valuesObj)) {
          valuesObj.radio_option = 'radio option value 2';
        }

        if (!('select_option' in valuesObj)) {
          valuesObj.select_option = "select option value 3";
        }

        if (!('checkbox_option' in valuesObj)) {
          valuesObj.checkbox_option = 'it is true';
        }

        if (!('toggle_option' in valuesObj)) {
          valuesObj.toggle_option = 'it is true';
        }


        // Bind Settings Editor to a button.
        var settingsBtn = document.querySelector('.js-settings-btn');

        // Configuration for Settings Editor
        var SettingsEditor = new Edicy.SettingsEditor(settingsBtn, {
          menuItems: [
            {
              "title": "The text option",
              "type": "text",
              "key": "text_option",
              "placeholder": "This is the placeholder",
              "class": [
                'text-option-custom-class-1',
                'text-option-custom-class-2'
              ]
            },
            {
              "title": "The textarea option",
              "type": "textarea",
              "key": "textarea_option",
              "placeholder": "This is the placeholder",
              "class": [
                'textarea-option-custom-class-1',
                'textarea-option-custom-class-2'
              ]
            },
            {
              "title": "The number option",
              "type": "number",
              "key": "number_option",
              "placeholder": "This is the placeholder",
              "step": 5,
              "min": -50,
              "max": 50,
              "class": [
                'number-option-custom-class-1',
                'number-option-custom-class-2'
              ]
            },
            {
              "title": "The range option",
              "type": "range",
              "key": "range_option",
              "placeholder": "This is the placeholder",
              "step": 10,
              "min": -100,
              "max": 100,
              "class": [
                'range-option-custom-class-1',
                'range-option-custom-class-2'
              ]
            },
            {
              "title": "The radio option",
              "type": "radio",
              "key": "radio_option",
              "list": [
                {
                  "title": "Radio option 1",
                  "value": "radio option value 1"
                },
                {
                  "title": "Radio option 2",
                  "value": "radio option value 2"
                },
                {
                  "title": "Radio option 3",
                  "value": "radio option value 3"
                }
              ],
              "class": [
                'radio-option-custom-class-1',
                'radio-option-custom-class-2'
              ]
            },
            {
              "title": "The select option",
              "type": "select",
              "key": "select_option",
              "list": [
                {
                  "title": "Select option 1",
                  "value": "select option value 1"
                },
                {
                  "title": "Select option 2",
                  "value": "select option value 2"
                },
                {
                  "title": "Select option 3",
                  "value": "select option value 3"
                }
              ],
              "class": [
                'select-option-custom-class-1',
                'select-option-custom-class-2'
              ]
            },
            {
              "title": "The checkbox option",
              "type": "checkbox",
              "key": "checkbox_option",
              "states": {
                "on": "it is true",
                "off": "it is false"
              },
              "class": [
                'checkbox-option-custom-class-1',
                'checkbox-option-custom-class-2'
              ]
            },
            {
              "title": "The toggle option",
              "type": "toggle",
              "key": "toggle_option",
              "states": {
                "on": "it is true",
                "off": "it is false"
              },
              "class": [
                'toggle-option-custom-class-1',
                'toggle-option-custom-class-2'
              ]
            },
          ],

          // Binded data object which should contain custom data object.
          values: valuesObj,

          // Style type the button.
          buttonStyle: 'default',
          // Title for the button.
          buttonTitle: 'Custom name for the button',
          // Class for the button while Settings Editor is visible.
          buttonActiveClass: 'settings-popover-open',

          // Custom classes for the Settings Editor popover container.
          containerClass: [
            'settings-container-custom-class-1',
            'settings-container-custom-class-2'
          ],

          // Callback function that runs when any of the settings is changed.
          preview: function(data) {
            console.log(data);
            this.setPosition();
          },

          // Callback function that runs when data is commited.
          commit: function(data) {
            console.log(data);
            pageData.set('my_settings', data);
          }

        });
      </script>
    {% endeditorjsblock %}
  </body>
</html>