Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regular input type #26

Closed
bissolli opened this issue Nov 23, 2016 · 5 comments
Closed

Regular input type #26

bissolli opened this issue Nov 23, 2016 · 5 comments

Comments

@bissolli
Copy link

Is there any solution for regular input as bootstrap-colorpicker?

@bissolli
Copy link
Author

I have made this component which do quite what I want!

<template>
    <div class="parent">
        <div class="input-group">
            <input v-model="color" class="form-control">
            <a href="#" @click.prevent="showPicker = !showPicker" class="input-group-addon">
                <i class="fa fa-square" :style="`color: ${color}`"></i>
            </a>
        </div>
        <div class="picker" v-show="showPicker">
            <picker v-model="color" @change-color="onChange"></picker>
        </div>
    </div>
</template>

<style scoped>
    .parent {
        position: relative;
    }
    .picker {
        position: absolute;
        top: 34px;
        left: 1px;
        z-index: 9999;
    }
</style>

<script>
    import { Chrome } from 'vue-color'

    export default {
        props: [ 'value' ],
        data () {
            return {
                showPicker: false,
                color: ''
            }
        },
        components: { 'picker': Chrome },
        watch: {
            value (value) {
                if (this.color !== value)
                    this.color = value
            },
            color () {
                this.$emit('input', this.color)
            }
        },
        methods: {
            onChange (val) {
                this.color = val.hex
            }
        }
    }
</script>

The problem is I couldn't show the picker the focusin/focusout input event because when I try to chose the color the focusout event triggers and close the picker! So I put a click event on the icon which toggles it!

Any ideas?

@cassioscabral
Copy link
Collaborator

Hi there, do you want to show the picker on focus instead of click ? When you said "I put a click event" are you referring to this @click.prevent="showPicker = !showPicker" ?

have you tried @focusin="openPicker" ? Vue accepts any events with @(v-on), I tried here on a fiddle and focusin is only called once(in the the focusin event). You could close the picker after a color change for example

@bissolli
Copy link
Author

bissolli commented Nov 24, 2016

Hey Cassio!

About the click event it is related to the code highlighted by you!
I have tried to you it with @focusin on the input field... but my problem is to close the picker... The only way found by me was clicking on the button beside the input!

I can't do it on the watch:color because when I change the color the picker will close at the same time and I would want keep searching for a color!

The best approach is to close when the user clicks outside picker or when the main click lost focus! I tried also listen the focusout event on the root element but when I click to choose my color it also triggers the focusout event even when my picker is inside the root element!

So the closest to the best approach that I got is this:

<template>
    <div class="input-group picker-input">
        <input v-model="color" class="form-control">
        <a href="#" class="input-group-addon" @click.prevent="showPicker = !showPicker">
            <i class="fa fa-square" :style="`color: ${color}`"></i>
        </a>
        <div class="picker-fade" v-show="showPicker" @click="closePicker"></div>
        <div class="picker-box" v-show="showPicker">
            <picker v-model="color" @change-color="onChange"></picker>
        </div>
    </div>
</template>

<style scoped>
    .picker-input {
        position: relative;
        z-index: 98;
    }
    .picker-box {
        position: absolute;
        top: 34px;
        left: 1px;
        z-index: 99;
    }
    .picker-fade {
        position: fixed;
        width: 100%;
        height: 100%;
        z-index: 97;
        left: 0;
        top: 0;
    }
</style>

<script>
    import { Swatches } from 'vue-color'

    export default {
        props: [ 'value' ],
        data () {
            return {
                showPicker: false,
                color: ''
            }
        },
        components: { 'picker': Swatches },
        watch: {
            value (value) {
                if (this.color !== value)
                    this.color = value
            },
            color () {
                let vm = this
                vm.$emit('input', vm.color)
            }
        },
        methods: {
            onChange (val) {
                this.color = val.hex
            },
            openPicker () {
                this.showPicker = true
            },
            closePicker () {
                this.showPicker = false
            }
        }
    }
</script>

@cassioscabral
Copy link
Collaborator

The way you want to close/show the picker is pretty much up to you since the pickers don't have a close button or event.

With a button to open, it's an option to use the same button to close.

Clicking outside the picker is trickier to know that, the parent or a Vuex state could know about the the children states, or even control(parent knows which child is open at the moment). Googling for the picker you mentioned, it closes one picker when other is opened, actually when other input is focused. To achieve that I would recommend this parent-child communication, parent knowing who is open and the child asks to close any other picker open on focus.

vue-color uses a lot of mousemove or mouseup, not focus, you could also intercept this event on pickers. Like @mouseup="doSomething"

You can check here more about the events: https://github.com/xiaokaike/vue-color/blob/master/src/components/common/Hue.vue#L105

Other possible solution is to build your own picker with separate components, if you need more customization. Here it is some of the components you can use: https://github.com/xiaokaike/vue-color/blob/master/src/index.js (you need to import them individually)

@cassioscabral
Copy link
Collaborator

@gustavobissolli maybe this will help you: https://github.com/simplesmiler/vue-clickaway

If that helps, please close the issue.
Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants