# Custom button for editableList

**URL:** <https://discourse.nodered.org/t/custom-button-for-editablelist/41342>\
**Category:** Feature Requests\
**Created:** [20 February 2021 10:20 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342 "2021-02-20T10:20:28Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [20 February 2021 10:20 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/1 "2021-02-20T10:20:28Z")

</div>

Hi folks,

I'm looking for a way to add _ **custom buttons** _ to an editableList:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/9/c920653b277bdae5a72663830455412b5ddc5b90.png)

Thought first that this would be possible via the [addButton](https://nodered.org/docs/api/ui/editableList/#options-addButton) function of the editableList, but that seems to be about the _"Add"_ button...

It would be nice if the editableList would allow us to do something like this:

```auto
myEditableList.addCustomButton("myButtonLabel", function () {
   // Do my stuff
});

```

And that this `addCustomButton` function will append the button after the other buttons, similar to this how it works [now](https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/editor-client/src/js/ui/common/editableList.js#L81):

```auto
$('<a href="#" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px;"><i class="fa fa-plus"></i> '+addLabel+'</a>')
   .appendTo(this.topContainer)
   .on("click", function(evt) {
      evt.preventDefault();
      that.addItem({});
   });

```

Would be nice to know whether it is ok for me to create a _ **pull request** _.  
And of course all tips are welcome (e.g. what would need to be the input parameters of the callback function, and so on ...).

Thanks and have a nice weekend!  
Bart

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [21 February 2021 07:57 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/2 "2021-02-21T07:57:46Z")

</div>

It seems that only a small change is required in the editableList , to support custom buttons:

- I have added a _ **right margin** _ of 5px to the "Add" button:

```auto
$('<a href="#" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px; margin-right: 5px;"><i class="fa fa-plus"></i> '+addLabel+'</a>')

```

- And a new _ **function** _ to create a custom button:

```auto
addCustomButton: function(buttonLabel, callback) {
   var label = buttonLabel || "unknown";
   $('<a href="#" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px; margin-right: 5px;">'+label+'</a>')
      .appendTo(this.topContainer)
      .on("click", function(evt) {
         evt.preventDefault();
         if (callback !== undefined) {
            callback();
         }
      });
}

```

That way I can easily add a custom button like this:

```auto
$("ol.list").editableList("addCustomButton", "<i class='fa fa-warning'></i> alert", function() {
   alert("button pressed");
})

```

Which results in a working custom button:

 ![editableList_button_demo](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/9/1957db3c0b8d21200a7e983988d928d5baa9551a.gif)

@dceejay, @knolleary: is this good enough for a pull request?

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [21 February 2021 10:56 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/3 "2021-02-21T10:56:10Z")

</div>

Hi Bart,

I think it would be better to do it as part of the initialisation of the list. I don't see this being something that needs to happen dynamically.

To be somewhat consist with other ui components, I'd suggest a `buttons` array:

```auto
$("#foo").editableList({ 
   ...
   buttons: [
       {
          label: "button Label",
          icon: "" // optional "fa fa-star",
          click: function(evt) { ...}
      }
   ]
});

```

`addButton` would still work in the same way it does today and would be an implicit first entry in the buttons array unless `addButton` is set to `false`.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [21 February 2021 21:15 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/4 "2021-02-21T21:15:54Z")

</div>

> [@knolleary](#):
>
> it would be better to do it as part of the initialisation of the list. I don't see this being something that needs to happen dynamically

Thanks Nick!  
Indeed via the initialisation options will be sufficient. So I have changed it to this:

```auto
            var buttons = this.options.buttons || [];

            if (this.options.addButton !== false) {
                var addLabel;
                if (typeof this.options.addButton === 'string') {
                    addLabel = this.options.addButton
                } else {
                    if (RED && RED._) {
                        addLabel = RED._("editableList.add");
                    } else {
                        addLabel = 'add';
                    }
                }
                buttons.unshift({
                    label: addLabel,
                    icon: "fa fa-plus",
                    click: function(evt) {
                        that.addItem({});
                    }
                });
            }

            buttons.forEach(function(button) {
                var innerHtml = "";
                if (button.icon) {
                    innerHtml = '<i class="'+button.icon+'"></i> ';
                }
                if (button.label) {
                    innerHtml += button.label;
                }
                $('<a href="#" class="red-ui-button red-ui-button-small red-ui-editableList-addButton" style="margin-top: 4px; margin-right: 5px;">'+innerHtml+'</a>')
                    .appendTo(that.topContainer)
                    .on("click", function(evt) {
                        evt.preventDefault();
                        if (button.click !== undefined) {
                            button.click();
                        }
                    });
            });

```

The `addButton` will insert the "Add" button to the start of the button array.

Now I can do it like you suggested:

```auto
var clickableShapesList = $("ol.list").editableList({
   addItem: function(container, i, clickableShape) {
      //...
   },
   removable: true,
   sortable: true,
   buttons: [{
      label: "with icon",
      icon: "fa fa-star",
      click: function(evt) { 
         alert("with icon");
      }
   },
   {
      label: "without icon",
      click: function(evt) { 
         alert("without icon");
      }
   }]
});

```

Which results in this:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/4/e4cca2519cf746777b12c2d66de7f72c4e16c6b4.png)

Hope you like this...

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [21 February 2021 21:18 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/5 "2021-02-21T21:18:53Z")

</div>

Once the external API is agreed, it's far easier to review an implementation in a PR then in a forum post. So go ahead and we can continue the discussion there.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [21 February 2021 21:29 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/6 "2021-02-21T21:29:59Z")

</div>

Bart, please consider supporting a `title` property (for tooltips) while you're in there 🙏

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [21 February 2021 22:38 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/7 "2021-02-21T22:38:40Z")

</div>

I created a [pull-request](https://github.com/node-red/node-red/pull/2881) (inclusive the "_title_" property) and a second [pull-request](https://github.com/node-red/node-red.github.io/pull/205) to update the editableList documentation.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [22 April 2021 22:39 UTC](https://discourse.nodered.org/t/custom-button-for-editablelist/41342/8 "2021-04-22T22:39:21Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
