Skip to content

Instantly share code, notes, and snippets.

@bayareawebpro
Last active January 7, 2020 00:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bayareawebpro/720131795fdb697d7bd28e13c81ed3c7 to your computer and use it in GitHub Desktop.
Save bayareawebpro/720131795fdb697d7bd28e13c81ed3c7 to your computer and use it in GitHub Desktop.

Usage

<v-form-control
    type="text"
    name="name"
    label="Name"
    v-model="entity.name"
    @change="isInvalid = false"
    :invalid="isInvalid"
    :help="'Enter the project name.'"
/>

<v-form-control
    type="select"
    name="server"
    label="Server"
    v-model="entity.server_id"
    @change="isInvalid = false"
    :invalid="isInvalid"
    :help="'Run recipe on server.'"
    :options="[{label: "optionA", value: 1}]"
    :multiple="false"
/>

Component

<script>
    export default {
        name: "FormControl",
        props: {
            value: {
                required: false,
                default: ()=> ''
            },
            type: {
                type: String,
            },
            name: {
                type: String,
            },
            label: {
                type: String,
            },
            help: {
                type: String,
            },
            placeholder: {
                type: String,
            },
            invalid: {
                type: Boolean,
            },
            multiple: {
                type: Boolean,
                default: ()=> false
            },
            options: {
                type: [Array, Object],
                default: ()=> [],
            },
        },
        computed: {
            field:{
                get(){
                    return this.value
                },
                set(value){
                    this.$emit('input', value)
                    this.$emit('change')
                }
            }
        },
        methods:{
            toggle(){
                this.field=!this.field
            },
            update(value){
                this.field=value
            }
        },
        watch:{
            options:{
                deep: true,
                immediate: true,
                handler(newVal){
                    if(!this.field && Array.isArray(newVal) && newVal.length === 1){
                        this.field = newVal[0].value
                    }
                }
            }
        }
    }
</script>
<template>
    <div class="element">

        <!-- TextArea -->
        <template v-if="type === 'textarea'">
            <label :for="name" class="label">{{ label }}</label>
            <textarea
                class="input"
                :name="name"
                v-model="field"
                :class="{invalid}"
                :placeholder="placeholder">
            </textarea>
        </template>
        <!-- TextArea -->

        <!-- Switch -->
        <template v-else-if="type === 'switch'">
            <label class="switch mt-5" :for="name">
                <span class="switch-well">
                   <input
                       :id="name"
                       :name="name"
                       type="checkbox"
                       v-model="field">
                   <span
                       tabindex="0"
                       class="slider"
                       @keydown.enter.capture.prevent.stop="toggle"
                       @keydown.space.capture.prevent.stop="toggle"
                       @keydown.right.capture.prevent.stop="update(true)"
                       @keydown.left.capture.prevent.stop="update(false)"
                   />
                </span>
                <span class="label">{{ label }}</span>
            </label>
        </template>
        <!-- Switch -->

        <!-- Select -->
        <template v-else-if="type === 'select'">
            <label :for="name" class="label">{{ label }}</label>
            <select
                :type="type"
                :name="name"
                class="input"
                v-model="field"
                :class="{invalid}"
                :multiple="multiple">
                <slot :options="options">
                    <option v-for="option in options" :value="option.value">
                        {{option.label}}
                    </option>
                </slot>
            </select>
        </template>
        <!-- Select -->

        <!-- Other -->
        <template v-else>
            <label :for="name" class="label">{{ label }}</label>
            <input
                :type="type"
                :name="name"
                class="input"
                v-model="field"
                :class="{invalid}"
                :placeholder="placeholder"
            />
        </template>
        <!-- Other -->

        <!-- Helper -->
        <p v-if="help" class="help" :class="{invalid: invalid}">
            {{ help }}
        </p>
        <!-- Helper -->
    </div>
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment