Which HTML/JS widget to display this balsamiq control?
-
28-05-2021 - |
Question
I did mockups in balsamiq & they have this nice widget, which
- Allowed to select a value, out of two values. Works really nicely on touchscreens
- Can be used to Display two values & highlighting the selected one
Example:
What the options to implement a widget similar to shown in picture via HTML/CSS & JS?
Solution
The approach I present below iterates through all fieldset
elements, and if all the inputs therein are of type="radio"
, hides them and appends span
elements (of class="buttonRadio"
) in their place, using the text from their relevant label
elements. It also binds click
events to the appended span
elements, and triggers the change
event on the original input
s and also adds the 'checked' class-name to the clicked/touched element, while removing that class it from its siblings:
$('fieldset').each(
function() {
var legend = $(this).find('legend').text();
if ($(this).find('input').length == $(this).find('input[type="radio"]').length) {
var that = $(this),
len = that.find('input[type="radio"]').length;
for (var i = 0; i < len; i++) {
$('<span />')
.text($('label')
.eq(i).text())
.addClass('buttonRadio')
.attr('data-fromID',that.find('input:eq(' + i + ')').attr('id'))
.appendTo(that);
}
}
}).on('click','.buttonRadio',function(){
var id = $(this).attr('data-fromID');
$(this).addClass('checked').siblings().removeClass('checked');
$('#' + id).click().trigger('change');
}).find('label, input[type="radio"]').css('display','none');
This uses the following CSS to style those elements:
.buttonRadio {
background-color: #fff;
padding: 0.5em 1em;
border: 1px solid #000;
margin: 0.5em 0 0 0;
}
.buttonRadio.checked {
background-color: #ffa;
}
Edited to amend the jQuery a little:
- cached the
$(this)
object a little earlier in this version, - remembered to use the
legend
variable that I assigned in the first incarnation but forgot to actually use...sigh. also hid the actual
<legend></legend>
element:$('fieldset').each( function() { var that = $(this), legend = that.find('legend').text(); $('<span />').text(legend).addClass('legend').appendTo(that); if (that.find('input').length == that.find('input[type="radio"]').length) { var len = that.find('input[type="radio"]').length; for (var i = 0; i < len; i++) { $('<span />') .text($('label') .eq(i).text()) .addClass('buttonRadio') .attr('data-fromID',that.find('input:eq(' + i + ')').attr('id')) .appendTo(that); } } }).on('click','.buttonRadio',function(){ var id = $(this).attr('data-fromID'); $(this).addClass('checked').siblings().removeClass('checked'); $('#' + id).click().trigger('change'); }).find('label, input[type="radio"], legend').css('display','none');
References:
addClass()
.attr()
.click()
.css()
.each()
.eq()
.find()
.on()
.removeClass()
.siblings()
.text()
.trigger()
.