Last active
May 3, 2017 14:55
-
-
Save davidtrushkov/5b58f0721c8b4686316dcd57ab74b000 to your computer and use it in GitHub Desktop.
Make a simple Vue JS and Laravel instant search
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HTML Part | |
<!doctype html> | |
<html lang="{{ config('app.locale') }}"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Laravel</title> | |
<!-- Fonts --> | |
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/sweetalert2/6.6.2/sweetalert2.min.css"> | |
<link href="/css/app.css" rel="stylesheet" type="text/css"> | |
<script> | |
window.Laravel = {!! json_encode([ | |
'csrfToken' => csrf_token(), | |
]) !!}; | |
</script> | |
</head> | |
<body> | |
@yield('content') | |
@if(Route::getCurrentRoute()->uri() == '/') | |
<div id="app"> | |
<div class="container search-content"> | |
<h4 class="text-center">Search Products</h4> | |
<search :users="{{ \App\User::all() }}" :starting-products="{{ \App\Product::all() }}"></search> | |
</div> | |
</div> | |
@endif | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/sweetalert2/6.6.2/sweetalert2.min.js"></script> | |
<script src="/js/app.js"></script> | |
</body> | |
</html> | |
// Component Part | |
<template> | |
<div> | |
<div class="col-xs-12"> | |
<input type="text" class="form-control" placeholder="Search Products..." v-model="searchP"> | |
<br /> | |
<button v-on:click="filterByPriceLowest" class="btn btn-default" v-bind:class="{ active: isActiveLow }"> | |
Price Lowest <i class="fa fa-arrow-circle-down" aria-hidden="true"></i> | |
</button> | |
<button v-on:click="filterByPriceHighest" class="btn btn-default" v-bind:class="{ active: isActiveHigh }"> | |
Price Highest <i class="fa fa-arrow-circle-up" aria-hidden="true"></i> | |
</button> | |
</div> | |
<div class="col-xs-12 no-padding"> | |
<div class="col-sm-4 user-box animated zoomIn" v-for="product in searchProducts"> | |
<div class="inner-user-box"> | |
<button class="btn btn-danger btn-xs" v-on:click="deleteProduct(product.id)"> | |
<i class="fa fa-trash" aria-hidden="true"></i> | |
</button> | |
<center> | |
<a :href="'/product/' + product.id"> | |
<img :src="product.avatar" class="img-circle" width="50px" height="50px"> | |
<h5>{{ product.name }}</h5> | |
<small>{{ product.brand }}</small> | |
<h4><b>${{ product.price }}</b></h4> | |
<small>{{ product.description | truncate }}</small> | |
</a> | |
</center> | |
</div> | |
</div> | |
</div> | |
</div> | |
</template> | |
<style scoped> | |
a:hover { | |
text-decoration: none; | |
color: #323a3e; | |
} | |
.form-control { | |
height: 45px; | |
} | |
.no-padding { | |
margin-left: 0; | |
margin-right: 0; | |
padding-left: 0; | |
padding-right: 0; | |
} | |
.user-box { | |
height: 275px; | |
margin-top: 25px; | |
box-shadow: 0 9px 11px -12px rgba(0,0,0,.75); | |
} | |
.user-box a { | |
color: #636b6f; | |
} | |
.inner-user-box { | |
height: 275px; | |
padding: 10px; | |
background-color: white; | |
} | |
</style> | |
<script> | |
export default { | |
props: ['users','startingProducts'], | |
data(){ | |
return{ | |
search: '', | |
searchP: '', | |
products: [], | |
isActiveHigh: false, | |
isActiveLow: false | |
} | |
}, | |
mounted() { | |
this.products = this.startingProducts; | |
}, | |
computed: { | |
/** Function to search products in search-bar **/ | |
searchProducts() { | |
// If there are no search results, return all the products. | |
if(!this.searchP){ | |
return this.products; | |
} | |
// Assign self to 'this' | |
let self = this; | |
// Return all the products with what ever was typed in in search box. | |
return this.products.filter(function(product){ | |
return (new RegExp(self.searchP,'i')).test(product.name) | |
}); | |
} | |
}, | |
methods: { | |
filterByPriceLowest() { | |
axios.get('products/price/lowest') | |
.then((response)=>{ | |
this.products = response.data; | |
this.isActiveLow = true | |
this.isActiveHigh = false | |
}) | |
.catch() | |
}, | |
filterByPriceHighest() { | |
axios.get('products/price/highest') | |
.then((response)=>{ | |
this.products = response.data; | |
this.isActiveHigh = true | |
this.isActiveLow = false | |
}) | |
.catch() | |
}, | |
deleteProduct(id) { | |
axios.post('products/delete/' + id) | |
.then((response)=>{ | |
swal({ | |
title: "Success!", | |
text: "Product deleted successfully!", | |
type: "success", | |
showConfirmButton: false, | |
allowEscapeKey: false, | |
allowOutsideClick: false, | |
timer: 5000, | |
}), | |
setTimeout(function(){ | |
location.reload(); | |
}, 4000) | |
}) | |
.catch() | |
} | |
} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment