I've implemented similar sliders that do work on mobile. Rather than using v-on:click
on the slider directly, have you thought about changing the slider into a component, and use v-on:input
on the usage of the component? You could also try it directly on the slider, as v-on:input
/@input
gets triggered when the value in the v-model
changes. Here's a snippet from my own uibuilder code, where I use the sliders specifically for brightness; I've only tested these on iOS, not on android however:
BrightnessSlider.vue:
<template>
<div>
<label :for="id">{{ label }}</label>
<b-form-input :id="id" v-model="localValue" type="range" :min="min" :max="max" debounce="1000" number></b-form-input>
<div class="mt-2" v-show="!is_minimal">Brightness: {{ localValue }}</div>
</div>
</template>
<script>
module.exports = {
name: 'BrightnessSlider',
props: {
value: {
type: Number,
required: true,
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
id: {
type: String,
required: true
},
label: {
type: String,
default: ""
},
is_minimal: {
type: Boolean,
default: false
},
},
computed: {
localValue: {
get() {return this.value},
set(localValue) {this.$emit('input', localValue)}
}
}
}
</script>
CompVerlichting.vue:
<template>
<div id="Verlichting">
<h2>Voorkamer</h2>
<h2>Slaapkamer</h2>
<b-table striped hover :items="lampen.filter(item => item.loc === 'slaapkamer')" :fields="fields" responsive="sm">
<template v-slot:cell(show_details)="row">
<b-button size="sm" @click="row.toggleDetails" class="mr-2">
{{ row.detailsShowing ? 'Hide' : 'Show'}} Details
</b-button>
</template>
<template v-slot:cell(state)="row">
<bootstrap-switch
:id="'switch-on-off-' + row.item.device.id"
v-model="row.value.on"
label="On?"
@change="$root.sendNR('uibuilder/verlichting', {device: row.item.device, state: row.item.state})"
>
</bootstrap-switch>
</template>
<template v-slot:row-details="row">
<b-card>
<b-row class="mb-2" v-if="row.item.has_brightness">
<b-col sm="3" class="text-sm-right">Brightness: </b-col>
<b-col>
<brightness-slider
v-model="row.item.state.brightness"
:min="0"
:max="100"
:id="'brightness-' + row.item.device.id"
:label="row.item.name"
is_minimal
@input="$root.sendNR('uibuilder/verlichting', {device: row.item.device, state: row.item.state})"
>
</brightness-slider>
</b-col>
</b-row>
<b-button size="sm" @click="row.toggleDetails">Hide Details</b-button>
</b-card>
</template>
</b-table>
</div>
</template>
<script>
module.exports = {
name: 'CompVerlichting',
data() {
return {
lampen: [
{
loc: 'voorkamer',
device: {
id: '...',
type: 'zwave'
},
has_brightness: true,
name: 'Plafondlamp',
state: {
on: false,
brightness: 0,
}
},
{
loc: 'slaapkamer',
device: {
id: 'kastverlichting',
type: 'zigbee'
},
has_brightness: true,
name: 'Kastverlichting',
state: {
on: false,
brightness: 0,
}
},
{
loc: 'slaapkamer',
device: {
id: 'nachtlampje',
type: 'zigbee'
},
has_brightness: true,
name: 'Leeslampje bed',
state: {
on: false,
brightness: 0
}
},
],
fields: [
{
key: 'name',
sortable: true,
},
{
key: 'state',
label: 'On/Off'
},
{
key: 'show_details',
}
]
};
},
components: {
'brightness-slider': httpVueLoader('./BrightnessSlider.vue'),
'bootstrap-switch': httpVueLoader('./BootstrapSwitch.vue')
}
};
</script>
Please ignore the rest of this second component, it's a temporary setup that is about (when I can find the time) to be completely overhauled. In here, $root.sendNR
is a method defined on the outermost part of the Vue app, so that I can call it from child components. It takes the format topic, payload.