Repository: holoviz/panel

Issue:
Make editable sliders name parameter editable (from python)
Editable sliders are a very nice addition to panel components and can advantageously replace conventional sliders in most cases in my opinion. However there is a difference currently with respect to the name parameter, which is constant in editable sliders while it is not in conventional sliders.

As in my app I use sliders which have their name changed programmatically, I would like to know if editable sliders could be modified so that the name parameter is no longer constant? In general I think it's best to make editable sliders behave identically to their non-editable counterparts as far as practicable.


Discussion:
Hi @TheoMathurin.  Could you provide a small, reproducible code example? That would make it easier to reproduce, explore, fix and release. Thanks.

And for me to probably show you a temporary workaround :-)
Hi @MarcSkovMadsen 

Sure
```python
import panel.widgets as pnw

slider = pnw.EditableFloatSlider(name='name1')
slider.param.set_param(name='name2')
```

Thanks in advance
I tried to find a workaround but it errors

```python
import param
import panel.widgets as pnw
import panel as pn

pn.extension()

slider = pnw.EditableFloatSlider(name='name1')

with param.edit_constant(slider):
    slider.name='name3'

slider
```

```bash
TypeError: Constant parameter 'name' cannot be modified
```
That is the same error you get when trying to modify it directly.
The work around is :
`slider._label.param.set_param(**{'margin': (0,10,0,0), 'value': "name3"})`
It works, thanks @xavArtley!
```python
try:
    slider.name =  "name3"
except TypeError:
    pass
```
also works. This is because the name of the widget is actually being correctly set in the first place (under the hood the value of a `StaticText` widget is set). However, the code currently sets the name of the `Column` param that wraps the `StaticText` and the slider. The `name` of any param can be set but not edited, which is what raises the error.

Resolving patch:
diff --git a/panel/widgets/base.py b/panel/widgets/base.py
--- a/panel/widgets/base.py
+++ b/panel/widgets/base.py
@@ -130,13 +130,14 @@ class CompositeWidget(Widget):
 
     def __init__(self, **params):
         super().__init__(**params)
-        layout = {p: getattr(self, p) for p in Layoutable.param
+        layout_params = [p for p in Layoutable.param if p != 'name']
+        layout = {p: getattr(self, p) for p in layout_params
                   if getattr(self, p) is not None}
         if layout.get('width', self.width) is None and not 'sizing_mode' in layout:
             layout['sizing_mode'] = 'stretch_width'
         self._composite = self._composite_type(**layout)
         self._models = self._composite._models
-        self.param.watch(self._update_layout_params, list(Layoutable.param))
+        self.param.watch(self._update_layout_params, layout_params)
 
     def _update_layout_params(self, *events):
         updates = {event.name: event.new for event in events}


Test patch:
diff --git a/panel/tests/widgets/test_slider.py b/panel/tests/widgets/test_slider.py
--- a/panel/tests/widgets/test_slider.py
+++ b/panel/tests/widgets/test_slider.py
@@ -1,11 +1,14 @@
 from datetime import datetime, date
 from collections import OrderedDict
 
-from bokeh.models import Div as BkDiv, Slider as BkSlider, Column as BkColumn
+from bokeh.models import (
+    Div as BkDiv, Slider as BkSlider, Column as BkColumn, Row as BkRow)
+import pytest
 
 from panel import config
 from panel.widgets import (DateSlider, DateRangeSlider, DiscreteSlider,
-                           FloatSlider, IntSlider, RangeSlider)
+                           FloatSlider, IntSlider, RangeSlider,
+                           EditableFloatSlider, EditableIntSlider, StaticText)
 
 
 def test_float_slider(document, comm):
@@ -314,3 +317,65 @@ def test_discrete_slider_options_dict(document, comm):
 
         discrete_slider.value = options['1']
         assert widget.value == 1
+
+
+@pytest.mark.parametrize(
+    'editableslider,start,end,step,val1,val2,val3',
+    [
+        (EditableFloatSlider, 0.1, 0.5, 0.1, 0.4, 0.2, 0.5),
+        (EditableIntSlider, 1, 5, 1, 4, 2, 5)
+    ],
+    ids=["EditableFloatSlider", "EditableIntSlider"]
+)
+def test_editable_float_slider(document, comm,
+    editableslider, start, end, step, val1, val2, val3):
+
+    slider = editableslider(start=start, end=end, value=val1, name='Slider')
+
+    widget = slider.get_root(document, comm=comm)
+
+    assert isinstance(widget, BkColumn)
+
+    col_items = widget.children
+
+    assert len(col_items) == 2
+
+    row, slider_widget = col_items
+
+    assert isinstance(slider_widget, editableslider._slider_widget._widget_type)
+    assert slider_widget.title == ''
+    assert slider_widget.step == step
+    assert slider_widget.start == start
+    assert slider_widget.end == end
+    assert slider_widget.value == val1
+    
+    assert isinstance(row, BkRow)
+
+    static_widget, input_widget = row.children
+
+    assert isinstance(static_widget, StaticText._widget_type)
+    assert static_widget.text == 'Slider:'
+
+    assert isinstance(input_widget, editableslider._input_widget._widget_type)
+    assert input_widget.title == ''
+    assert input_widget.step == step
+    assert input_widget.value == val1
+
+    slider._process_events({'value': val2})
+    assert slider.value == input_widget.value == slider_widget.value == val2
+    slider._process_events({'value_throttled': val2})
+    assert slider.value_throttled == val2
+
+    # Testing throttled mode
+    with config.set(throttled=True):
+        slider._process_events({'value': val1})
+        assert slider.value == val2 # no change
+        slider._process_events({'value_throttled': val1})
+        assert slider.value == val1
+
+        slider.value = val3
+        assert input_widget.value == slider_widget.value == val3
+
+    slider.name = 'New Slider'
+
+    assert static_widget.text == 'New Slider:'