Search code examples
vuejs2vue-events

Clicking on input with keyup.enter.prevent form is submitted anyway


In @vue/cli 4.1.1 app I use bootstrap-vue and I have a form with 2 tabs : on 1st tab several fields and clicking Enter key on any control my form is submitted as expected, but I have the second tab with listing of meta keywords and single input control I want clicking on this control

v-on:keyup.enter.prevent="addMetaKeyword()"

to run update method, but without form submitted, but failed as my form is submitted. I do like :

    <template>
        <b-card class="backend_editor_container">
            <b-card-header>
                <h3 class="row_content_left_aligned p-2" v-show="is_page_loaded">
                    <i :class="'info_link '+getHeaderIcon('page')"></i>{{ getHeaderTitle }}
                </h3>
                <div v-show="!is_page_loaded">
                    <h3>
                        <b-spinner variant="success" label="Page loading"></b-spinner>&nbsp;Page loading...
                    </h3>
                </div>
    
            </b-card-header>
    
            <b-card-body v-show="is_page_loaded">
    
                <div>
                    <b-tabs content-class="mt-3" justified>
    
                        <b-tab
                                title="Details"
                        >
    
                            <ValidationObserver
                                    ref="pageObserverForm"
                                    v-slot="{handleSubmit}"
                            >
                                <b-form @submit.prevent="handleSubmit(onSubmit)">
    
    
                                    <b-row class="editor_row" v-if="!is_insert">
                                        <b-col md="4">
                                            <label for="id" class="pt-2 ">Id:</label>
                                        </b-col>
                                        <b-col md="8">
                                            <b-form-input
                                                    id="id"
                                                    v-model="pageForm.id"
                                                    readonly
                                                    class="text-right"
                                            ></b-form-input>
                                        </b-col>
                                    </b-row>
            ...
                        </b-tab>
    
    
                        <b-tab
                                title="Meta"
                                active
                        >
                            <fieldset class="bordered text-muted p-0 m-0 mb-4">
    
                                <legend class="bordered">Add meta keyword</legend>
    
                                <b-row class="editor_row">
                                    <b-col md="4">
                                        <label for="new_meta_keyword" class="pt-2 ">New meta keyword:</label>
                                    </b-col>
                                    <b-col md="8">
                                        <b-form-input
                                                id="id"
                                                v-model="new_meta_keyword"
                                                class="text-left"
                                                v-on:keyup.enter.prevent="addMetaKeyword()"
                                        ></b-form-input>
                                    </b-col>
                                </b-row>
                                <div class="buttons_container">
                                    <b-button type="button" variant="primary" size="sm" @click.prevent="addMetaKeyword()" class="m-1 ml-4">
                                        <i :class="'info_link '+getHeaderIcon('save')"></i>Add
                                    </b-button>
                                </div>
    
                            </fieldset>

How correct ?

"bootstrap-vue": "^2.3.0",
"vue": "^2.6.11",

Modified BLOCK #1 :

        addMetaKeyword() {
            this.new_meta_keyword = this.trim(this.new_meta_keyword)
            if (this.isEmpty(this.new_meta_keyword)) {
                this.showPopupMessage('Page editor', 'Meta keyword can not be empty !', 'warn')
                return
            }

            let l = this.metaKeywordsList.length
            for (let i = 0; i < l; i++) {
                if (this.metaKeywordsList[i] === this.new_meta_keyword) {
                    this.showPopupMessage('Page editor', 'This Meta keyword is already defined !', 'warn')
                    return
                }
            }

            this.metaKeywordsList[this.metaKeywordsList.length] = this.new_meta_keyword
            this.new_meta_keyword = null
            this.showPopupMessage("Page editor", 'You need to save changes in meta keyword mby clicking on "Update" button !', 'success');
        },

Thanks!


Solution

  • The problem is that the keyup event is not preventable. Instead use the keydown event like so <b-input @keydown.enter.prevent="yourMethod"></b-input>, this will run yourMethod without submitting the form.

    new Vue({
     el: "#app",
     methods: {
      onSubmit() {
        console.log('Form submitted')
      },
      doOtherStuff(){
        console.log('Doing other stuff')
      }
     }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
    <script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
    
    <link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" rel="stylesheet"/>
    
    <div id='app'>
      <b-form @submit.prevent="onSubmit">
        <h1>This will submit your form</h1>
        <b-input></b-input>
        <h1>This wont submit your form</h1>
        <b-input @keydown.enter.prevent="doOtherStuff"></b-input>
        
        <!-- Needs the button to handle submit, I'm hiding it in this case -->
        <b-btn type="submit" class="d-none"></b-btn>
      </b-form>
    </div>