There is a simple page where i display search results by keywords.
But now i want to search on those results by some criteria.
How can i do it
SearchController
class SearchController extends \BaseController {
public function search() {
$keyword = Input::get('header-search-query');
if (empty($keyword)) {
$product = Product::paginate(10);
$this - > setModel($product);
return View::make('product.listbykeyword') - > with('products', $product);
}
return View::make('product.listbykeyword') - > with('products', Product::like('title', $keyword) - > paginate(10));
}
public function advance() {
//what should i put here
}
}
View
#foreach($products as $product)
<div class="media">
<div class="media-left" style="width:16%;">
<a href="{{ URL::to('image/'.$product->productImage()->first()['image']) }}">
{{ HTML::image('image/'.$product->productImage()->first()['image'],'no-image',array('class'=>'media-object','height'=>'100','width'=>'100'))}}
</a>
</div>
<div class="media-body">
<h4 class="media-heading">{{ HTML::link('/product/'.$product->id,$product->title) }}</h4>
<p>{{substr($product->description,0,85)}}</p>
<p>Price : {{$product->price}} TK</p>
<p class="time">{{$product->created_at->diffForHumans()}}
<b>Near</b> {{$product->location}}
</p>
</div>
</div>
<hr></hr>
#endforeach
As it was true that you can't able to use Datatables in your case as it is a public search i would recommend you to use ajax call on the keychange event.
Step 1 :
Detect the keychange from your textbox
<input id='myTextbox1' type='text'/>
$('#myTextbox1').on('input', function() {
alert('Text1 changed!');
});
Here is the fiddle
Step 2 :
Call the ajax page to your controller
$.ajax({
type: "POST",
url : "yourcontroller",
data : dataString,
success : function(data){
$("#result").html(data);
}
});
Place a div named as result in your page.
So, First time you will get the result from your default controller you use to search and then next time whenever you type the text in your myTextbox1 it will call the controller yourcontroller and in your controller you should get the datastring and return the matching output to the view.
Hope this helps you.
Related
I am creating a web app having dashboard using laravel and vue.
When I pass data from controller to vue file data is received properly but when I set it to vue variable the value is not set in the variable. All data is received and its displayed in the console but when I set it to the vue variable, the variable doesn't update its value.
This is my Controller class:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class UsersController extends Controller
{
//
public function index()
{
$users=User::all();
return response()->json($users);
}
}
This is myTeam.vue for receiving and displaying the data:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card card-default">
<div class="card-header">Example Component</div>
<h1>
This request list
Hello,{{this.items}}
</h1>
<ul class="list-group">
<li class="list-group-item" v-for="t in items">{{items}}</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
//items: []
items:[],
}
},
created() {
var self=this;
axios.get('/allusers').then((response) => self.items=response.data) .catch((error)=>console.log(error));
axios.get('/allusers') .then(response => console.log(response.data));
console.log('Component mounted.'+this.items)
},
}
</script>
Now when I run it the console prints the array properly means data is received but when I set it to items variable the data is not set.
My Output is this:
This is the output image file
Please check it and thanks in advance ...
This is never print items array because it's execute before the ajax response is filled.
console.log('Component mounted.'+this.items)
That's why your console is always blank. You can search about blocking and non blocking programming.
your code have small bug. Update your code and try this:
<h1>
This request list
Hello,{{items}}
</h1>
<ul class="list-group">
<li class="list-group-item" v-for="t in items">{{t}}</li>
</ul>
...
<script>
export default {
data(){
return {
items:[],
}
},
mounted: function () {
this.getList();
}
methods: {
let _this = this;
axios.get('/allusers')
.then((response) => _this.items = response.data)
.catch((error)=>console.log(error));
},
}
</script>
This can help you. Good luck.
I have a homepage where there is a menu with some categories and below there are the latest 10 posts.
A post can have many categories and one category can belong to many posts so there are 2 models and a pivot table "category_post" with 2 columns: id and name.
So in the homepage, there is a menu with some categories and below the posts:
<ul class="Categories__Menu">
#foreach($categories->take(6) as $category)
<li class="ative">
{{$category->name}}
</li>
#endforeach
</ul>
<div class="row" id="posts">
#foreach($posts as $post)
<div class="col-12 col-sm-6 col-lg-4 col-xl-3 mb-4">
<div class="card">
<img class="card-img-top" src="{{$post->image}}" alt="Card image cap">
<h5 class="card-title">{{$post->name}}</h5>
<div class="card-footer d-flex justify-content-between align-items-center">
More
</div>
</div>
</div>
#endforeach
</div>
I want that when each category is clicked to show only the posts of that category in the homepage, but in the same homepage, not in a specific category page. So maybe the best approach is using AJAX.
But Im getting an error accessing "http://proj.test/posts/where/category/5"
ReflectionException (-1)
Class PostController does not exist
Or when I click in a category in the menu it appears in the console:
GET http://proj.test/posts/where/category/5 500 (Internal Server Error)
Do you know where is the issue?
The code:
In the FrontController I already pass the categories and posts to the homepage view:
FrontController:
class FrontController extends Controller
public function index(){
return view('home')
->with('categories', Category::orderBy('created_at', 'desc')->get())
->with('posts', Post::orderBy('created_at','desc')->take(10)->get());
}
}
Post and Category models:
class Post extends Model
{
public function categories(){
return $this->belongsToMany('App\Category');
}
}
class Category extends Model
{
public function posts(){
return $this->belongsToMany('App\Post');
}
}
PostController:
public function WhereHasCategory(Request $request)
{
$posts = Post::whereHas('categories', function ($categories) use (&$request) {
$categories->where('id',$request->id);
})->get();
return response()->json($posts);
}
Route to the homepage:
Route::get('/', [
'uses' => 'FrontController#index',
'as' =>'index'
]);
Route to the ajax part:
Route::get('posts/where/category/{id}','\PostController#WhereHasCategory')->name('category.posts');
Ajax:
$(function() {
$("a[name='category']").on('click', function(){
var category_id = $(this).attr("id");
$.ajax({
url: '{{ route('category.posts',null) }}/' + category_id,
type: 'GET',
success:function(result){
$('#posts').empty();
$.each(result,function(index, postObj){
$('#posts').append("<p>"+postObj.title+"</p>");
});
console.log(result);
},
error: function(error) {
console.log(error.status)
}
});
});
});
You've defined the class wrong in the ajax route.
Route::get(
'posts/where/category/{id}',
'\PostController#WhereHasCategory'
)->name('category.posts');
You've put the controller as \PostController when I imagine it's App\Http\Controllers\PostController. When you prefix the class with \ it tells it that it's in the global scope, with no namespace. Remove the \.
In the homepage there is a menu with some categories and below there are the latest 10 posts.
A post can have many categories and one category can belong to many posts so there are 2 models and a pivot table "category_post" with 2 columns: id and name.
So in the homepage, there is a menu with some categories and the posts:
<ul class="Categories__Menu">
#foreach($categories->take(6) as $category)
<li class="ative">
{{$category->name}}
</li>
#endforeach
</ul>
<div class="row" id="posts">
#foreach($posts as $post)
<div class="col-12 col-sm-6 col-lg-4 col-xl-3 mb-4">
<div class="card">
<img class="card-img-top" src="{{$post->image}}" alt="Card image cap">
<h5 class="card-title">{{$post->name}}</h5>
<div class="card-footer d-flex justify-content-between align-items-center">
More
</div>
</div>
</div>
#endforeach
</div>
I want that when each category is clicked to show only the posts of that category in the homepage, but in the same homepage, not in a specific category page. So maybe the best approach is using AJAX.
Im not understanding what is necessary in the controllers and routes and the jquery is also dont working properly. Do you know how what is necessary to list the posts when a category is clicked with AJAX?
In the Frontcontroller I already pass the categories and posts to the homepage view:
class FrontController extends Controller
public function index(){
return view('home')
->with('categories', Category::orderBy('created_at', 'desc')->get())
->with('posts', Post::orderBy('created_at','desc')->take(10)->get());
}
}
route to the homepage:
Route::get('/', [
'uses' => 'FrontController#index',
'as' =>'index'
]);
Post and Category models:
class Post extends Model
{
public function categories(){
return $this->belongsToMany('App\Category');
}
}
class Category extends Model
{
public function posts(){
return $this->belongsToMany('App\Post');
}
}
In this homepage I have at bottom the ajax below
#section('scripts')
<script>
$(function() {
$("a[name='category']").on('click', function(){
var category_id =$(this).attr("id");
alert("test");
$.get('/ajax-category?category_id=' + category_id, function (data) {
$('#posts').empty();
$.each(data,function(index, postObj){
$('#posts').append('');
});
});
});
});
</script>
#stop
Pivot table "category_post" structure
public function up()
{
Schema::create('category_post', function (Blueprint $table) {
$table->increments('id');
$table->integer('post_id');
$table->integer('category_id');
$table->timestamps();
});
}
Just in your API route add a new route for your SQL queries, something like this following route :
Route::get('posts/where/category/{id}','\Posts#WhereHasCategory')->name('category.posts');
Then in your WhereHasCategory function return related posts :
API Controller (WhereHasCategory) :
public function WhereHasCategory(Request $request)
{
$posts = Post::whereHas('categories', function ($categories) use (&$request) {
$categories->where('id',$request->id);
})->get();
return response()->json($posts);
}
Post Model (Many To Many Relationships) :
public function Categories () {
return $this->belongsToMany(Category::class,'post_category','post_id','category_id');
}
You will get those posts that have $request->id category
For your Ajax part, you have to make an ajax request to the above route, You will get the posts which you want, so once you're done change the content of your home page (If you are using VueJS or similar Javascript framework it's really easy) ... That is all, I think!
Try this for your ajax request :
<a name="category" id="2018" href="#">
Category
</a>
<div id="posts">
<p>Title : Posts Are Here !</p>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script>
$(function() {
$("a[name='category']").on('click', function(){
var category_id = $(this).attr("id");
$.ajax({
url:"https://jsonplaceholder.typicode.com/posts",
type: 'GET',
success:function(result){
$('#posts').empty();
$.each(result,function(index, postObj){
$('#posts').append("<li>"+postObj.title+"</li><p>"+postObj.body+"</p>");
});
},
error: function(error) {
console.log(error.status)
}
});
});
});
</script>
Always keep your Javascript queries at the end of the page.
I think your ajax not working because your page is refreshing when you click the category link, try to add hashtag in the href property.
exsampel:
<ul class="Categories__Menu">
#foreach($categories->take(6) as $category)
<li class="ative">
{{$category->name}}
</li>
#endforeach
</ul>
or change <a> with <span>.
sorry for my English. I hope it would help.
I have two methods show and index I have a list of items on the index method that when a user clicks it takes her to another page containing some data that belongs to that id. Instead of doing it such way, I want to use jquery to make the data load on the same page. I have the following on my index.blade.php view. How do I achieve this in laravel?
#foreach ($categories as $category)
<div class="body">
<h4><a style="text-decoration: none; " href="{{ URL::route('category.show', $category->id) }}">{{$category->name}}</a></h4>
</div>
#endforeach
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use illuminate\HttpResponse;
use App\Http\Requests\todolistRequest;
use App\Http\Requests\CreateCategoryRequest;
use App\Http\Requests;
use App\Companylist;
use App\Category;
use Illuminate\Support\Facades\DB;
class CategoryController extends Controller
{
public function create(){
return view('category.create');
}
public function index(){
$categories=Category::all();
return view('category.index',compact('categories'));
}
public function store(CreateCategoryRequest $request){
$category = new Category($request->all());
$category->save();
return \Redirect::route('category.create')->with('message', 'Your list has been created!');
}
public function show($id)
{
$category = Category::findOrFail($id)->companylist()->get();
$cat=Category::findOrFail($id);
// this my route
Route::resource('category','CategoryController');
return view('category.show')->with('category', $category)->with('cat',$cat);
}
//
}
Use bootstrap modals or pop ups.
Design your category.show view according to your needs.
Call ajax and append your returned view response to that modal body and show it so it will be exactly same view you wanted.
example code is for replace and ajax is like
This is replace modal
<!-- Show Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Show data</h4>
</div>
<div class="modal-body replace">
</div>
</div>
This will be your ajax method
$('.showModalButton').on('click',function(e){
var id = $(this).data('id'); // get id of resource you want to show
$('.replace').empty(); //
$.ajax({
url: 'your route/'+id,
type: "GET",
success:function(data) {
$('.replace').html(data);
},
error:function(jQXHR, textStatus, errorThrown) {
console.log(jQXHR);
console.log(textStatus);
console.log(errorThrown);
}
}); //end Ajax call
});
This will be your show method in controller
public function show($id)
{
$category = Category::findOrFail($id)->companylist()->get();
$cat=Category::findOrFail($id);
// this my route
Route::resource('category','CategoryController');
return view('category.show')->with('category',$category)->with('cat',$cat);
}
Design category.show however you want to show your data.
I'm trying to use ajax to find the next page on my pagination. However it keeps bringing in the whole body. I've taken a print screen to show the problem.
I'm not an expert on ajax show would appreciate some help as to how I can rectify this issue?
My code is below:
public function viewall()
{
$data["projects"] = $projects = Auth::user()->projects()->paginate(3);
if(Request::ajax())
{
$html = View::make('projects.viewall', $data)->render();
return Response::json(array('html' => $html));
}
return View::make('projects.viewall')->with('projects', $projects);
}
Js/js.js
$(".pagination a").click(function()
{
var myurl = $(this).attr('href');
$.ajax(
{
url: myurl,
type: "get",
datatype: "html",
beforeSend: function()
{
$('#ajax-loading').show();
}
})
.done(function(data)
{
$('#ajax-loading').hide();
$("#projects").empty().html(data.html);
})
.fail(function(jqXHR, ajaxOptions, thrownError)
{
alert('No response from server');
});
return false;
});
viewall.blade.php
#extends("layout")
#section("content")
<div class="container">
<h4>Your Projects</h4>
<div id="ajax-loading" class="alert alert-warning" style="display: none;">
<strong>Loading...</strong>
</div>
#if (Auth::check())
#if (count($projects) > 0)
#foreach ($projects as $project)
<div class="one-third column" id="projects">
{{ $project->project_name }}
{{ $project->project_brief }}
{{ date("d-m-Y", strtotime($project->start_day)) }}
</div>
#endforeach
#else
<h5 class="errorslist">You have no projects click <a class="errorslist" href="/project/create">here to create a project</a></h5>
#endif
#endif
<div class="sixteen columns">
{{ $projects->links() }}
</div>
</div>
#stop
This line:
$("#projects").empty().html(data.html);
will fill the #project up with your returned html which you created here:
$html = View::make('projects.viewall', $data)->render();
So,you just need to change projects.viewall with only 'partial view' that you want to load.
Probably you don't need to extends your main layout.
But you render a view here:
$html = View::make('projects.viewall', $data)->render();
so html is created by Laravel and then you insert it as html into the #projects domElement.
I experienced this kind of problem, just run
dd( json_decode( json_encode( Products::paginate(5) ), true) );
and can get a hint :)
I have read a solution about this here:
http://www.tagipuru.xyz/2016/05/17/displaying-data-using-laravel-pagination-in-the-html-table-without-page-reload/