Vue enables seamless click-and-edit functionality for text input

I am in search of a Vue component that allows for click-and-edit functionality.

After discovering this fiddle, I made some modifications. It functions like this:

https://i.sstatic.net/bSMPj.gif

Access the fiddle here.

The issue: Currently, an additional click is required to focus on the input field. How can I achieve automatic focus?

The HTML code snippet from the fiddle:

<div id="app">
Click the values to edit!
  <ul class="todo-list">
    <li v-for = "todo in todos">
      <input v-if = "todo.edit" v-model = "todo.title"
      @blur= "todo.edit = false; $emit('update')"
      @keyup.enter = "todo.edit=false; $emit('update')">
            <div v-else>
        <label @click = "todo.edit = true;"> {{todo.title}} </label>
      </div>
    </li>
  </ul>

</div>

JavaScript (JS) portion:

new Vue({
  el: '#app',
  data: {
    todos: [{'title':'one value','edit':false},
                  {'title':'one value','edit':false},
                    {'title':'otro titulo','edit':false}],
    editedTodo: null,
    message: 'Hello Vue.js!'
  },
  methods: {
    editTodo: function(todo) {
      this.editedTodo = todo;
    },
  }

})

Answer №1

If you want to enhance your Vue.js application, consider using a directive like the one below:

JavaScript

new Vue({
  el: '#app',
  data: {
    todos: [
      { title: 'one value', edit: false },
      { title: 'one value', edit: false },
      { title: 'otro titulo', edit: false }
    ],
    editedTodo: null,
    message: 'Hello Vue.js!'
  },
  methods: {
    editTodo: function (todo) {
      this.editedTodo = todo
    }
  },
  directives: {
    focus: {
      inserted (el) {
        el.focus()
      }
    }
  }
})

HTML

<div id="app">
    Click the values to edit!
    <ul class="todo-list">
        <li v-for="todo in todos">
            <input
                v-if="todo.edit"
                v-model="todo.title"
                @blur="todo.edit = false; $emit('update')"
                @keyup.enter="todo.edit=false; $emit('update')"
                v-focus
            >
            <div v-else>
                <label @click="todo.edit = true;"> {{todo.title}} </label>
            </div>
        </li>
    </ul>
</div>

To learn more about custom directives in Vue.js, check out this link https://v2.vuejs.org/v2/guide/custom-directive.html

Answer №2

Thanks to the assistance of @AitorDB, I have successfully crafted a Vue component called Click-to-Edit. It is all set for immediate use, so I am sharing it here.

Key features include:

  • Full support for v-model
  • Saving changes by clicking outside or pressing Enter

ClickToEdit.vue: (Vue 2.x)

<template>
  <div>
    <input type="text"
           v-if="edit"
           :value="valueLocal"
           @blur.native="valueLocal = $event.target.value; edit = false; $emit('input', valueLocal);"
           @keyup.enter.native="valueLocal = $event.target.value; edit = false; $emit('input', valueLocal);"
           v-focus=""
             />
        <p v-else="" @click="edit = true;">
          {{valueLocal}}
        </p>
    </div>
</template>

<script>
  export default {
  
  props: ['value'],
  
  data () {
  return {
      edit: false,
      valueLocal: this.value
    }
  },
  
  watch: {
    value: function() {
      this.valueLocal = this.value;
    }
  },
  
  directives: {
    focus: {
      inserted (el) {
        el.focus()
      }
    }
  }
  
}
</script>

Update for Vue 3.x: [Important Changes from 2.x]

  • Eliminate the use of .native in event handlers
  • Replace the focus hook with mounted as specified in Custom Directives 3.x.

Answer №3

This solution builds upon the groundwork laid by @Masen Furer, with additional protection mechanisms in place to handle scenarios where a user deletes all data. Although there may be potential for utilizing an "update" method, my attempts at implementing it were unsuccessful. I've also incorporated a feature that allows users to press the escape key to discard any changes made.

<template>
  <span>
    <input type="text"
           v-if="edit"
           :value="valueLocal"
           @blur="save($event);"
           @keyup.enter="save($event);"
           @keyup.esc="esc($event);"
           v-focus=""/>
        <span v-else @click="edit = true;">
          {{valueLocal}}
        </span>
    </span>
</template>

<script>
  export default {
  
  props: ['value'],
  
  data () {
  return {
      edit: false,
      valueLocal: this.value,
      oldValue: (' ' + this.value).slice(1)
    }
  },
  methods: {
      save(event){
        if(event.target.value){             
            this.valueLocal = event.target.value; 
            this.edit = false; 
            this.$emit('input', this.valueLocal);
        }
      },
      esc(event){
          this.valueLocal = this.oldValue; 
          event.target.value = this.oldValue;
          this.edit = false; 
          this.$emit('input', this.valueLocal);
      }
  },
  watch: {
    value: function() {
      this.valueLocal = this.value;
    }
  },
  
  directives: {
    focus: {
        inserted (el) {
            el.focus()
        }
    }
  }
  
}
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Collapse a previously used item when a new item is opened within Angular

I've managed to create a tree structure for a sideBar Menu using this code, and it's working well. However, what I'm trying to achieve is that when a menu with submenus is expanded and the user clicks on another parent menu, the expanded sub ...

Is there a way to locate a specific property within a mongoose model using a different property?

In my mongoose schema, I have defined the following properties: var personnelSchema = new Schema({ fullName: String, dob: String, cNumber: String, address: String, wCard: String, dLic: Number, ...

Enhance Your HTML Skills: Amplifying Table Display with Images

Recently, I utilized HTML to design a table. The Table Facts : In the first row, I included an appealing image. The second row contains several pieces of content. In continuation, I added a third row. The contents in this row are extensive, resulting i ...

Ways to display two horizontal scrolling menu bars

I am in need of displaying two horizontal scroll menu bars on my website. After some research, I came across a custom horizontal scroll menu with left and right arrows. https://jsfiddle.net/c5grnve6/ While it works well with only one scroll menu on the p ...

Find your favorite artist on Spotify through the search function

Recently, I stumbled upon this intriguing demo showcasing how to search for an artist using the Spotify API. However, despite several attempts, I have been unable to make it function properly. Can anyone provide any tips or guidance on making this work suc ...

Help needed with using Regex to restrict the number of alphabetical characters allowed

Struggling with configuring RegEx's. Seeking guidance to create a RegEx with the following criteria: Only allow numbers (0-9) Allow a period (.), negative sign (-), plus sign (+), dollar sign ($), and comma (,) Do not permit any alphabetic characte ...

What is the origin of this mysterious error?

I'm working on a function to format various types of variables and utilize a toString() method. It's handling complex objects, arrays, and circular references flawlessly. However, when testing it on a jQuery object using format($("body")) with l ...

Compare the path string with the parameters of Vue Router

My path-string is "/foo/123/bar/456", which does not match the current path. The Vue Router path I have set is /foo/:fooid/bar/:barid I am wondering if there is a way to extract params from the string using Vue Router? This is what I'm ex ...

Is it more important to focus on passing props or making API requests the top priority in your web application structure

Context Currently, I am working on a Vue App utilizing the Composition API. My backend serves as the source of data for loading pages and components. Inquiry When it comes to structuring my app's architecture, should I prioritize passing props thro ...

What is the best way to acquire an ID that is generated dynamically?

Being new to javascript and ajax, I am facing a challenge. I have a while loop with 2 buttons, both of which seem to function correctly, except for one small issue... The product-id is only being passed for the first or last element in the loop. How can I ...

Enhance the CSS styling for the React-Calendly integration in a React project

I am trying to customize the CSS of an Inline Widget called React Calendly. I have attempted to use React Styled Component Wrapper, Frame React Component, and DOM javascript but unfortunately, the design changes are not reflecting as desired. Specifically, ...

How can I implement BoxHelper on an Object3D containing children in Three.js?

I am exploring the possibility of using the THREE.BoxHelper to generate a bounding box for an Object3D that has children. My goal is to render a wireframe bounding box for the object while omitting diagonals on the box's faces. Upon inspecting the sou ...

Why is my Vue view not being found by Typescript (or possibly Webpack)?

npx webpack TS2307: Cannot locate module './App.vue' or its corresponding type declarations. I am currently utilizing webpack, vue, and typescript. My webpack configuration is pretty basic. It uses a typescript file as the entry point and gener ...

When the Ajax "GET" request is made to the intra-service, the CMS service worker will respond with an "OK" even when offline

Hello there, We are currently utilizing an open-source CMS that recently received an upgrade with a new feature - a javascript serviceworker implementation to manage all requests. This CMS includes workflow forms where users engage (created by us). Durin ...

Turning off tables using ASP.net controls and Telerik controls

Here is the code for my custom table: <table id="DispalyTable" border="4px" style="width: 100%;" > <tr> <td style="width: 137px; height: 137px;" valign="top"> ...

transform a JSON object into a targeted JSON array

Looking to transform a JSON object into an array format, like so: [ { "name": "Batting" ,"data": [10,20,30,40]} , { "name": "Bowling" ,"data": [10,30,50,70] },{ "name": "Fielding" ,"data": [20,40,50,70]}] While I can create JSON objects for each index, I ...

Displaying files based on time signatures using NodeJS with a delay

I have 6 levels of user tiers. Each tier has a different time delay in viewing posts: 1st tier: See posts immediately upon posting. 2nd tier: See the same post after 60 minutes 3rd tier: See the same post after 120 minutes 4th tier: See the same post af ...

Automating the process of posting a file to a form with javascript

I have a piece of client-side JavaScript that creates a jpeg file through HTML5 canvas manipulation when the user clicks an "OK" button. My goal is to automatically insert this jpeg output into the "Upload Front Side" field in a form, simulating a user up ...

Capture the contents of a table cell and store it in the clipboard

Is there a way to create a hover copy button in a table cell without actually placing the button inside the <td> tags? The goal is to allow users to easily copy text from a specific column cell by hovering over it. function myFunction() { var c ...

Displaying Array Information in JavaScript

After spending a significant amount of time searching online, I have not been able to find a working solution to achieve what I need. Essentially, I am making an AJAX request that executes a database query and then outputs the results using echo json_enco ...