Leaflet.EasyButton
Leaflet.EasyButton copied to clipboard
Change button state icon at runtime
Hi! I have a button with 3 states and want to refresh the 3rd state's icon with the count of features retrieved from backend. So far I've tried updating the button.option.state[2].icon in a watcher, but... although the components option have been changed, the button itself doesn't refresh.
Any tips on how to force that refresh?
const _this = this
this.searchInArea = this.$leaflet.easyButton({
states: [{
stateName: 'search',
icon: `<i class="mdi mdi-map-search search-in-zone-btn text-primary">${this.$t('searchInZone')}</i>`,
title: _this.$t('searchInZone'),
onClick: (btn, map) => {
btn.state('loading')
_this.loadFeatures()
.then(() => {
btn.state('loaded')
})
}
}, {
stateName: 'loading',
icon: `<i class="search-in-zone-btn mdi mdi-loading mdi-spin">${this.$t('loading')}</i>`
}, {
stateName: 'loaded',
icon: `<i class="search-in-zone-btn">Showing ${_this.layerFeatures.length} features</i>`
}]
})
(....)
watch: {
layerFeatures() {
if (this.layerFeatures) {
this.searchInArea.options.states.find(st => st.stateName === 'loaded').icon = `<i class="search-in-zone-btn">Showing ${this.layerFeatures.length} features</i>`
}
}
}
I'd probably create an empty div
for the third state and update it as you would with any other dom element
const _this = this
this.searchInArea = this.$leaflet.easyButton({
states: [{
stateName: 'search',
icon: `<i class="mdi mdi-map-search search-in-zone-btn text-primary">${this.$t('searchInZone')}</i>`,
title: _this.$t('searchInZone'),
onClick: (btn, map) => {
btn.state('loading')
_this.loadFeatures()
.then(() => {
btn.state('loaded')
})
}
}, {
stateName: 'loading',
icon: `<i class="search-in-zone-btn mdi mdi-loading mdi-spin">${this.$t('loading')}</i>`
}, {
stateName: 'loaded',
icon: `<div id="feature-count-container"></div>`
}]
})
const featureCount = document.getElementById('feature-count-container');
watch: {
layerFeatures() {
if (this.layerFeatures) {
featureCount.innerHTML = `<i class="search-in-zone-btn">Showing ${this.layerFeatures.length} features</i>`
}
}
}
Let me know if this presents any issues or you have any other questions
Thx for the answer, but I may be doing something wrong, cause the feature-count-container div can't be found in the DOM.
Is it created even if the initial state is not itself? (currently the initial state is 'search')
Ah, I see. The icon element is created when you initialize the easyButton, but document.getElementById
will only find elements that are attached to the document.
What framework/library handles the watch
function?
this is a bit hacky, but I think it should get things working for you:
// switch states to attach the icon to the document
this.searchInArea.state('loaded');
// search the dom and grab a reference to the element
const featureCount = document.getElementById('feature-count-container');
// switch back to the default state
this.searchInArea.state('search');