9

I have a input (top right) where users can search things, when it's directive length get 3 characters it will display a list of products and highlight the matches...

Look at my code:

html

<div id="app">
  <div id="header">
    <div class="right"><input type="text" v-model="message" v-on:keyup="searchStart()" v-on:blur="searchLeave()"/>
      <ul v-if="this.searchInput" class="product-list">
      <li v-for="product in products">
        {{ product.id }} - {{ product.name | highlight }} - {{ product.qtd }}</li></ul>
    </div>
  </div>
  <div id="main">
    <div id="menu">fdfds</div>
    <div id="container">{{ message }}</div>
  </div>
</div>

js

var search = new Vue({
  el: "#app",
  data: {
    message: "",
    searchInput: false,
    products: [
      {
        id: 1,
        name: "produto 01",
        qtd: 20
      },
      {
        id: 2,
        name: "produto 02",
        qtd: 40
      },
      {
        id: 3,
        name: "produto 03",
        qtd: 30
      },
    ]
  },
  methods: {
    searchStart: function(){
      if(this.message.length >= 3)
        this.searchInput = true;
      console.log(this.searchInput);
    },
    searchLeave: function(){
      this.searchInput = false;
      this.message = "";
      console.log(this.searchInput);
    }
  },
  filters: {
    highlight: function(value){
      return value.replace(search.message, '<span class=\'highlight\'>' + search.message + '</span>');
    }
  }
});

Here you can see a live pen: http://codepen.io/caiokawasaki/pen/dXaPyj

try to type prod inside the pen...

Is my filter correct? The way I created the filter is correct?

The main question is: How to output the HTML from my filter?

Edit/Solution

The problem in the case was codepen, there is some kind of conflict with vue, so I was not able to escape the html using {{{}}}, put the code in another editor (jsfidle) and it worked.

I'm accepting the answer given to the reward because it's right.

Caio Kawasaki
  • 2,894
  • 6
  • 33
  • 69
  • The Vue documentation suggests you should be able to use triple bracks — {{{ variable }}} — to display unescaped HTML. When I try updating the HTML to use triple brackets though it throws an error. There's even another Stackoverflow question where this was accepted as the solution: http://stackoverflow.com/questions/30877491/vue-display-unescaped-html – George Mandis Aug 12 '16 at 20:11
  • Looking more closely at your code, is there any reason you couldn't do this in your template: {{ product.id }} - {{ product.name }} - {{ product.qtd }} It doesn't solve the problem of displaying unescaped HTML from within your template, but it does seem to achieve what you're going for here. – George Mandis Aug 12 '16 at 20:17
  • @GeorgeMandis I just want to highlight the string from the message model, and not the entire name... Get it? This is diving-me crazyy – Caio Kawasaki Aug 12 '16 at 20:46
  • Hi Caio, I couldn't figure out what was wrong with your code. What I did is open a `jsfiddle` (I don't like to work with `codepen`), get a working example, and move my way up from there. It's not a solution, but hopefully it will be a starting point: https://jsfiddle.net/oajqg1n5/11/ –  Aug 15 '16 at 06:32
  • Just use tripple braces [fiddle demo](https://jsfiddle.net/s6paku9r/) – Bogdan Kuštan Aug 15 '16 at 15:49

1 Answers1

2

You'll need 3 steps here for achieve what you want:

  • Use triple braces {{{ }}} to display unescaped html
  • Filter your users by your v-model variable, in order to just show the matches
  • Replace the substring matching by the <span> tag

Check out the computed property filteredUsers and the filter in this working jsfiddle

Alex JM
  • 1,084
  • 2
  • 11
  • 32