Reputation: 7138
I'm working with vuejs
in laravel 5.6 and I've made search form with 2 inputs, but i'm not sure how to show results in different page and my data return by json.
controller
public function indexsearch(Request $request)
{
$area = request('area');
$keywords = request('keywords');
if($keywords){
$projects = Project::where('title', 'LIKE', "%{$keywords}%")
->orWhere('body', 'LIKE', "%{$keywords}%")
->orWhere('area', 'LIKE', "%{$keywords}%")
->get();
}else{
$projects = Project::where('title', 'LIKE', "%{$keywords}%")
->orWhere('body', 'LIKE', "%{$keywords}%")
->orWhere('area', 'LIKE', "%{$keywords}%")
->get();
}
return response()->json($projects);
}
route
Route::get('indexsearch', 'Api\SearchController@indexsearch');
component
<template>
<div>
<div class="form-row justify-content-center align-items-center mmt-5">
<div class="col-md-4">
<label class="sr-only" for="inlineFormInput">Query</label>
<input v-model.lazy="keywords" type="text" class="customformdes form-control mb-2" id="inlineFormInput" placeholder="E.g. Larave, Vue, Design, Writer">
</div>
<div class="col-md-4">
<label class="sr-only" for="inlineFormInputGroup">Area</label>
<input v-model.lazy="area" type="text" class="customformdes form-control mb-2" id="inlineFormInputGroup" placeholder="E.g. Jabodetabek, Medan, Surabaya">
</div>
<div class="col-md-2">
<button type="button" class="customformdes btn btn-block btn-primary mb-2"><i class="fab fa-searchengin"></i> Search</button>
</div>
</div>
// currently this part shows the result as hidden drop-down
<b-list-group v-if="results.length > 0">
<b-list-group-item v-for="result in results" :key="result.id" :to="`/projects/${result.slug}`">{{result.title}}</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
var _ = require('lodash');
import navbar from './navbar.vue';
export default {
data() {
return {
keywords: null,
area: null,
results: []
};
},
watch: {
keywords(after, before) {
this.fetch();
}
},
methods: {
fetch() {
axios.get('/api/indexsearch', { params: { keywords: this.keywords, area: this.area } })
.then(response => this.results = response.data)
.catch(error => {});
}
}
}
</script>
Thanks in advance.
Upvotes: 0
Views: 1117
Reputation: 3729
For your first issue, you can add more watcher for the area
:
(Since you are just calling a single method
from your watcher, you can just directly use the method's name as the value of your watcher as it is just the same.)
watch: {
keywords: 'fetch',
area: 'fetch'
},
you can also use $vm.watch
to watch for multiple values at the same time.
Instead of:
watch: {
keywords(after, before) {
this.fetch();
}
},
you can have it like this:
mounted() {
this.$watch(
function() {
return this.keywords + this.area
},
(newVal, oldVal) => {
this.fetch();
}
)
}
As for the second issue, you can pass props data to the target page.
See this example code below:
ResultsPage.vue:
<template>
<div>
<div v-for="result in results" :key="result.id">{{ result.title }}</div>
</div>
</template>
<script>
export default {
props: ['results']
}
</script>
router configuration:
import ResultsPage from 'ResultsPage.vue'
new Router({
routes: [
// ... some other routes in here
{
path: '/results',
name: 'results',
props: true,
component: ResultsPage,
}
]
})
then you can now navigate to the ResultsPage
by using $router.push()
:
methods: {
fetch() {
axios.get('/api/indexsearch', {
params: {
keywords: this.keywords,
area: this.area
}
})
.then(response => {
this.$router.push({
name: 'results',
params: {
results: response.data
}
})
})
.catch(error => {});
}
}
Upvotes: 1
Reputation: 3184
You will need to add $area
as your search term to solve the first issue.
And to show the results on a separate page you will need to request a route that returns a view in your search method.
// Controller
public function indexsearch(Request $request)
{
$area = request('area');
$keywords = request('keywords');
if($keywords){
$projects = Project::where('title', 'LIKE', "%{$keywords}%")
->orWhere('body', 'LIKE', "%{$keywords}%")
->orWhere('area', 'LIKE', "%{$area}%")
->get();
}else{
$projects = Project::where('title', 'LIKE', "%{$keywords}%")
->orWhere('body', 'LIKE', "%{$keywords}%")
->orWhere('area', 'LIKE', "%{$area}%")
->get();
}
return view('search_results', compact('projects'));
}
If you want to show the results on a separate page then you don't really need vue here.
You can do something like this to submit a form in your view:
<form action="search"> <!-- or whatever your searchindex route is -->
<div class="form-row justify-content-center align-items-center mmt-5">
<div class="col-md-4">
<label class="sr-only" for="inlineFormInput">Query</label>
<input v-model.lazy="keywords" type="text" class="customformdes form-control mb-2" id="inlineFormInput" placeholder="E.g. Larave, Vue, Design, Writer">
</div>
<div class="col-md-4">
<label class="sr-only" for="inlineFormInputGroup">Area</label>
<input v-model.lazy="area" type="text" class="customformdes form-control mb-2" id="inlineFormInputGroup" placeholder="E.g. Jabodetabek, Medan, Surabaya">
</div>
<div class="col-md-2">
<button type="button" class="customformdes btn btn-block btn-primary mb-2"><i class="fab fa-searchengin"></i> Search</button>
</div>
</div>
</form>
Then in your search results blade (search_results.blade.php) view:
<div>
<b-list-group">
@foreach($projects as $project)
<b-list-group-item>{{ $project->title }}</b-list-group-item>
@endforeach
</b-list-group>
</div>
I hope this helps solve your issue.
Upvotes: 0