Search code examples
jekyllnetlifynetlify-cms

How to make Netlify CMS' list widget returns number


I want to use Netlify CMS for my Jekyll site and I have this layout:

{% for skills in page.skills %}
    <div class="guide-skill">
        <div class="guide-skill-fill">
            {% for i in (1..15) %}
            <div class="{% if skills.levels contains i %}fill{% endif %} skill-check"><p>{{ i }}</p></div>
            {% endfor %}
        </div>
    </div>
{% endfor %}

and the front matter of page that I write in text editor that uses this layout :

skills:
  - levels:
      - 1

the code works fine, the fill class is added properly.

But when I use Netlify CMS with list widget, it returns string instead of number to the levels list, like this :

skills:
  - levels:
      - '1'

So the code doesn't work, how to make it returns number?

What I've tried

  • Quote the i, but it gave me an error
  • Use valueType : "int", didn't work

My config

- label: "Hero Skills"
  name: "skills"
  widget: "list"
  required: false
  fields:
      - {label: "Skill Number", name: "number", widget: "number"}
      - {label: "Levels", name: "levels", widget: "list"}

Solution

  • None of the built in widgets can output a list of numbers (that aren't strings), but you could always use a custom widget when the built in widgets don't work. Custom widgets are React components, and we publish global hooks (createClass, h) for those not using a module system. More in the docs: https://www.netlifycms.org/docs/custom-widgets/#registerwidget

    For your particular case, you can modify the Categories widget from the docs example to only deal with numbers and output them as well. Add this at the end of the body tag in your index.html file for Netlify CMS:

    <script>
      var NumberListControl = createClass({
        handleChange: function(e) {
          var value = e.target.value.replace(/[^0-9, ]/, '');
          this.props.onChange(value.split(',').map(function(val) {
            var trimmed = val.trim();
            return trimmed ? parseInt(trimmed, 10) : trimmed;
          }));
        },
    
        render: function() {
          var value = this.props.value;
          return h('input', {
            type: 'text',
            value: value ? value.join(', ') : '',
            onChange: this.handleChange,
            className: this.props.classNameWrapper,
          });
        }
      });
    
      var NumberListPreview = createClass({
        render: function() {
          return h('ul', {},
            this.props.value.map(function(val, index) {
              return h('li', {key: index}, val);
            })
          );
        }
      });
    
      CMS.registerWidget('number_list', NumberListControl, NumberListPreview);
    </script>