Категория vuejs и фильтр ключевых слов - PullRequest
0 голосов
/ 02 октября 2018

Привет, ребята, я уже давно занимаюсь этим. Я пытаюсь отфильтровать свои шаблоны по категориям и ключевым словам с помощью кнопок.У меня есть приложение vuejs, которое использует метод фильтра.Это работает очень хорошо, за исключением случаев, когда у меня не выбрано ни одного ключевого слова и я начал выбирать несколько категорий.Например, у меня есть шаблон с именем test, который связан как с категорией спорта, так и с категорией отдыха.Когда оба выбраны, я получаю дубликат.Я очень близок к этому, я только что застрял в этой части в течение недели.Я понимаю, что это много кода, но он чистый, читаемый и не имеет смысла, если я не дам вам обзор.

Вот скрипка с кодом https://jsfiddle.net/rshba6jz/

Вот интерфейсcode

<?php require_once('header.php');
require_once('database.php');

if ($result = $mysqli->query("SELECT t.*, GROUP_CONCAT(c.category) categories, GROUP_CONCAT(k.keyword) keywords FROM dataclayTemplates t LEFT JOIN dataclayCategoryLink cl JOIN dataclayCategories c ON cl.categoryId=c.id ON t.id=cl.templateId LEFT JOIN dataclayKeywordLink kl JOIN dataclayKeywords k ON kl.keywordId=k.id ON t.id=kl.templateId GROUP BY t.id"))
{
  while($row = $result->fetch_array(MYSQLI_ASSOC)) {
    if($row["categories"] == null) {
      $row["categoryArray"] = [];
    } else {
      $row["categoryArray"] = array_unique(explode(",",$row["categories"]));
    }
    unset($row["categories"]);
    if($row["keywords"] == null) {
      $row["keywordArray"] = [];
    } else {
      $row["keywordArray"] = array_unique(explode(",",$row["keywords"]));
    }
    unset($row["keywords"]);
    $templateArray[] = $row;
  }
}

$result->close();

$categoryArray = array();

if ($result = $mysqli->query("SELECT category FROM dataclayCategories;"))
{
  while($row = $result->fetch_array(MYSQLI_ASSOC)) {
    array_push($categoryArray, $row['category']);
  }
}

$result->close();

$keywordArray = array();

if ($result = $mysqli->query("SELECT keyword FROM dataclayKeywords;"))
{
  while($row = $result->fetch_array(MYSQLI_ASSOC)) {
    array_push($keywordArray, $row['keyword']);
  }
}

$result->close();

$mysqli->close();


?>
<div v-cloak id="templates" class="container content">

    <div class="col-lg-3 visible-lg-block hidden-md" id="SearchTemplatesLargeContainer">
        <form role="form" role="form" onsubmit="return false">
            <div class="form-group">
                <label for="searchBar">Search</label>
                <input v-model="searchQuery" type="text" placeholder="Search Tempates" id="searchBar" autocomplete="off" class="form-control">
            </div>
            <div class="form-group">
                <label>Sort By</label>
                <select v-model="sortBy" class="form-control">
          <option value="renderTime">Render Time</option>
          <option value="az">A-Z</option>
          <option value="dateAdded">Newest</option>
        </select>
            </div>
            <div class="form-group">
                <h5>Categories</h5>
                <div v-for="category in categories" :class="category + 'Button'" v-on:click.prevent="selectCategory(category)" class="btn btn-default categoryButton">
                    {{category}}
                </div>
            </div>
            <div class="form-group">
                <h5>Keywords</h5>
                <div v-for="keyword in keywords" :class="keyword + 'Button'" v-on:click.prevent="selectKeyword(keyword)" class="btn btn-default categoryButton">
                    {{keyword}}
                </div>
            </div>
        </form>
    </div>
    <!--end lg template menu col-lg-3-->

    <!--search templates modal-->
    <div class="modal fade" role="dialog" id="searchTemplatesModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">X</button>
                    <h2 class="modal-title">Search Templates</h2>
                    <!--end .modal-title-->
                </div>
                <!--end modal-header-->
                <div class="modal-body">
                    <form role="form">
                        <div class="form-group">
                            <label>Search</label>
                            <input v-model="searchQuery" type="text" placeholder="Search Tempates" autocomplete="off" class="form-control">
                        </div>
                        <!--.end searchQuery-->
                        <div class="form-group">
                            <label>Sort By</label>
                            <select v-model="sortBy" class="form-control">
                                <option value="renderTime">Render Time</option>
                                <option value="az">A-Z</option>
                                <option value="dateAdded">Newest</option>
                        </select>
                        </div>
                        <!--end sortBy-->
                        <div class="form-group">
                            <h5>Categories</h5>
                            <div v-for="category in categories" :class="category + 'Button'" v-on:click.prevent="selectCategory(category)" class="btn btn-default categoryButton">
                                {{category}}
                            </div>
                        </div>
                        <!--end categorys-->
                        <div class="form-group">
                            <h5>Keywords</h5>
                            <div v-for="keyword in keywords" :class="keyword + 'Button'" v-on:click.prevent="selectKeyword(keyword)" class="btn btn-default categoryButton">
                                {{keyword}}
                            </div>
                        </div>
                        <!--end keywords-->
                    </form>
                </div>
                <!--end .modal-body-->

                <div class="modal-footer">
                    <button type="button" class="btn btn-primary btn-block" data-dismiss="modal">Search</button>
                </div>
                <!--end .modal-footer-->
            </div>
            <!--end .modal-content-->
        </div>
        <!--end .modal-dialog-->
    </div>
    <!-- end search templates modal-->
    <div class="col-lg-9 col-md-12 col-sm-12 col-xs-12">
        <div class="row">
            <h1 class="mainHeading">Templates</h1>
        </div>
        <div class="row">
            <div v-cloak v-bind:key="template.itemId + '_' + index" v-for="(template, index) in searchResults" class="col-md-4">
                <div class="card">
                    <video muted :src="mysource" controls preload="none" controlsList="nodownload nofullscreen" :poster="mysouce" loop="loop"></video>
                    <div class="card-body">

                        <p class="card-title">{{template.itemName}}</p>
                        <!--end card-title-->
                        <p v-show="displayCount==0" class="card-text">Please create a display to customize</p>
                        <!--end user has no display card-text-->
                        <p v-show="displayCount>0" class="card-text">Custom Text, Custom Colors, Upload Logo</p>
                        <!--end user has display card text-->
                        <p class="card-text">{{template.renderTime}} minutes</p>
                        <a href="#" v-show="loggedIn==true && displayCount>0" class="btn btn-primary btn-block">Customize</a>
                        <!--logged in and has display button-->
                        <a href="#" v-show="loggedIn==false" class="btn btn-primary btn-block" disabled>Customize</a>
                        <!--not logged in button-->
                        <a href="profile.php?showAddDisplayForm=1" v-show="loggedIn==true && displayCount==0" class="btn btn-primary btn-block">Create A Display</a>
                    </div>
                    <!--end card-body-->
                </div>
                <!--end card-->
            </div>
            <!-- end col-md-4-->
        </div>
        <!--end row-->
    </div>
    <!--end col-lg-9 col-md-12 col-sm-12 col-xs-12-->
</div>
<!--end templates app-->
<script>
var app = new Vue({
  el: '#templates',
  data: {
    loggedIn: false,
    displayCount:'<?php if(isset($_SESSION['displayCount'])){echo $_SESSION['displayCount'];} else{echo 0;}?>',
    searchQuery:'',
    templateArray: <?php echo json_encode($templateArray); ?>,
    filteredTemplateArray: <?php echo json_encode($templateArray); ?>,
    categories: <?php echo json_encode($categoryArray); ?>,
    selectedCategories: [],
    keywords: <?php echo json_encode($keywordArray); ?>,
    selectedKeywords: [],
    sortBy: ''
  },
  computed: {
      searchResults: function(){
          return this.filteredTemplateArray.filter((template)=>{
            return template.itemName.toLowerCase().includes(this.searchQuery.toLowerCase());
          })
      }
  },
  created: function() {
    this.loggedIn=<?php if(isset($_SESSION['loggedIn'])){echo $_SESSION['loggedIn'];} else {echo 0;}?>;
    this.filteredTemplateArray.sort(function(a,b) {
      return parseInt(a.renderTime) - parseInt(b.renderTime);
    });
  },
  watch: {
    sortBy: function() {
      if(this.sortBy == "az") {
        this.filteredTemplateArray.sort(function(a,b) {
          if(a.itemName > b.itemName) {
            return 1;
          }
          if(a.itemName < b.itemName) {
            return -1;
          }
          return 0;
        });
      }

      if(this.sortBy == "dateAdded") {
        this.filteredTemplateArray.sort(function(a,b) {
          if(a.dateAdded < b.dateAdded) {
            return 1;
          }
          if(a.dateAdded > b.dateAdded) {
            return -1;
          }
          return 0;
        });
      }

      if(this.sortBy == "renderTime") {
        this.filteredTemplateArray.sort(function(a,b) {
          return parseInt(a.renderTime) - parseInt(b.renderTime);
        });
      }
    }
  },
  mounted: function(){
      this.sortBy="renderTime";
  },
  methods: {
    filter: function() {
      var filteredCategoryArray = [];
      var filteredKeywordArray = [];
      if(this.selectedCategories.length != 0) {
        for(var i = 0; i < this.templateArray.length; i++) {
          for(var j = 0; j < this.selectedCategories.length; j++ ) {
            for(var k = 0; k < this.templateArray[i].categoryArray.length; k++ ) {
              if(this.templateArray[i].categoryArray[k] == this.selectedCategories[j]) {
                  console.log(this.templateArray[i].categoryArray[k]);
                  console.log(this.selectedCategories[j]);
                var arrayDuplicate = false;
                for(var l = 0; l < filteredKeywordArray.length; l++) {
                  if(filteredCategoryArray[l].id == this.templateArray[i].id) {
                    arrayDuplicate = true;
                  }
                }
                if(arrayDuplicate == false) {
                  filteredCategoryArray.push(this.templateArray[i]);
                }
              }
            }
          }
        }
      } else {
        for(var i = 0; i < this.templateArray.length; i++){
          filteredCategoryArray.push(this.templateArray[i]);
        }
      }

      if(this.selectedKeywords.length != 0) {
        for(var i = 0; i < filteredCategoryArray.length; i++) {
          for(var j = 0; j < this.selectedKeywords.length; j++ ) {
            for(var k = 0; k < filteredCategoryArray[i].keywordArray.length; k++ ) {
              if(filteredCategoryArray[i].keywordArray[k] == this.selectedKeywords[j]) {
                var arrayDuplicate = false;
                for(var l = 0; l < filteredKeywordArray.length; l++) {
                  if(filteredKeywordArray[l].id == filteredCategoryArray[i].id) {
                    arrayDuplicate = true;
                  }
                }
                if(arrayDuplicate == false) {
                  filteredKeywordArray.push(filteredCategoryArray[i]);
                }
              }
            }
          }
        }
      } else {
        for(var i = 0; i < filteredCategoryArray.length; i++){
          filteredKeywordArray.push(filteredCategoryArray[i]);
        }
      }
      if(this.sortBy == "az") {
        filteredKeywordArray.sort(function(a,b) {
          if(a.itemName > b.itemName) {
            return 1;
          }
          if(a.itemName < b.itemName) {
            return -1;
          }
          return 0;
        });
      }

      if(this.sortBy == "dateAdded") {
        filteredKeywordArray.sort(function(a,b) {
          if(a.dateAdded < b.dateAdded) {
            return 1;
          }
          if(a.dateAdded > b.dateAdded) {
            return -1;
          }
          return 0;
        });
      }

      if(this.sortBy == "renderTime") {
        filteredKeywordArray.sort(function(a,b) {
          return parseInt(a.renderTime) - parseInt(b.renderTime);
        });
      }

      this.filteredTemplateArray = filteredKeywordArray;
      $('html,body').scrollTop(0);
    },
    selectCategory: function(category) {
      var categoryButton = $('.' + category + 'Button');
      categoryButton.toggleClass('categoryButtonSelected');
      if(this.selectedCategories.includes(category)){
        var array = [];
        for(var i = 0; i < this.selectedCategories.length; i++) {
          if(this.selectedCategories[i] != category) {
            array.push(this.selectedCategories[i]);
          }
        }
        this.selectedCategories = array;
      } else {
        this.selectedCategories.push(category);
      }
      this.filter();
    },
    selectKeyword: function(keyword) {
      var categoryButton = $('.' + keyword + 'Button');
      categoryButton.toggleClass('categoryButtonSelected');
      if(this.selectedKeywords.includes(keyword)){
        var array = [];
        for(var i = 0; i < this.selectedKeywords.length; i++) {
          if(this.selectedKeywords[i] != keyword) {
            array.push(this.selectedKeywords[i]);
          }
        }
        this.selectedKeywords = array;
      } else {
        this.selectedKeywords.push(keyword);
      }
      this.filter();
    }
  }
});
</script>

У меня есть, когда щелкают по шаблону, это то, что передается в мой FilterTemplateArray в Инспекторе vue.Если есть несколько элементов с одинаковым идентификатором (в данном случае 223, я бы хотел, чтобы они были отфильтрованы, чтобы не было дубликатов. Он отлично работает с ключевыми словами, но не работает с категориями. Я уверен, что это просто, но я действительно застрял и некоторая помощьбыло бы здорово.

    filteredTemplateArray:Array[1]
0:Object
categoryArray:Array[3]
0:"Misc"
1:"Holiday"
2:"Sports"
dateAdded:"2018-10-01 17:54:22"
id:"233"
itemId:"fb41a01641bb2e769db412d3b21c2e3e"
itemName:"test"
keywordArray:Array[2]
0:"Snow"
1:"LensFlare"
projectPath:"M:/Projects/Generics/uploads/testLocation"
renderTime:"4"
stillImageLocation:"0.13"
tested:"0"
thumbName:"TEST"

1 Ответ

0 голосов
/ 18 октября 2018

создать наблюдатель, который следит за selectedCategories и при его изменении запускает метод, который отфильтровывает дубликаты и устанавливает отфильтрованные категории обратно в исходный массив, когда selectedCategories.length == 0.Это создает фильтр категории, который считает.например, если отмечены спортивные и праздничные дни, будут показаны только все элементы в спорте и все элементы в праздничные дни, которые, кажется, работают лучше, чем обратный отсчет или те, которые существуют только в обоих.Я использую приложение вместо этого в качестве переменной, которую я назвал своим экземпляром vue, и потому что, когда вы углубляетесь в функцию, это не всегда означает приложение.

    watch: {
      selectedCategories(){
          this.categoryFilter();
      },
          sortBy(){
              this.sortTemplatesBy();
          }
    },
  methods: {
            sortTemplatesBy: function(){ 
      if(this.sortBy == "az") {
        this.filteredTemplateArray.sort(function(a,b) {
          if(a.itemName > b.itemName) {
            return 1;
          }
          if(a.itemName < b.itemName) {
            return -1;
          }
          return 0;
        });
      }

      if(this.sortBy == "dateAdded") {
        this.filteredTemplateArray.sort(function(a,b) {
          if(a.dateAdded < b.dateAdded) {
            return 1;
          }
          if(a.dateAdded > b.dateAdded) {
            return -1;
          }
          return 0;
        });
      }

      if(this.sortBy == "renderTime") {
        this.filteredTemplateArray.sort(function(a,b) {
          return parseInt(a.renderTime) - parseInt(b.renderTime);
        });
      }
    },
      categoryFilter: function(){
          if(app.selectedCategories.length!=0){
          app.filteredTemplateArray=[];
          var templateArray = app.templateArray;
          for(i=0; i<app.selectedCategories.length; i++){
              var filtered=templateArray.filter(function(template){
                  var currentCategory=app.selectedCategories[i];
                  console.log("this is current category"+currentCategory+"end currentCategory");
                  var returnValue=template.categoryArray.includes(currentCategory);
                  console.log("this is i"+i+"end i");
                  console.log("this is return value"+returnValue+"end return value");
                  return returnValue;
              });
              console.log(filtered);
              app.filteredTemplateArray=app.filteredTemplateArray.concat(filtered);

      }
          var uniqueArray=[];
          var allResultsArray=app.filteredTemplateArray;
          for(j=0; j<allResultsArray.length; j++){
              if(uniqueArray.indexOf(allResultsArray[j]) == -1){
                  uniqueArray.push(allResultsArray[j])
              }
          }
          app.filteredTemplateArray=uniqueArray;
      } else {app.filteredTemplateArray=app.templateArray;}
          this.sortTemplatesBy();
      }
  }
...