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

Showing error messages in Angular when a form is submitted and found to be invalid

My form currently displays an error message under each field if left empty or invalid. However, I want to customize the behavior of the submit button when the form is invalid. <form #projectForm="ngForm" (ngSubmit)="onSubmit()"> ...

CSS for Adjusting Parent Height Based on Child Content

I've been working on adjusting the height of the parent class to fit the child class perfectly without overflowing Here is a snippet from my CSS file: Parent &__video position: relative; width: 471px; background: red; border-radius: 12px ...

Troubleshooting the NullInjectorError in Angular - Service Provider Missing?

I'm facing an issue in my code where I have buttons that should trigger pop-ups displaying details as a list when clicked. However, every time I click the buttons, I encounter the error mentioned below. It seems like I am unable to access the desired ...

"Encountering issues when trying to retrieve a global variable in TypeScript

Currently facing an issue with my code. I declared the markers variable inside a class to make it global and accessible throughout the class. However, I am able to access markers inside initMap but encountering difficulties accessing it within the function ...

The Dynamic Kendo Grid construction encountered an invalid template issue

In my project, I'm working on creating a dynamic Kendo UI grid with columns that are dynamically generated. However, I'm encountering an issue where the data is not rendering properly onto the grid. The backend of this project involves using ASP ...

Issue with Gijgo grid not updating properly during change event

I'm currently working on an MVC 5 application and I've hit a roadblock with a particular view. This view contains a dropdown menu and a grid (Gijgo-grid). The grid's content is supposed to change based on the selected value from the dropdown ...

Adding Bootstrap modal content to a webpage before it renders is a simple process that involves preloading the

When using Bootstrap modal, is it possible to load a remote URL along with the parent page without needing to click on a button? ...

What steps can be taken to disable Angular's automatic trimming of fields?

Is there a global way to prevent Angular from automatically trimming input fields throughout the entire application? I know that I can avoid it for specific fields using the ngTrim directive, but it's not ideal to add this directive to every text fiel ...

I'm having some trouble with my middleware test in Jest - what could be going wrong?

Below is the middleware function that needs testing: export default function validateReqBodyMiddleware(req: Request, res: Response, next: NextFunction) { const { name, email }: RequestBody = req.body; let errors: iError[] = []; if (!validator.isEmai ...

What is the best way to utilize my function across several different elements?

I'm having trouble applying my function to multiple elements. My goal is to have each element change individually on its own. Currently, only the first element is changing. I want all three of them to change separately. For instance: Not Available ...

What is the best way to invoke a Javascript function within the same file using PHP?

I am facing an issue with my PHP file named "PhpCallJavascript". I am attempting to call the function CreateSVG() from within the PHP code. However, it seems that it is not working. Do I need to incorporate AJAX here? Or perhaps there is another solutio ...

Cookie Consent has an impact on the performance of PageSpeed Insights

On my website, I have implemented Cookie Consent by Insights. The documentation for this can be found at However, I noticed a significant drop in my Google PageSpeed Insight scores after loading the JavaScript source for Cookie Consent. The main issue hig ...

Display all items with pagination in a Material UI Table using React

I have recently implemented pagination in a react data table to handle a large number of entries. I wanted to add an option to display all entries by selecting "all" in the rowsPerPageOptions dropdown menu. Currently, I am able to show the count of all ent ...

Tips for inserting information from a JSON file into a mailto hyperlink

As a newcomer to JavaScript, I am eager to tackle the challenge presented below: Situation: In possession of a JSON file containing personal details such as name, email address, bio, etc., my task is to design a basic web page showcasing this data for ea ...

What is the best method to include spacing between strings in an array and then combine them into a csv-friendly format?

The method I am currently employing involves the following: var authorsNameList = authors.map(x => x.FirstName + ' ' + x.LastName); Yet, this generates an outcome similar to this: Bob Smith,Bill Jones,Nancy Smith Nevertheless, the desired ...

Convert a multidimensional array into a string using JavaScript

Currently, I'm in the process of generating an invoice for a collection of books and my intent is to submit it using ajax. However, when attempting to json encode the array of books within the invoice, I am encountering a setback where the value keeps ...

Getting form field values with JQuery

I am currently facing an issue with a form field in HTML. Here is the code snippet: <form id="tasklist"> <input type="text" id="name" ...></input> ... additional form elements go here ... </form> Although I am trying to retrie ...

Troubleshooting Problems with Ajax across Different Web Browsers

I am facing an issue with my ajax function - it works perfectly on Chrome and Firefox, but not on Internet Explorer 8. Can anyone help me identify the problem? Here is the HTML section: <select id='choices'> <option id="no" value="no" ...

Steer clear of Cross-Site Request Forgery through

As someone who is still learning about web security, I am curious about the best practices for using tokens on JavaScript requests to prevent CSRF attacks. Is it possible for someone to provide a code example? I already know how to implement this properly ...

The positioning of the input is being altered by the bootstrap-vue formatter

Is there a way to replace whitespaces with underscores in the file name input of bootstrap-vue without changing the cursor position? If I add a white space not at the end of the input, the formatter moves the cursor to the end. How can I achieve this? I a ...