1

I made an input search to filter a list of users that is called with PHP. I'm trying to implement in Vue.js the filter so that when I search the name, the user appears filtered in the list.

Here is the searchbar HTML:

<div class="row" id="toprow">
          <div class="col-md-6">
              <div id="titlerow1">Users</div>
          </div>

          <div class="col-md-6">
                  <input class="searchbar" id="search1" placeholder="Search..."></input>
          </div>
</div> 

The users list HTML:

<div id="users" name="users">
                        <?php   if(!empty($user))
                        { 
                            foreach($user as $value) 
                            { 
                            ?>
                                <div class="row oddEven usersElements userid" id=<?php echo $value->id;?> style="margin-top: -1vw;">
                                    <div v-on:click="displayAgregators(<?php echo $value->id;?>)" class="col-md-10">
                                        <span id="items<?php echo $value->id;?>"><?php echo ucfirst($value->username);?></span>
                                    </div>
                                    <div class="col-md-2">
                                        <div class="colorsByUser" :style="{backgroundColor: randomColor()}"></div>
                                    </div>
                                </div>
                            <?php } 
                        }?>
                    </div>

Before it was in jQuery, here is the code:

$('#search1').keyup(function() {
    var string1 = $(this).val().toLowerCase();
    console.log("str1=" + string1);
    $(".usersElements").each(function(index) {
        var string = $(this).attr('id');
        var string2 = $('#' + string).text().toLowerCase();
        console.log("str2=" + string2);
        var valtest = string2.indexOf(string1);
        console.log("index value:" + valtest);
        if (valtest >= 0) {
            $('#' + string).show();
        } else {
            $('#' + string).hide();
        }
    });
});

I hope you guys can help! :)

Timmy
  • 165
  • 4
  • 18
  • Is there any way you can request the data as data, rather than having PHP embed data in HTML from which you have to extract it? It would be much more Vue-ish. – Roy J May 17 '17 at 17:21
  • I didn't understand completely what you meant about the data thingy :/ – Timmy May 17 '17 at 18:01
  • Vue would like to have an array of users and render the list of them in the HTML. But the users only exist as a mess of HTML generated by PHP, so you have to extract strings out of HTML to get data to work with. It would be much much better for Vue to be able to request the user data from the server. – Roy J May 17 '17 at 18:14
  • Maybe something here will help: http://stackoverflow.com/a/23740549/392102 – Roy J May 17 '17 at 18:16
  • Ah, okay i see what you mean. Unfortunately, this code was already implemented with PHP, so i can't use $.ajax() for the content request :/ – Timmy May 17 '17 at 18:18

1 Answers1

0

Since you're stuck with PHP generating stuff, probably the best you can do is make each row a component. The HTML will look about like this:

<div id="users" name="users">
  <?php if(!empty($user)) { 
          foreach($user as $value)  { 
  ?>
  <user-component
   name="<?php echo ucfirst($value->username);?>"
   id="<?php echo $value->id;?>"
   :match-pattern="searchPattern"
  ></user-component>
  <?php    } 
         }
  ?>
</div>

The template for your component will look about like this:

  <div v-show="matches()" class="row oddEven usersElements userid" style="margin-top: -1vw;">
    <div v-on:click="displayAgregators(id)" class="col-md-10">
      <span>{{name}}</span>
    </div>
    <div class="col-md-2">
      <div class="colorsByUser" :style="{backgroundColor: randomColor()}"></div>
    </div>
  </div>

and it will take three props: name and id come from the PHP stuff, while match-pattern comes from your parent Vue. it will have a method (or a computed) that tests whether it matches the pattern. Something like

matches() {
  return this.name.toLowerCase().includes(this.matchPattern);
}

Your search bar should have v-model="searchPattern", and you should of course define a searchPattern variable in your Vue.

Roy J
  • 42,522
  • 10
  • 78
  • 102