Closed github-weiwei closed 8 months ago
@github-weiwei well, I would love to get an answer to this one as well. In the meantime I figured out sth that kind of works:
import { Form } from 'vue-formio'; // this one is needed so that we have Formio in global scope
import BaseComponent from 'vue-formio/node_modules/formiojs/components/base/Base';
import Vue from 'vue/dist/vue.esm';
var MyVueComponent = Vue.extend({
name: 'MyVueComponent',
props: {
component: null
},
template: '<div v-bind:id="component.key">{{ component.someProp }}</div>'
});
class MyComponent extends BaseComponent {
build() {
super.build();
let element = super.getElement();
var instance = new MyVueComponent({
propsData: {
component: this.component,
},
el: element
});
instance.$mount();
element.appendChild(instance.$el);
}
}
Formio.registerComponent('mycomponent', MyComponent);
`
Now, if you add mycomponent to your form definition you should see a result.
Thank you I try.
Answer is a bit outdated as the code has changed since 2018
Here's a sample ratings component based on a radio button
import { Formio } from 'vue-formio'
import Vue from 'vue'
import { generateUniqueId } from '../../models/form-utils'
const RatingsComponent = Vue.extend({
props: {
component: {
type: Object,
default: () => {}
},
// eslint-disable-next-line vue/require-default-prop
instance: null,
styles: {
type: String,
default: ''
}
},
mounted: function() {
var css = document.createElement('style')
css.type = 'text/css'
css.setAttributeNode(document.createAttribute('scopped'))
css.appendChild(document.createTextNode(this.styles))
this.$el.appendChild(css)
},
methods: {
handleClick(value, values) {
if (!this.component.disabled) {
values.forEach((option) => {
option.checked = false
option.id = generateUniqueId()
option.checked =
value !== this.instance.getValue() ? option.value <= value : false
})
this.instance.updateValue(value, {
modified: true
})
}
}
},
template: `
<div>
<fieldset>
<div v-for="(item) in component.values" :key="item.id" class="rating" :class="{'rating--disabled': component.disabled}">
<input type="radio" :name="item.value" :value="item.value" :checked="item.checked"/>
<label :for="item.value" :title="item.value" @click="handleClick(item.value, component.values)"></label>
</div>
</fieldset>
</div>
`
})
const RadioComponent = Formio.Components.components.radio
export class RatingFormIOComponent extends RadioComponent {
attach(element) {
const styles = this.styling('.rating')
var instance = new RatingsComponent({
propsData: {
component: this.component,
styles,
instance: this
},
el: element.querySelector('.form-radio')
})
instance.$mount()
return super.attach(element)
}
styling(id) {
return `
${id} {
float:left;
}
${id}:not(:checked) > input {
position: absolute;
clip: rect(0, 0, 0, 0);
height: 0;
width: 0;
overflow: hidden;
opacity: 0;
}
${id}:not(:checked) > label {
float:right;
padding:0 .1em;
overflow:hidden;
white-space:nowrap;
cursor:pointer;
font-size:200%;
line-height:1.2;
color:#ddd;
text-shadow:1px 1px #bbb, 2px 2px #666, .1em .1em .2em rgba(0,0,0,.5);
}
${id}:not(:checked) > label:before {
content: '★ ';
}
${id} > input:checked ~ label {
color: #f70;
text-shadow:1px 1px #c60, 2px 2px #940, .1em .1em .2em rgba(0,0,0,.5);
}
${id}:not(:checked) > label:hover,
${id}:not(:checked) > label:hover ~ label {
color: gold;
text-shadow:1px 1px goldenrod, 2px 2px #B57340, .1em .1em .2em rgba(0,0,0,.5);
}
${id} > input:checked + label:hover,
${id} > input:checked + label:hover ~ label,
${id} > input:checked ~ label:hover,
${id} > input:checked ~ label:hover ~ label,
${id} > label:hover ~ input:checked ~ label {
color: #ea0;
text-shadow:1px 1px goldenrod, 2px 2px #B57340, .1em .1em .2em rgba(0,0,0,.5);
}
${id} > label:active {
position:relative;
top:2px;
left:2px;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome, Edge, Opera and Firefox */
}
${id}--disabled > label {
cursor: not-allowed !important
}
`.replace(/\s+/g, '')
}
}
import { Formio } from 'vue-formio'
import { RatingFormIOComponent } from './rating-formio'
export const registerCustomComponents = () => {
Formio.Components.addComponent('rating', RatingFormIOComponent)
}
We're currently addressing a backlog of GitHub issues. Closing this thread as it is outdated. Please re-open if it is still relevant. Thank you for your contribution!
Can anyone tell me how to solve it ? Thank you.