Skip to content

Commit 5ca4f69

Browse files
committed
FilterData.vue reusable component added
1 parent b9ab562 commit 5ca4f69

File tree

16 files changed

+259
-91
lines changed

16 files changed

+259
-91
lines changed

README.md

+167-8
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
npm run watch
99
```
1010

11-
> ## How to Sorting , Paginating and Filtering
11+
> ## <h2 style="color:green;background:#eee;padding-left:13px;"> How to Sorting , Paginating and Filtering </h2>
1212
</br>
1313
14-
#### Step-1: Pagination.vue
14+
### Step-1: Pagination.vue
1515
``` javascript
1616
[...]
1717
<template>
@@ -40,7 +40,7 @@
4040
</script>
4141

4242
```
43-
#### Step - 2: State Management
43+
### Step - 2: State Management
4444
``` js
4545
export default {
4646
state: {
@@ -123,7 +123,7 @@ export default {
123123

124124
[![View Added Image](docs/images/pagination.png)](docs/images/pagination.png)
125125

126-
* #### Step-3 Backend
126+
* ### Step-3 Backend
127127
``` php
128128
// web.php
129129
[...]
@@ -187,8 +187,7 @@ class CategoryController extends Controller
187187
}
188188
}
189189
```
190-
#### Now Test in browser :smile:
191-
190+
### Now Test in browser :smile:
192191

193192
### Reusable Single File Pagination Component
194193
```js
@@ -247,11 +246,171 @@ export default {
247246
}
248247
[...]
249248
```
249+
# <h2 style="color: #2f6;backgroundd:#333;padding-left:15px;">Filtering , Searching & Sorting via VueX </h2>
250+
>Reusable FilterData.vue File
251+
252+
``` javascript
253+
<template>
254+
<Card translate="bn" type="primary">
255+
<Row>
256+
<Col span="5" class="mr-2">
257+
<form class="form-inline ml-3 mb-4" @submit.prevent="getResult">
258+
<div class="input-group input-group-sm">
259+
<input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search" v-model="defaultFilter.q" >
260+
<div class="input-group-append">
261+
<button class="btn btn-navbar" type="submit">
262+
<i class="fas fa-search"></i>
263+
</button>
264+
</div>
265+
</div>
266+
</form>
267+
</Col>
268+
<Col span="5" class="mr-2">
269+
<i-select v-model="defaultFilter.orderBy" style="width:200px">
270+
<i-option v-for="item in orderList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
271+
</i-select>
272+
</Col>
273+
<Col span="5" class="mr-2">
274+
<Select v-model="defaultFilter.sortBy" >
275+
<Option v-for="(sort,i) in SortList" :key="i" :value="sort.value"> {{ sort.label }} </Option>
276+
</Select>
277+
</Col>
278+
<Col span="5" class="mr-2">
279+
<Select v-model="defaultFilter.perPage">
280+
<Option v-for="(per,i) in perPageList" :key="i" :value="per.value"> {{ per.label }} </Option>
281+
</Select>
282+
</Col>
283+
<Col span="3">
284+
<Button type="default" @click="getResult" icon="ios-settings"> Filter </Button>
285+
</Col>
286+
</Row>
287+
</Card>
288+
</template>
289+
290+
<script>
291+
export default {
292+
name : "FilterData" ,
293+
props:{
294+
defaultFilter: Object,
295+
getResult: [Function]
296+
},
297+
data(){
298+
return {
299+
perPageList : [{
300+
label : "5 Per Page" ,
301+
value : 5
302+
},
303+
{
304+
label : "10 Per Page" ,
305+
value : 20
306+
},
307+
{
308+
label : "20 Per Page" ,
309+
value : 20
310+
},
311+
{
312+
label : "30 Per Page" ,
313+
value : 30
314+
},
315+
{
316+
label : "40 Per Page" ,
317+
value : 40
318+
},
319+
{
320+
label : "50 Per Page" ,
321+
value : 50
322+
},
323+
{
324+
label : "80 Per Page" ,
325+
value : 80
326+
},
327+
{
328+
label : "100 Per Page" ,
329+
value : 100
330+
},
331+
{
332+
label : "200 Per Page" ,
333+
value : 200
334+
}],
335+
orderList : [{ label : "ID" ,value : "id" },
336+
{label : "Name" ,value : "name" },
337+
{ label : "Date" ,value : "created_at"}],
338+
SortList : [{
339+
label : "Ascending" ,
340+
value : "asc"
341+
},
342+
{
343+
label : "Descending" ,
344+
value : "desc"
345+
}]
346+
}
347+
}
348+
}
349+
</script>
350+
```
351+
> OUTPUT of FilterData.VUE
352+
[![Filter Data View](docs/images/FilterData.vue.png)](docs/images/FilterData.vue.png)
250353

251-
> Now Preparing project for Localization & Translating
354+
> Categories.vue
355+
``` js
356+
<template>
357+
<div class="content bg-transparent">
358+
<div class="container-fluid">
359+
<filter-data
360+
:defaultFilter="filterString"
361+
:getResult="getCategories" ></filter-data>
362+
<!--~~~~~~~ TABLE ONE ~~~~~~~~~-->
363+
<div class="card p-2">
364+
365+
<p class="card-title ml-3">Categories
366+
<!-- adding modal -->
367+
<add-modal-component v-if="isPermitted('create','category')"></add-modal-component> </p>
368+
369+
<div class="card-body">
370+
<view-categories-component v-if="isPermitted('view','category')"></view-categories-component>
371+
</div>
372+
373+
<!-- edit Modal -->
374+
<edit-modal-component v-if="isPermitted('update','category')"></edit-modal-component>
375+
</div>
376+
377+
</div>
378+
</div>
379+
</template>
380+
381+
<script>
382+
import { mapActions, mapGetters } from 'vuex'
383+
import addModalComponent from "../component/addModalComponent"
384+
import editModalComponent from "../component/editModalComponent"
385+
import viewCategoriesComponent from '../component/viewCategoriesComponent';
386+
import FilterData from '../component/FilterData';
387+
388+
export default {
389+
components: {
390+
addModalComponent,
391+
editModalComponent,
392+
viewCategoriesComponent,
393+
FilterData
394+
},
395+
computed: {
396+
...mapGetters("categoriesStoreIndex",['filterString' ])
397+
},
398+
methods:{
399+
...mapActions("categoriesStoreIndex", ['getCategories'])
400+
}
401+
}
402+
403+
</script>
404+
```
405+
406+
> OUTPUT
407+
[![ GET FILTER RESULT](docs/images/filter_result.png)](docs/images/filter_result.png)
408+
409+
> <p style="color:yellow;font-size:20px;">Now Preparing project for Localization & Translating</p>
252410
253411
Run this npm command
254412

255413
npm install vue-i18n vuex-persistedstate
256414

257-
415+
# Here is final output of categories.vue
416+
[![Categories OUTPUT](docs/images/categories.vue.png)](docs/images/categories.vue.png)

app/Http/Controllers/Admin/CategoryController.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,15 @@ public function store(Request $request)
4848
}
4949
public function multiDelete(Request $request)
5050
{
51-
if (Gate::forUser(Auth::guard('admin')->user())->allows('multiDelete')) {
51+
if (Gate::forUser(Auth::guard('admin')->user())->allows('super')) {
5252
try {
5353
DB::beginTransaction();
5454
foreach ($request->all() as $category) {
55-
$this->deleteFileFromServer(public_path().$category['icon']);
55+
$this->deleteFileFromServer($category['icon']);
5656
Category::find($category['id'])->delete();
5757
}
5858
DB::commit();
59+
return response()->json(['message' => "SUCCESS"], 200);
5960
} catch (\Throwable $th) {
6061
DB::rollback();
6162
}
@@ -85,14 +86,17 @@ public function upload(Request $request){
8586
}
8687
public function deleteImage(Request $request)
8788
{
88-
$filePath = public_path().$request->image;
89+
$filePath = $request->image;
8990
$this->deleteFileFromServer($filePath);
9091
return "done";
9192
}
92-
public function deleteFileFromServer($filePath)
93+
public function deleteFileFromServer($filePath , $hasFullPath = false)
9394
{
95+
if(!$hasFullPath){
96+
$filePath = public_path().$filePath;
97+
}
9498
if (file_exists($filePath)) {
95-
@unlink($filePath);
99+
return @unlink($filePath);
96100
}
97101
return;
98102
}

app/Models/Category.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class Category extends Model
1818
public function scopeSearch($query , $q)
1919
{
2020
if($q == null) return;
21-
return $query->where('name','LIKE', "%$q%");
21+
return $query->where('name','LIKE', "%$q%")
22+
->orWhere('id','LIKE', "%$q%")
23+
->orWhere('created_at','LIKE', "%$q%")
24+
->orWhere('icon','LIKE', "%$q%");
2225
}
2326
}

docs/images/FilterData.vue.png

14 KB
Loading

docs/images/filter_result.png

23.1 KB
Loading

0 commit comments

Comments
 (0)