Laravel Pagination Appends Not Keeping Search Data - laravel

I've been able to implement the pagination and appends() on my form and it does show the proper values in the url on page 2, though it doesn't actually bring the values back into the form/query, it simply resets the actual data being searched for and displays all.
Here is my form code and the appends.
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
.
.
.
<?php echo $employees->appends(array("srch_lname" => Session::get('srch_lname'),
"srch_fname" => Session::get('srch_fname') ))->links(); ?>
And my Controller
public function getIndex() {
$srch_lname = Session::get('srch_lname');
$srch_fname = Session::get('srch_fname');
$employees = vEmployees::co()->restrictions()
->where('lastname', 'LIKE', $srch_lname . '%')
->where('firstname', 'LIKE', $srch_fname . '%')
->paginate(10);
return View::make('employees.index')
->with('employees', $employees)
->with('title', 'Users');
}
public function postIndex() {
if (Input::has('btnSearch')) {
return Redirect::to('/employees')->with('search', 1)
->with('srch_lname', Input::get('srch_lname'))
->with('srch_fname', Input::get('srch_fname'));
else {
return Redirect::to('/employees');
}
}
Full Form
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<div class="stepContainer">
<div class="formwiz content">
<h4 class="widgettitle">Search for an Employee</h4>
<p>
<label>Lastname</label>
<span class="field">
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
</span>
</p>
<p>
<label>Firstname</label>
<span class="field">
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
</span>
</p>
</div>
</div>
<div class="actionBar" style="text-align: right;">
<button class="btn btn-primary" name="btnSearch" value="1">
Search for Employee(s)
</button>
</div>
{{ Form::close() }}

You need to pass your inputs to the view so that Input::old() has values to work with after the redirect from postIndex to getIndex.
in getIndex(), add to View::make()
->with('input', [ 'srch_lname'=> $srch_lname, 'srch_fname' => $srch_fname ]);

It looks like you do not have the pageSearch value in your pagination query string. Try this.
<?php echo $employees->appends(
array("btnSearch" => "1",
"srch_lname" => Session::get('srch_lname'),
"srch_fname" => Session::get('srch_fname') )
)->links(); ?>

I made a small sample but since I don't have your employees I just used the User model and commented out the filtering, just used as a test to pass and get input values.
Note the change to Input:: from Session, in getIndex() and in the form for $employees->appends(). Use Input instead of Session, I did not see anywhere in your code where you save the filter values in session variables.
I also changed the Redirect::to() to pass the parameters in the URL since it is a get method.
I tested and the filter values are passed to getIndex() and the form fields, also the inputs get properly passed by pagination links.
class EmployeeController extends BaseController
{
public
function getIndex()
{
$srch_lname = Input::get('srch_lname');
$srch_fname = Input::get('srch_fname');
$employees = User::query()
//->where('lastname', 'LIKE', $srch_lname . '%')
//->where('firstname', 'LIKE', $srch_fname . '%')
->paginate(10);
// make input available for page's form fields as old input
Session::flash('_old_input', Input::all());
return View::make('employees')
->with('employees', $employees)
->with('title', 'Users');
}
public
function postIndex()
{
if (Input::has('btnSearch'))
{
return Redirect::to('/employees?search=1&srch_lname=' . urlencode(Input::get('srch_lname')) . '&srch_fname=' . urlencode(Input::get('srch_fname')));
//return Redirect::to('/employees')->with('search', 1)
// ->with('srch_lname', Input::get('srch_lname'))
// ->with('srch_fname', Input::get('srch_fname'));
}
else
{
return Redirect::to('/employees');
}
}
}
Form and ->appends():
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<div class="stepContainer">
<div class="formwiz content">
<h4 class="widgettitle">Search for an Employee</h4>
<p>
<label>Lastname</label>
<span class="field">
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
</span>
</p>
<p>
<label>Firstname</label>
<span class="field">
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
</span>
</p>
</div>
</div>
<div class="actionBar" style="text-align: right;">
<button class="btn btn-primary" name="btnSearch" value="1">
Search for Employee(s)
</button>
</div>
{{ Form::close() }}
<?php echo $employees->appends(array("srch_lname" => Input::get('srch_lname'),
"srch_fname" => Input::get('srch_fname') ))->links(); ?>

I got it working! I continued to do some research and running the search through POST was really a major issue in adding that gap between the search itself and holding the data into the GET method of pagination.
I'll run through everything I did below for anyone in the future having the same issue.
I first created a Route that would direct to a new function in my EmployeesController
Route::get('emp_srch', 'EmployeesController#search');
And created the new function in the Controller
public function search() {
$srch_lname = Input::get('srch_lname');
$srch_fname = Input::get('srch_fname');
$employees = vEmployees::co()->restrictions()
->where('lastname', 'LIKE', $srch_lname . '%')
->where('firstname', 'LIKE', $srch_fname . '%')
->orderBy('lastname')
->orderBy('firstname')
->paginate(10);
Session::flash('_old_input', Input::all());
return View::make('employees.index')
->with('employees', $employees)
->with('title', 'Users')
->with('pagetitle', 'Employees')
}
It's essentially the function I had in the getIndex though rearranging the way the search was functioning I believe was the defining factor in actually getting this to work in my case.
I also changed the url on the form, which directed to my new Route. As well as changing the form so it uses the GET Method and no longer POST.
{{ Form::open(array('url' => 'emp_srch', 'class' => 'stdform', 'method' => 'get')) }}
I do want to thank vladsch and whoacowboy for helping push me in the right direction(s).

Related

Refresh same livewire component after form wire:submit.prevent

Please I'd like to refresh same component after form submit. There is an if statement that allows the the form to display in the component. I'd like to refresh the whole component so as not to show the form again after submit.
I already tried emit but I don't think it works for same component.
Livewire component
<?php
namespace App\Http\Livewire;
use App\Lesson;
use App\Question;
use App\QuestionsOption;
use App\TestsResult;
use Livewire\Component;
class LessonTest extends Component
{
public $test_result;
public $lesson;
public $test_exists;
public array $question = [];
//protected $listeners = ['testDone' => 'render'];
public function mount($test_exists, $lesson, $test_result)
{
$this->lesson = $lesson;
$this->test_exists = $test_exists;
$this->test_result = $test_result;
}
public function lessonTest()
{
$lesson = Lesson::where('slug', $this->lesson->slug)->firstOrFail();
$answers = [];
$test_score = 0;
foreach ($this->question as $question_id => $answer_id) {
$question = Question::find($question_id);
$correct = QuestionsOption::where('question_id', $question_id)
->where('id', $answer_id)
->where('correct', 1)->count() > 0;
$answers[] = [
'question_id' => $question_id,
'option_id' => $answer_id,
'correct' => $correct,
];
if ($correct) {
$test_score += $question->score;
}
/*
* Save the answer
* Check if it is correct and then add points
* Save all test result and show the points
*/
}
$test_result = TestsResult::create([
'test_id' => $this->lesson->test->id,
'user_id' => \Auth::id(),
'test_result' => $test_score,
]);
$test_result->answers()->createMany($answers);
$this->reset(['question']);
$this->emit('testDone');
}
public function render()
{
return view('livewire.lesson-test');
}
}
Livewire Blade View
<div>
#if ($test_exists)
<hr />
<h3>Test: {{ $lesson->test->title }}</h3>
#if (!is_null($test_result))
<div class="alert alert-info">Your test score: {{ $test_result->test_result }} /
{{ $lesson->test->questions->count() }}</div>
#else
<form wire:submit.prevent='lessonTest' action="{{ route('lessons.test', [$lesson->slug]) }}"
method="post">
{{ csrf_field() }}
#foreach ($lesson->test->questions as $question)
<b>{{ $loop->iteration }}. {{ $question->question }}</b>
<br />
#foreach ($question->options as $option)
<input type="radio" wire:model='question.{{ $question->id }}'
name="questions[{{ $question->id }}]" value="{{ $option->id }}" />
{{ $option->option_text }}<br />
#endforeach
<br />
#endforeach
<button class="btn btn-success btn-lg refresh" type="submit">Submit</button>
</form>
#endif
<hr />
#endif
</div>
Thank You. I got it solved, I forget that I passed the test result from the controller before, so I had to recall the test_result and also the test_exist inside the lessonTest action.
$this->test_result = TestsResult::where('test_id', $this->lesson->test->id)
->where('user_id', \Auth::id())
->first();
$this->test_exists = true;

Update data in laravel 6

I try to create crud in laravel 6. Create, Read and Delete process is running well. But when Update process, the data in table not change. Could anyone help me to find the problem ? The following my code.
Route
Route::get('/blog', 'BlogController#index');
Route::get('/blog/add','BlogController#add');
Route::post('/blog/store','BlogController#store');
Route::get('/blog/edit/{id}','BlogController#edit');
Route::post('/blog/update','BlogController#update');
Controller
public function index()
{
$blog = DB::table('blog')->get();
return view('blog',['blog' => $blog]);
}
public function edit($id)
{
$blog = DB::table('blog')->where('blog_id', $id)->get();
return view('edit', ['blog'=>$blog]);
}
public function update(Request $request)
{
DB::table('blog')->where('blog_id',$request->blog_id)->update([
'blog_title' => $request->title,
'author' => $request->author]);
return redirect('/blog');
}
View
#foreach ($blog as $n)
<form method="post" action="/blog/update" />
{{ csrf_field() }}
Title <input type="text" name="title" value="{{ $n->title}}">
Author<input type="text" name="author" value="{{ $n->author}}">
<button type="submit" class="btn btn-secondary">Update</button>
</form>
#endforeach
You must provide id in your route
Route::post('/blog/update/{id}','BlogController#update');
In update method add parameter id and then find product against id
public function update(Request $request, $id)
{
DB::table('blog')->where('blog_id',$id)->update([
'blog_title' => $request->title,
'author' => $request->author]);
return redirect('/blog');
}
#foreach ($blog as $n)
<form method="post" action="{{ route('your route name'), ['id' => $$n->id] }}" />
{{ csrf_field() }}
Title <input type="text" name="title" value="{{ $n->title}}">
Author<input type="text" name="author" value="{{ $n->author}}">
<button type="submit" class="btn btn-secondary">Update</button>
</form>
#endforeach
try separating the update into two statements like so
$blog = DB::table('blog')->where('blog_id',$id)->first();
$blog->update([
'blog_title' => $request->title,
'author' => $request->author]);
Also you might want to use models in the future so you can do it like
$blog = Blog::where('blog_id',$id)->first();
Doesn't really shorten your code but it improves the readibility.
Do your update like this:
public function update(Request $request)
{
$post = DB::table('blog')->where('blog_id',$request->blog_id)->first();
$post->blog_title = $request->title;
$post->author = $request->author;
$post->update();
return redirect('/blog');
}

Laravel 5.0: Route with query string

I am using laravel 5.0, I am sending a query string on A tag with an id.
I am getting id but not the query string data
Below is the code:
View
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4">
<div class="img-decor">
<a href="{{url('buycarddetail/'.$retailer->id)}}" class="">
<img src="{{ assetnew('uploads/client_image/'.$retailer->image) }}" alt="..." class="img-rounded" width="200">
</a>
<div class="deals-title">
{{ $retailer->name }}
<div class="sub-details">Save up to {{ $retailer->discount }}%</div>
</div>
</div>
</div>
Controller
public function buycarddetail($id = null, Request $request)
{
echo $id;
echo '<pre>'; $data = $request->all(); exit;
return view('buycarddetail');
}
Route
Route::get('buycarddetail/{id}', ['as' => 'buycarddetail', 'uses' => 'HomeController#buycarddetail']);
I want to use the query string data for further process on controller
Please help
Based on your code you're not actually appending any query string when generating the link {{url('buycarddetail/'.$retailer->id)}}.
As per your comments you can do this to generate a link to your route with the query string.
{{ route('buycarddetail', ['id' => $retailer->id, '_token' => csrf_token(), 'brand' => 'test', 'buybrand' => 'example']) }}
This example would generate a link like
http://example.com/buycarddetail/17?_token=QHE8va7stXUOPabwTjKmXyJxdsuPSZ9VbH3uThwx&brand=test&buybrand=example

I Cannot able to pass the id in route file in laravel

I am declaring the above thing in the route for edit of my data.
Route::get('editproduct/{id}', 'HomeController#Edit_Product');
Above is my editproduct.blade.php page
<?php
$id = $_GET['eid'];
$product_info = DB::select("SELECT * FROM `product` WHERE `pid` = '".$id."'");
foreach($product_info as $detail)
{
$actual_image = 'theme/uploads/'.$detail->pimage;
$product_image = $detail->pimage;
$product_name = $detail->pname;
$product_price = $detail->pprice;
}
?>
#include('include/header')
<div class="tab-pane add-product-view" id="profile">
<form name="add_product" method="post" enctype="multipart/form-data" role="form" action="{{ url('edit-product-process') }}">
{{ csrf_field() }}
<div class="form-label">Add Image: </div>
<div class="form-field"><input type="file" name="add_image" id="add_image" value="{{asset($actual_image)}}" /></div>
<img src="{{asset($actual_image)}}" width="50" height="50" />
<div class="form-label">Product Name:</div>
<div class="form-field"><input type="text" name="product_name" id="product_name" value="{{ $product_name }}" /></div>
<div class="form-label">Product Price:</div>
<div class="form-field"><input type="text" name="product_price" id="product_price" value="{{ $product_price }}" /></div>
<div class="btn btn-primary"><input type="submit" name="submit" value="Add Product"</div>
</form>
</div>
#include('include/footer')
This is My HomeController.blade.php
public function Edit_Product($id){
return View::make('editproduct')->with('id', $id);
}
public function edit_product_process(Request $request){
$prd_id = $request->pid;
$imageTempName = $request->file('add_image')->getPathname();
$imageName = $request->file('add_image')->getClientOriginalName();
$path = base_path() . '/theme/uploads/';
$request->file('add_image')->move($path , $imageName);
$remember_token = $request->_token;
$date = date('Y-m-d H:i:s');
$pname = $request->product_name;
$pprice = $request->product_price;
DB::table('product')->where('pid',$prd_id)->update(
array(
'pimage' => $imageName,
'pname' => $pname,
'pprice' => $pprice,
'remember_token' => $remember_token,
'created_at' => $date,
'updated_at' => $date,
)
);
return redirect('dashboard');
}
I am getting the below error, Please anyone can be able to help me, I am new at laravel.
page is not found
NotFoundHttpException in RouteCollection.php line 161:
If you're getting this error when you're trying to submit the form, you should check you route. It should look like this:
Route::post('edit-product-process', 'HomeController#edit_product_process');
Also, to pass an ID into edit_product_process you need to add field with ID into the form:
<input type="hidden" name="id" value="{{ $id }}">
And then you can get it in edit_product_process with $request->id
Your route should be as:
Route::get('editproduct/{id}', 'HomeController#Edit_Product')->name('product.edit');
Then you can use it as:
{{ route('product.edit', ['id' => $id]) }}
But it's a terrible practice to use DB queries in views.
Please do read more about queries and controllers in the docs.
Check Your Controller Name Why r using blade in that.This is bad practice.HomeController.blade.php

Updating on the current id

I'm trying to update my pivot table using radio button. Where I don't need to go to another url. But it doesn't get the values of radio button when performing update. Here how it looks.
//SELECT
Route::get('/documents/pending/view/{id}',
[
'uses' => '\App\Http\Controllers\DocumentController#readDocumentsSentForApproval',
'as' => 'document.viewPending',
]);
//UPDATE
Route::post('/documents/pending/view/{id}',
[
'uses' => '\App\Http\Controllers\DocumentController#updateApprovalsDocument',
'as' => 'document.viewPending',
]);
Controller:
public function readDocumentsSentForApproval($id)
{
$viewPendingDocuments = DB::table('approvals_document')
->select('documents.title', 'documents.content', 'categories.category_type', 'documents.id')
->join('documents', 'documents.id', '=', 'approvals_document.document_id')
->join('categories', 'categories.id', '=', 'documents.category_id')
->where('documents.id', '=', $id)
->first();
$getApprovers = DB::table('approvals_document')
->select('users.first_name', 'users.middle_name', 'users.last_name', 'users.username', 'approvals_document.updated_at', 'approvals_document.isApprove', 'approvals_document.id', 'approvals_document.approver_id')
->join('documents', 'documents.id', '=', 'approvals_document.document_id')
->join('users', 'users.id', '=', 'approvals_document.approver_id')
->where('documents.id', '=', $id)
->get();
return view ('document.viewPending')
->with('viewPendingDocuments', $viewPendingDocuments)
->with('getApprovers', $getApprovers);
}
public function updateApprovalsDocument(Request $request)
{
//Getting the hidden input named = id.
$id = $request->get('id');
$document = DB::table('approvals_document')
->where('approvals_document.id', '=', $id)
->update(['isApprove' => $request->status, 'updated_at' => new DateTime]);
return redirect()->back();
}
View
#foreach($getApprovers as $list)
<tr>
<td>
#if(Auth::id() == $list->approver_id)
<form class="form-inline" id="submitMe" method="post" action="{{ url('documents/pending/view' . $list->id) }}">
<input type="hidden" name="id" value="{{ $list->id }}">
<div class="form-group">
<label>
<input type="radio" onclick="showApprove()" name="status" value="1">Approve</label>
<label>
<input type="radio" onclick="showReject()" name="status" value="2">Reject</label>
</div>
<input type="hidden" name="_token" value="{{ Session::token() }}">
</form>
#endif
</td>
</tr>
#endforeach
I passed the current url on the action so it will know what id is it. Is this the proper way updating? Thanks for your help!
There is nothing wrong with it, but I think the recommended way in Laravel would be to use the patch route, as this is the RESTful way of doing it.
post would be used for creating the entity, patch is used for updating it.
The only changes you would need to make, is the route binding (post to patch) and adding the form spoofing for the method
<input type="hidden" name="_method" value="PATCH">
https://laravel.com/docs/5.3/routing#form-method-spoofing
You could also use the route binding for the id, instead of passing it in as a form field. This would be more advantageous if you wanted to do validation on that route (e.g. a middleware, allowing only the owner of that record to update it).
I already find a solution for this using Form Method Spoofing
public function readDocumentsSentForApproval($id)
{
$viewPendingDocuments = DB::table('approvals_document')
->select('documents.title', 'documents.content', 'categories.category_type', 'documents.id')
->join('documents', 'documents.id', '=', 'approvals_document.document_id')
->join('categories', 'categories.id', '=', 'documents.category_id')
->where('documents.id', '=', $id)
->first();
$getApprovers = DB::table('approvals_document')
->select('users.first_name', 'users.middle_name', 'users.last_name', 'users.username', 'approvals_document.updated_at', 'approvals_document.isApprove', 'approvals_document.approver_id',
'approvals_document.id as approvalDocumentId', 'documents.id as documentId')
->join('documents', 'documents.id', '=', 'approvals_document.document_id')
->join('users', 'users.id', '=', 'approvals_document.approver_id')
->where('documents.id', '=', $id)
->get();
return view ('document.viewPending')
->with('viewPendingDocuments', $viewPendingDocuments)
->with('getApprovers', $getApprovers);
}
View:
<form class = "form-inline" role = "form" id = "submitMe" method = "POST" action = "/documents/pending/{{ $list->documentId}}/view">
{{ method_field('PATCH') }}
<input type = "hidden" name = "id" value = "{{ $list->approvalDocumentId }}">
<div class = "form-group">
<label><input type = "radio" onclick = "showApprove()" name = "status" value = "1"> Approve</label>
<label><input type = "radio" onclick = "showReject()" name = "status" value = "2"> Reject</label>
</div>
<input type = "hidden" name = "_token" value = "{{ Session::token() }}">
</form>

Resources