Skip to content

Instantly share code, notes, and snippets.

@Jonarod
Created November 23, 2019 18:23
Show Gist options
  • Save Jonarod/8553d88b1b0d1e1898ff1b5c951b00cc to your computer and use it in GitHub Desktop.
Save Jonarod/8553d88b1b0d1e1898ff1b5c951b00cc to your computer and use it in GitHub Desktop.
Simple custom Radio component for Vue.js, compatible with v-model.
/**
* @usage:
*
* <RadioBox label="Foo" value="foo" v-model="MySelectedValue" />
* <RadioBox label="Bar" value="bar" v-model="MySelectedValue" />
* <RadioBox label="Baz" value="baz" v-model="MySelectedValue" />
*
* data(){
* return {
* MySelectedValue: "",
* }
* }
*/
<template>
<label class="wrapper flex items-center">
{{label}}
<input class="checkbox" type="radio" :checked="isChecked" :value="value" @change="$emit('change', $event.target.value)" />
<span class="checkmark"></span>
</label>
</template>
<script>
export default {
model: {
prop: 'modelValue',
event: 'change'
},
props: {
"label": { type: String, default: "", required:true },
"modelValue": { default: "" },
"value": { type: String, default: undefined }
},
computed: {
isChecked() {
return this.modelValue == this.value
}
}
}
</script>
<style lang="postcss" scoped>
/* Customize the label (the wrapper) */
.wrapper {
display: block;
position: relative;
padding-left: 35px;
margin-bottom: 6px;
cursor: pointer;
font-size: 22px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
font-size: 16px;
}
/* Hide the browser's default radio button */
.wrapper input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
/* Create a custom radio button */
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 21px;
width: 21px;
border-radius: 50%;
background-color: #eee;
border: 1px solid #ccc;
}
/* On mouse-over, add a grey background color */
.wrapper:hover input ~ .checkmark {
background-color: #ccc;
}
/* When the radio button is checked, add a blue background */
.wrapper input:checked ~ .checkmark {
background-color: #1CD4A7;
}
/* Create the indicator (the dot/circle - hidden when not checked) */
.checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the indicator (dot/circle) when checked */
.wrapper input:checked ~ .checkmark:after {
display: block;
}
/* Style the indicator (dot/circle) */
.wrapper .checkmark:after {
top: 5px;
left: 6px;
width: 8px;
height: 8px;
border-radius: 50%;
background: white;
}
</style>
@mra-dev
Copy link

mra-dev commented Mar 14, 2022

Searched a lot and finally found this. Thanks a lot.

@felipeblini
Copy link

felipeblini commented Jan 30, 2023

thanks a lot!!

It didn´t work with boolean value, to make it work I create a localValue property:

 props: {
    "label": { type: String, default: "", required:true },
    "modelValue": { default: "" },
    // "value": { type: String, default: undefined }
    "value": { default: undefined },
  },

data() {
    return {
      localValue: null,
    }
  },

watch: {
    modelValue: {
      handler: function (modelValue) {
        if (modelValue === 'false') return (this.localValue = false)
        if (modelValue === 'true') return (this.localValue = true)

        this.localValue = modelValue
      },
      immediate: true,
    },
  },

computed: {
    isChecked() {
      //return this.modelValue == this.value
      return this.localValue == this.value
    },
  },

@udithishara
Copy link

To make it work with Boolean's you can simply convert this.value to a string and compare it as modelValue will be a string anyway

    modelValue: { type: String, default: undefined },
    value: { type: [String, Number, Boolean], default: undefined },
  isChecked() {
    return this.modelValue === this.value.toString()
  },

@CristianNiquin
Copy link

Thank's!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment