1

I wanted to display three different lists of json in a table. The first contains URLs, the second URLs to google maps and the last messages.

To render it I have a template like this:

<script type="text/x-template" id="grid-template">
  <table class="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">${isUrl(key,entry[key])}</td>
      </tr>
    </tbody>
  </table>
</script>


  Vue.component('demo-grid', {
    template: '#grid-template',
    delimiters: ['${', '}'],
    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
      },

      isUrl: function (key, str){
        if (key == "url"){
          var exp = /^((?:https?|ftp):\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/ig;
          return str.replace(exp,"<a :href='$1'>$1</a>");
        }
        else{
          console.log("ej")
          return str
        }
      }
    }

  })

I wanted to create a hyperlink when the columns' key name is "url", but vue auto-escapes this. How can I manage to replace text for a hyperlink?

An example of the data:

[{
  "date": "2017-08-09 18:25:06.226631", 
  "id": 5, 
  "private": true,
  "reviewed": false, 
  "title": "To Protect Voting, Use Open-Source Software - NYTimes.com", 
  "url": "j.mp/2upm633", 
  "user": 1
}]

1 Answer 1

4

You can format the url in the template like so:

<tr v-for="entry in filteredData">
  <td v-for="key in columns">
    <template v-if="key === 'url'">
      <a :href="entry[key]">${ entry[key] }</a>
    </template>
    <template v-else>
      ${ entry[key] }
    </template>
  </td>
</tr>
Sign up to request clarification or add additional context in comments.

1 Comment

didn't thought in that. So simple... Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.