Skip to content

Commit

Permalink
Merge pull request #1492 from cgjgh/Slider-Text-Field
Browse files Browse the repository at this point in the history
Slider text field
  • Loading branch information
joepavitt authored Dec 4, 2024
2 parents 5a3ac99 + f75931b commit e477c5d
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 20 deletions.
144 changes: 144 additions & 0 deletions cypress/fixtures/flows/dashboard-slider.json
Original file line number Diff line number Diff line change
Expand Up @@ -329,5 +329,149 @@
"dashboard-ui-slider"
]
]
},
{
"id": "dashboard-ui-button-dynamic-textfield",
"type": "ui-button",
"z": "node-red-tab-slider",
"group": "dashboard-ui-group",
"name": "Show Text Field",
"label": "Show Text Field",
"order": 0,
"width": 0,
"height": 0,
"emulateClick": false,
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"iconPosition": "left",
"payload": "",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"buttonColor": "",
"textColor": "",
"iconColor": "",
"enableClick": true,
"enablePointerdown": false,
"pointerdownPayload": "",
"pointerdownPayloadType": "str",
"enablePointerup": false,
"pointerupPayload": "",
"pointerupPayloadType": "str",
"x": 180,
"y": 280,
"wires": [
[
"dashboard-ui-set-property-textfield"
]
]
},
{
"id": "dashboard-ui-set-property-textfield",
"type": "change",
"z": "node-red-tab-slider",
"name": "",
"rules": [
{
"t": "delete",
"p": "payload",
"pt": "msg"
},
{
"t": "delete",
"p": "topic",
"pt": "msg"
},
{
"t": "set",
"p": "ui_update.showTextField",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 380,
"y": 280,
"wires": [
[
"dashboard-ui-slider"
]
]
},
{
"id": "dashboard-ui-set-property-step",
"type": "change",
"z": "node-red-tab-slider",
"name": "",
"rules": [
{
"t": "delete",
"p": "payload",
"pt": "msg"
},
{
"t": "delete",
"p": "topic",
"pt": "msg"
},
{
"t": "set",
"p": "msg.ui_update.step",
"pt": "msg",
"to": "2",
"tot": "num"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 380,
"y": 320,
"wires": [["dashboard-ui-slider"]]
},
{
"id": "dashboard-ui-button-dynamic-step",
"type": "ui-button",
"z": "node-red-tab-slider",
"group": "dashboard-ui-group",
"name": "Set Step",
"label": "Set Step",
"order": 0,
"width": 0,
"height": 0,
"emulateClick": false,
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"iconPosition": "left",
"payload": "",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"buttonColor": "",
"textColor": "",
"iconColor": "",
"enableClick": true,
"enablePointerdown": false,
"pointerdownPayload": "",
"pointerdownPayloadType": "str",
"enablePointerup": false,
"pointerupPayload": "",
"pointerupPayloadType": "str",
"x": 160,
"y": 320,
"wires": [["dashboard-ui-set-property-step"]]
}
]
59 changes: 59 additions & 0 deletions cypress/tests/widgets/slider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,63 @@ describe('Node-RED Dashboard 2.0 - Slider (Dynamic Properties)', () => {
// check the min value is updated
cy.get('#nrdb-ui-widget-dashboard-ui-slider').find('.v-slider-thumb').should('have.attr', 'aria-valuemax', '50')
})
it('include "showTextField"', () => {
// First, check that the text field does not exist
cy.get('#nrdb-ui-widget-dashboard-ui-slider').within(() => { cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').should('not.exist') })
cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-button-dynamic-textfield'))
// Check if the text field is present when showTextField is true
cy.get('#nrdb-ui-widget-dashboard-ui-slider').within(() => { cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').should('exist') })
})
})

describe('Node-RED Dashboard 2.0 - Slider (Text Field Input)', () => {
beforeEach(() => {
cy.deployFixture('dashboard-slider')
cy.visit('/dashboard/page1')
})

it('text field emits a value on blur', () => {
cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field'), 200)
// then we can type into the input
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').type('{selectall}{del}40')
cy.focused().blur()
cy.checkOutput('msg.payload', 40)
})

it('text field validation for max value', () => {
// Extract the max value from the slider thumb and store it in a variable
// eslint-disable-next-line promise/always-return, promise/catch-or-return
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').invoke('attr', 'max').then((maxValue) => {
const greaterThanMaxValue = parseInt(maxValue) + 10
cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field'), 200)
// then we can type into the input
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').type(`{selectall}{del}${greaterThanMaxValue}`)
cy.focused().blur()
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').should('have.value', maxValue)
})
})
it('text field validation for min value', () => {
// Extract the min value from the slider thumb and store it in a variable
// eslint-disable-next-line promise/catch-or-return, promise/always-return
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').invoke('attr', 'min').then((minValue) => {
const lessThanMinValue = parseInt(minValue) - 20
cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field'), 200)
// then we can type into the input
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').type(`{selectall}{del}${lessThanMinValue}`)
cy.focused().blur()
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').should('have.value', minValue)
})
})

it('text field rounds input to nearest step', () => {
// eslint-disable-next-line promise/catch-or-return, promise/always-return

cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-button-dynamic-step'))

cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field'), 200)
// then we can type into the input
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').type('{selectall}{del}27')
cy.focused().blur()
cy.get('#nrdb-ui-widget-dashboard-ui-slider-text-field').should('have.value', 28)
})
})
3 changes: 3 additions & 0 deletions docs/nodes/widgets/ui-slider.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ dynamic:
Class:
payload: msg.ui_update.class
structure: ["String"]
Show Text Field:
payload: msg.ui_update.showTextField
structure: ["true | false"]
---

<script setup>
Expand Down
6 changes: 6 additions & 0 deletions nodes/widgets/locales/en-US/ui_slider.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ <h3>Properties</h3>
Add <a href="https://pictogrammers.com/library/mdi/">mdi icon</a> before and after the slider.
For example, "minus". There is no need to include the "mdi-" prefix, just the name of the icon.
</dd>
<dt>Show Text Field <span class="property-type">true | false</span></dt>
<dd>Defined when text field will be visible next to slider. Defaults to 'false'.</dd>
</dl>
<h3>Dynamic Properties (Inputs)</h3>
<p>Any of the following can be appended to a <code>msg.ui_update.</code> in order to override or set properties on this node at runtime.</p>
Expand Down Expand Up @@ -81,4 +83,8 @@ <h3>Dynamic Properties (Inputs)</h3>
<dt class="optional">class <span class="property-type">string</span></dt>
<dd>Add a CSS class, or more, to the Button at runtime.</dd>
</dl>
<dl class="message-properties">
<dt class="optional">showTextField <span class="property-type">true | false</span></dt>
<dd>Show text field next to slider.</dd>
</dl>
</script>
22 changes: 22 additions & 0 deletions nodes/widgets/locales/en-US/ui_slider.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"ui-slider": {
"label": {
"name": "Name",
"group": "Group",
"size": "Size",
"class": "Class",
"label": "Label",
"thumb": "Thumb",
"ticks": "Ticks",
"range": "Range",
"min": "min.",
"max": "max.",
"step": "step",
"icons": "Icons",
"color": "Color",
"outputs": "Output",
"show": "Show",
"textField": "Text Field"
}
}
}
20 changes: 16 additions & 4 deletions nodes/widgets/ui_slider.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
iconAppend: { value: '' },
color: { value: '' },
colorTrack: { value: '' },
colorThumb: { value: '' }
colorThumb: { value: '' },
showTextField: { value: false }
},
inputs: 1,
outputs: 1,
Expand Down Expand Up @@ -86,6 +87,12 @@
$('#node-input-showTicks').val('false')
}

// handle no value for showTextField (from sliders created before this was a value)
if (!this.showTextField) {
this.showTextField = false
$('#node-input-showTextField').val(false)
}

// use jQuery UI tooltip to convert the plain old title attribute to a nice tooltip
$('.ui-node-popover-title').tooltip({
show: {
Expand Down Expand Up @@ -144,19 +151,24 @@
</div>
</div>
<div class="form-row">
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
<label for="node-input-label"><i class="fa fa-font"></i> Label</label>
<input type="text" id="node-input-label">
</div>
<div class="form-row form-row-flex" style="align-items: center;">
<label for="node-input-label"><i class="fa fa-i-cursor"></i> <span data-i18n="ui-slider.label.textField"></span></label>
<input style="width:20px;" type="checkbox" id="node-input-showTextField">
<label style="width:auto" for="node-input-showTextField"><span data-i18n="ui-slider.label.show"></span></label>
</div>
<div class="form-row">
<label for="node-input-thumbLabel"><i class="fa fa-i-cursor"></i> Thumb</label>
<label for="node-input-thumbLabel"><i class="fa fa-map-marker"></i> Thumb</label>
<select id="node-input-thumbLabel">
<option value="false">Never</option>
<option value="true">On Drag</option>
<option value="always">Always</option>
</select>
</div>
<div class="form-row">
<label for="node-input-showTicks"><i class="fa fa-i-cursor"></i> Ticks</label>
<label for="node-input-showTicks"><i class="fa fa-reorder fa-rotate-90"></i> Ticks</label>
<select id="node-input-showTicks">
<option value="false">Never</option>
<option value="true">On Drag</option>
Expand Down
3 changes: 3 additions & 0 deletions nodes/widgets/ui_slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ module.exports = function (RED) {
if (typeof (updates.colorThumb) !== 'undefined') {
statestore.set(group.getBase(), node, msg, 'colorThumb', updates.colorThumb)
}
if (typeof (updates.showTextField) !== 'undefined') {
statestore.set(group.getBase(), node, msg, 'showTextField', updates.showTextField)
}
}
return msg
}
Expand Down
Loading

0 comments on commit e477c5d

Please sign in to comment.