Making a column in a Vue data grid return as a clickable button

My goal is to utilize vue.js grid to display multiple columns with calculated text values, along with a clickable column at the end that triggers a dynamic action based on a parameter (such as calling an API in Laravel).

However, when I include the last column as a clickable link, vue.js displays the HTML tag instead of rendering it within the grid. What am I missing here? VueCode:

  // register the grid component
    Vue.component('demo-grid', {
      template: '#grid-template',
      props: {
        data: Array,
        columns: Array,
        filterKey: String
      },
      data: function () {
        var sortOrders = {}
        this.columns.forEach(function (key) {
          sortOrders[key] = 1
        })
        return {
          sortKey: '',
          sortOrders: sortOrders
        }
      },
      computed: {
        filteredData: function () {
          var sortKey = this.sortKey
          var filterKey = this.filterKey && this.filterKey.toLowerCase()
          var order = this.sortOrders[sortKey] || 1
          var data = this.data
          if (filterKey) {
            data = data.filter(function (row) {
              return Object.keys(row).some(function (key) {
                return String(row[key]).toLowerCase().indexOf(filterKey) > -1
              })
            })
          }
          if (sortKey) {
            data = data.slice().sort(function (a, b) {
              a = a[sortKey]
              b = b[sortKey]
              return (a === b ? 0 : a > b ? 1 : -1) * order
            })
          }
          return data
        }
      },
      filters: {
        capitalize: function (str) {
          return str.charAt(0).toUpperCase() + str.slice(1)
        }
      },
      methods: {
        sortBy: function (key) {
          this.sortKey = key
          this.sortOrders[key] = this.sortOrders[key] * -1
        }
      }
    })

    // bootstrap the demo
    var demo = new Vue({
      el: '#demo',
      data: {
        searchQuery: '',
        gridColumns: ['name', 'power','report'],
        gridData: [
          { name: 'Chuck s', power: Infinity },
          { name: 'Bruce Lee', power: 9000 },
          { name: 'Jackie Chan', power: 7000 },
          { name: 'Jet Li', power: 8000 ,report: '<a href="http://www.google.com>Google</a>"'}
        ]
      }
    })

HTML file:

<script type="text/x-template" id="grid-template">
  <table>
    <thead>
      <tr>
        <th v-for="key in columns"
          @click="sortBy(key)"
          :class="{ active: sortKey == key }">
          {{ key | capitalize }}
          <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
          </span>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="entry in filteredData">
        <td v-for="key in columns">
          {{entry[key]}}
        </td>
      </tr>
    </tbody>
  </table>
</script>

<!-- demo root element -->
<div id="demo">
  <form id="search">
    Search <input name="query" v-model="searchQuery">
  </form>
  <demo-grid
    :data="gridData"
    :columns="gridColumns"
    :filter-key="searchQuery">
  </demo-grid>
</div>

Answer №1

If you want to properly interpret the content, you can utilize the v-html directive like this:

<td v-for="key in columns" v-html="entry[key]">

Note: Ensure to handle the quotation marks properly here:

{ name: 'Jet Li', power: 8000 ,report: '<a href="http://www.google.com">Google</a>'}

Vue.component('demo-grid', {
  template: `<table>
    <thead>
      <tr>
        <th v-for="key in columns"
          @click="sortBy(key)"
          :class="{ active: sortKey == key }">
          {{ key | capitalize }}
          <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
          </span>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="entry in filteredData">
        <td v-for="key in columns" v-html="entry[key]">
        
        </td>
      </tr>
    </tbody>
  </table>`,
  props: {
    data: Array,
    columns: Array,
    filterKey: String
  },
  data: function() {
    var sortOrders = {}
    this.columns.forEach(function(key) {
      sortOrders[key] = 1
    })
    return {
      sortKey: '',
      sortOrders: sortOrders
    }
  },
  computed: {
    filteredData: function() {
      var sortKey = this.sortKey
      var filterKey = this.filterKey && this.filterKey.toLowerCase()
      var order = this.sortOrders[sortKey] || 1
      var data = this.data
      if (filterKey) {
        data = data.filter(function(row) {
          return Object.keys(row).some(function(key) {
            return String(row[key]).toLowerCase().indexOf(filterKey) > -1
          })
        })
      }
      if (sortKey) {
        data = data.slice().sort(function(a, b) {
          a = a[sortKey]
          b = b[sortKey]
          return (a === b ? 0 : a > b ? 1 : -1) * order
        })
      }
      return data
    }
  },
  filters: {
    capitalize: function(str) {
      return str.charAt(0).toUpperCase() + str.slice(1)
    }
  },
  methods: {
    sortBy: function(key) {
      this.sortKey = key
      this.sortOrders[key] = this.sortOrders[key] * -1
    }
  }
})

// bootstrap the demo
var demo = new Vue({
  el: '#demo',
  data: {
    searchQuery: '',
    gridColumns: ['name', 'power', 'report'],
    gridData: [{
        name: 'Chuck s',
        power: Infinity
      },
      {
        name: 'Bruce Lee',
        power: 9000
      },
      {
        name: 'Jackie Chan',
        power: 7000
      },
      {
        name: 'Jet Li',
        power: 8000,
        report: '<a href="http://www.google.com">Google</a>'
      }
    ]
  }
})
<html>

<head>
  <meta name="description" content="Vue.delete">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.min.js"></script>
</head>

<body>
  <div id="demo">
    <!-- Grid template will be displayed here -->

    <!-- Root element for the demo -->
    <div id="demo">
      <form id="search">
        Search <input name="query" v-model="searchQuery">
      </form>
      <demo-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery">
      </demo-grid>
    </div>
  </div>
</body>

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

Avoid running another process before the current one finishes in jQuery

I have a situation where I am using $.ajax inside a for loop in jQuery. for(var i=0; i < 2; i++) { $.ajax({ url :"/models/getdata"+i, dataType:"json", success:function(data) { } }); } The issue is that before the success function for i=0 completes, ...

Vuex getter not reflecting changes in filter after modifying state array

I am currently working on a to-do application where I have implemented a button to toggle the checked/completed state of all todos. However, I have encountered an issue where although I am mutating an array of the state, the getters are not updating accord ...

Learn the process of extracting an array of objects by utilizing an interface

Working with an array of objects containing a large amount of data can be challenging. Here's an example dataset with multiple key-value pairs: [{ "id": 1, "name":"name1", age: 11, "skl": {"name": & ...

The function forEach is unable to handle the process of uploading multiple images to cloudinary

I'm facing an issue with uploading multiple images to Cloudinary from my Vue2JS front-end. I have successfully created a function that uploads a single image, but I am struggling with uploading multiple images using a forEach loop. upload(evt) { ...

Verify the presence of an image

I have a code snippet that I use to refresh an image in the browser. However, I want to enhance this code so that it first checks if the image exists before displaying it. If the image does not exist, I want to display the previous version of the picture i ...

Issue with Vue class binding failing to update when state is modified

I'm attempting to utilize Vue class binding depending on the index within the v-for loop. While I can see that the state in Vue dev tools is changing correctly, the class name itself isn't being updated. <div class="group" v-for= ...

Establishing a connection to a JSON API to retrieve and process

I am trying to extract all instances of names from this page: . For guidance, I have been using this tutorial as a reference: . However, when I run the code provided, it doesn't return anything. What could be going wrong? var request = new XMLHttpRe ...

javascript authorization for iframes

I am currently working on a localhost webpage (parent) that includes an iframe displaying content from another url (child; part of a different webapp also on localhost). My goal is to use JavaScript on the parent-page to inspect the contents of the iframe ...

Enable next-i18next to handle internationalization, export all pages with next export, and ensure that 404 error pages are displayed on non-generated pages

After carefully following the guidelines provided by i18next/next-i18next for setting up i18n and then referring to the steps outlined in this blog post on locize on how to export static sites using next export, I have managed to successfully generate loca ...

What could be causing the state to continuously appear as null in my redux application?

Currently, I am in the process of developing a basic contacts application to gain expertise in React and Redux. The main focus right now is on implementing the feature to add a new contact. However, I have encountered an issue where the state being passed ...

Unable to store cookie using jQuery on Internet Explorer 9

Having trouble setting a cookie on IE9 and can't figure out why. My objective is to create a cookie that expires after a year, using the code below: $.cookie( name, value, { expires:days } ) where days equals 365. However, the cookie disappears as s ...

Issue with symbol not functioning on different device

There seems to be a display issue with the ...

What are the steps to correctly implement async await in a standard sequence?

When I press the button onPress={() => Login()} First, I need to obtain a token by using the signInWithKakao function. Secondly, right after acquiring the token, if it is available, I want to dispatch the profile using the kakaoprofile function. However, ...

The server nodejs is unable to recognize the dotenv file

This is my very first project with the MERN stack and I'm currently working on pushing it to GitHub. Since I am using Mongoose, I needed to protect the login credentials for my account. After some research, I discovered the solution of using a .env fi ...

methods for transferring information from a website to a smartphone using SMS

I am currently in the early stages of learning JavaScript and working on a project that involves creating a form (a web page) to send data to my mobile device via SMS when the submit button is clicked. However, I am unsure how to transfer data from JavaS ...

Having difficulty in closing Sticky Notes with JavaScript

Sticky Notes My fiddle code showcases a functionality where clicking on a comment will make a sticky note appear. However, there seems to be an issue with the Close Button click event not being fired when clicked on the right-hand side of the note. I have ...

Is there a way to effectively incorporate react-native with php and ensure that the data returned by the fetch function is

I'm struggling to make my return value work in this code. Has anyone had success using react-native with php and fetch json? Any tips or advice would be greatly appreciated. PHP $myArray = array(); $myArray['lat'] = $_POST['lat']; ...

tips for setting the value of a checkbox to true in React Material-UI with the help of React Hooks

<FormControlLabel onChange={handleCurrentProjectChange} value="end" control={<Checkbox style={{ color: "#C8102E" }} />} label={ <Typography style={{ fontSize: 15 }}> C ...

The HTML function transforms blank spaces into the symbol "+"

Just starting out with a question: I created a basic submission form, but I noticed that if there are any spaces in the inputs, the values get changed to a plus sign (+). Here's my form: <form name="input" action="search" method="get"> Web Ad ...

Why does the header still show content-type as text/plain even after being set to application/json?

When using fetch() to send JSON data, my code looks like this: var data = { name: this.state.name, password: this.state.password } fetch('http://localhost:3001/register/paitent', { method: 'POST&a ...