Implementing row updates using contenteditable feature in Vue.js

I am currently exploring how to detect and update the changes made in a 'contenteditable' element within a specific row.

<tbody>
    <!-- Iterate through the list and retrieve each data -->
    <tr v-for="item in filteredList" :key="item">
      <td v-for="field in fields" :key="field">
        <p contenteditable="true" >{{ item[field] }}</p>
      </td>
      <button class="btn btn-info btn-lg" @click="UpdateRow(item)">Update</button>
      <button class="btn btn-danger btn-lg" @click="DelteRow(item.id)">Delete</button>
    </tr>
  </tbody>

My goal is to reflect the changes made in the 'contenteditable' field in the respective row when calling the 'UpdateRow' function:

setup (props) {
const sort = ref(false)
const updatedList = ref([])
const searchQuery = ref('')

// a function to sort the table
const sortTable = (col) => {
  sort.value = true
  // Using _.sortBy() method
  updatedList.value = sortBy(props.tableData, col)
}

const sortedList = computed(() => {
  if (sort.value) {
    return updatedList.value
  } else {
    return props.tableData
  }
})

// Filter Search
const filteredList = computed(() => {
  return sortedList.value.filter((product) => {
    return (
      product.recipient.toLowerCase().indexOf(searchQuery.value.toLowerCase()) != -1
    )
  })
})
const DeleteRow = (rowId) => {
  console.log(rowId)
  fetch(`${import.meta.env.VITE_APP_API_URL}/subscriptions/${rowId}`, {
    method: 'DELETE'
  })
    .then((response) => {
      // Error handling
      if (!response.ok) {
        throw new Error('Something went wrong')
      } else {
        // Display alert message
        alert('Deletion successful')
        console.log(response)
      }
    })
    .then((result) => {
      // Handling response
      if (result === 'fail') {
        throw new Error(result.message)
      }
    })
    .catch((err) => {
      alert(err)
    })
}

const UpdateRow = (rowid) => {
  fetch(`${import.meta.env.VITE_APP_API_URL}/subscriptions/${rowid.id}`, {
    method: 'PUT',

    body: JSON.stringify({
      id: rowid.id,
      date: rowid.date,
      recipient: rowid.recipient,
      invoice: rowid.invoice,
      total_ex: Number(rowid.total_ex),
      total_incl: Number(rowid.total_incl),
      duration: rowid.duration
    })
  })
}

return { sortedList, sortTable, searchQuery, filteredList, DeleteRow, UpdateRow }

}

The commented lines of code work when manually entered:

          // id: 331,
          // date: rowid.date,
          // recipient: 'new R',
          // invoice: 'inv500',
          // total_ex: Number(500),
          // total_incl: Number(6000),
          // duration: 'Monthly'

Each cell can be edited, but I am unsure how to capture the change event

Answer №1

Understanding the functionality of run-time js frontend frameworks can be simplified to the concept that "content is the function of data." Essentially, the html displays the data provided to it. If you want the data to update when the user makes changes, you must explicitly instruct it to do so. Certain frameworks (such as react) necessitate setting up 1-way data binding where you define both the data displayed in the template and the event triggering the update. Vue simplifies this process with syntactic sugar like v-model for achieving 2-way binding. Different input types interact differently with v-model, each requiring unique handling due to their behavior. For text inputs or textareas using v-model="item[field]", the internal model gets updated effectively. However, non-input tags like h1 or p lack native v-model support, requiring a 1-way databinding approach to define content/value and the event updating the model upon html content changes.

Refer to this example:

<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>

<template>
  <h1 contenteditable @input="({target})=>msg=target.innerHTML">{{ msg }}</h1>
  <h2 contenteditable>{{ msg }}</h2>
  <input v-model="msg">
</template>

When changing content within h2, the model remains unaltered as vue does not track these modifications. However, alterations through input or h1 will trigger updates, prompting a re-render of h2 and its content adjustment.

TL;DR;

Utilize this structure:

<p
  contenteditable="true"
  @input="({target})=>item[field]=target.innerHTML"
>{{ item[field] }}</p>

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

Organize the table data based on time

My website specializes in offering cell phone rental services. Users can visit the site to view the available devices that we have. I designed the display of these devices using a table format and components from "@mui/material". One of the columns in thi ...

I am having trouble programmatically setting the 'checked' attribute for a newly added checkbox on an asp.net page

I dynamically added checkboxes using jQuery on my ASPX page and attempted to check some checkboxes by default based on conditions. However, I encountered the following error: Uncaught TypeError: undefined is not a function I tried the following methods ...

Getting a URL to redirect after a successful login via an AJAX request in PHP

I've been trying to figure out how to redirect the URL after a successful login using an Ajax call in PHP. Can someone please review my code and point out any mistakes? Here is the content of the registration.php file located at http://localhost:8080 ...

Tips for saving the web address and breaking down each word

Hello, I am familiar with how to store URL parameters using the following JavaScript code. However, I am wondering if there is a way to store each word that comes after a slash in a URL. For example, let's consider the URL: http://localhost:9000/Data ...

Exploring the intricacies of React Router parameters

I have been facing some issues with my routing setup. Specifically, I have a static route called list and a dynamic route called user/:id. The problem arises when navigating between these two pages. (1) Whenever I navigate to the list route from the user/: ...

Validate all JavaScript buttons by binding a click event

I've implemented the JS validation plugin from this source and it's functioning properly. However, it captures all button clicks on the page, including when I click on Back to Home, triggering form validation unnecessarily. I only want the form ...

When attempting to launch a VUE project on Nginx, there seems to be an issue locating static files such as css and

Currently running on a Windows operating system, I am trying to deploy a VUE project on an Nginx server. To build the VUE project: Follow these steps: Navigate to E:\test\test-project-frontend-demo Run npm install && npm run build Up ...

Tips for maintaining the InteractionCollector's presence even after a Discord.js bot reboot

One of the tasks my AI assistant handles is processing proposals submitted through Google Forms and transferring them to a designated channel where individuals can cast their votes by selecting either Yes or No using the corresponding MessageButton. Once ...

I'm unable to modify the text within my child component - what's the reason behind this limitation?

I created a Single File Component to display something, here is the code <template> <el-link type="primary" @click="test()" >{{this.contentShow}}</el-link> </template> <script lang="ts"> imp ...

Modifying an object's attribute in React.js by toggling a checkbox

As I delve into learning React, I am constructing a straightforward todo list. Here's the object contained within my initialState: getInitialState:function(){ return { items: [ { text:"Buy Fish", ...

Highcharts memory leakage issue arises when working with jQuery version 2.X

After extensive testing on my AngularJS application, I have discovered a memory leak when using Highcharts with the latest version of jQuery (2.1.4). Below are links to two plunkers for comparison: Using jQuery 1.8.2: http://plnkr.co/edit/lQ6n5Eo2wHqt35OV ...

Vue enables components to be used in any part of the application, not limiting them to

Currently, I am initializing my Vue instance in the following manner: import ListClubsComponent from "./components/clubs/list-clubs.vue"; new Vue({ el: "#app", components: { "list-clubs": ListClubsComponent } }); It seems to be functi ...

Modifying HTML line codes using Python: A step-by-step guide

If only I could modify this particular line: <button _ngcontent-c19="" class="blue-button-disabled" disabled="">CONTINUE </button> to be like this instead: <button _ngcontent-c19="" class="blue- ...

Inject an HTML or jade webpage into a div within another HTML or jade webpage

I'm facing an issue in my Node.js project with a script (JS) that is responsible for loading a Jade page into a div of another Jade page using $("#div").load(directory). Despite specifying the directory of the jade page to be loaded, I keep getting an ...

adding a variable to the value of an input field using the val() method

Here is a code snippet that appends the text 'text goes here' to an input value: $('#someid').val($('#someid').val() + 'text goes here'); I attempted to use a variable in a similar way, but it didn't work as e ...

Unable to install react-dom/test-utils using npm

I recently included two libraries in my package.json "devDependencies": { ... "react-dom/test-utils": "*", "react-test-renderer/shallow": "*" }, These were recommended by the React documentation to align with version 16 of the React ecosy ...

Error message: Unable to access $controller with AngularJS and Karma

As someone who is just starting with testing, I figured it was a good idea to begin testing this project. However, when I execute grunt karma:watch, I encounter an error related to the configuration files. My config file includes: module.exports = functi ...

Vue 2.0 - Component mounting error: template or render function not defined even though render function is defined

Currently working on a Single Page Application using Vue 2.0. I am bundling all my templates with Webpack from .vue files through Laravel Elixir, laravel-elixir-webpack-official, and laravel-elixir-vue-2. I have gone through numerous existing questions on ...

Changing the width of the file input using css

Clicking just below the word demonstration also triggers a click on the input type file. How can this be avoided so that the click event only fires in the intended area regardless of size? <!DOCTYPE html> <html> <body> <style> in ...

`vuejs datepicker template organization revamp`

I tried to incorporate a Vue.js datepicker into my Vue template, but when I added the component, it caused my template layout to shift from right to left and affect other HTML elements. Here is an image of my template before adding the datepicker: This i ...