Thank you for taking the time to read and perhaps reply. I think I may have gotten myself so far down the rabbit hole, I'm overlooking an obvious answer.
Here is what I'm trying to accomplish:
I have a form with numerous text inputs rendered using Laravel Collective. I have a Bootstrap modal which allows a user to input a URL:
<div>
<input wire:model="url" type="text">
<button class="btn btn-primary" wire:click="scrape">Scrape</button>
</div>
Upon submitting the URL, I have a Livewire method which parses specific data from the URL:
`public $url;
public function scrape()
{
$link = GoutteFacade::request('GET', $request->url);
//dd($link->filter('title')->text());
}`
What I'm trying to do is pass $link to my Livewire component (or Blade file if need be) so I can populate an input field like so:
`<div class="form-group">
{!! Form::label('title', 'Title', ['class' => 'control-label']) !!}
{!! Form::text('title', (isset($link) ? $link->filter('title')->text() : null), ['class' => 'form-control', 'placeholder' => 'Your catchy title']) !!}
#error('title')
<x-alert type="danger" :message="$message" />
#enderror
</div>`
I'm trying to avoid doing a complete page reload, hence Livewire to provide a better UX. Just cannot wrap my head around this.
Thank you in advance!
you can do it using events
public function scrape()
{
$link = GoutteFacade::request('GET', $request->url);
$this->emitTo('to-emit-component', 'sendLink',['data' => $link]);
}
in the component to-emit-component listen the event
protected $listeners = [
'sendLink'
];
public function sendLink($data)
{
dd($data);
}
I think my answer will respond to the question but can give to others people hint to proceed otherwise.
Case: I created a mount method in Livewire file for getting query params. As a search issue, I wanted to populate inputs in other page submitting the query.
Query and Local are linked to livewire blade as model.
Livewire file
public String $query = '';
public String $local = '';
public function mount(Request $request)
{
if ($request->input('searchQui') != '' && $request->input('searchOu') != '') {
$this->query = $request->input('searchQui');
$this->local = $request->input('searchOu');
}
}
Livewire Blade
Related
I am trying to create a Poll (quiz) app, now I am doing a functionality that gets random questions from the database and returns in a poll (test)
I am displaying the answers 1 by 1 and when a user clicks submit answer a request is ran and the next answer is displayed
The problem is that every time a user submits the controller gets called again and the db query as well (when he clicks the next question button
This means that the query will get different random questions now and because of that same questions appears twice sometimes
I want to make sure that the query that gets the questions only gets called once
Model:
private $random_questions;
public function getRandomQuestions($questions_count)
{
if (!$this->random_questions)
{
$this->random_questions = Question::orderByRaw('RAND()')->take($questions_count)->get();
}
return $this->random_questions;
}
public function nextQuestionLink($questions_count, $question_number) {
$nextQuestionLink = [];
if ($questions_count != $question_number && $questions_count > $question_number) {
$nextQuestionLink['url'] = '/polls/random/'.$questions_count.'/'.++$question_number;
$nextQuestionLink['text'] = 'Следващ въпрос';
$nextQuestionLink['class'] = 'btn-default';
} else {
$nextQuestionLink['url'] = '/result';
$nextQuestionLink['text'] = 'Приключи';
$nextQuestionLink['class'] = 'btn-primary';
}
return $nextQuestionLink;
}
Controller:
public function getRandomQuestions($questions_count, $question_number)
{
$question = Question::Instance();
$questions = $question->getRandomQuestions($questions_count);
$nextQuestionLink = $question->nextQuestionLink($questions_count,
$question_number);
return view('polls.random_questions_poll')->with([
'question' => $questions[$questions_count-1],
'next' => $nextQuestionLink,
]);
}
View:
#section('content')
<div id="quiz-wrapper">
<h1>{{ $question->question }}</h1>
{!! Form::open(array( 'id' => 'message')) !!}
{!! csrf_field() !!}
#foreach($question->answers->shuffle() as $answer)
<h3>
<div class="form-group">
<div class="radio">
{{Form::radio('result', "$question->id-$answer->id") }}
{{ Form::label('result', $answer->name) }}
</div>
</div>
</h3>
#endforeach
<a class="next-question-button btn {{ $next['class'] }}" href="{{ $next['url'] }}" style="display: block;" role="button">{{ $next['text'] }}</a>
<p id="validation-error-container"></p>
{!! Form::close() !!}
</div>
#endsection
Since php by default is stateless, you will need to store the initial set of questions in persistent storage and retrieve them from that for all later requests.
You can do this quite succinctly with sessions in your controller:
public function getRandomQuestions($questions_count, $question_number)
{
//attempt to retrieve from session
$questions = session('questions', function(){
//if not found in session, generate from DB,
$questions = Question::Instance()->getRandomQuestions($questions_count);
//and store in session for next request.
session(['questions' => $questions]);
return $questions;
});
$nextQuestionLink = $question->nextQuestionLink($questions_count,
$question_number);
return view('polls.random_questions_poll')->with([
'question' => $questions[$questions_count-1],
'next' => $nextQuestionLink,
]);
}
I am trying to code the edit route for laravel and for some reason keep getting the error "Trying to get property of non-object laravel". The Create controller works fine, however when I use the controller#update route I keep getting this error
My Controller for adding an event: (update)
public function update(Request $request, $id)
{
//create event
$my_user = my::find($id);
$my_user->programme = $request->input('programme');
$my_user->goal1 = $request->input('goal1');
$my_user->goal2 = $request->input('goal2');
$my_user->goal3 = $request->input('goal3');
$my_user->goal4 = $request->input('goal4');
$my_user->goal5 = $request->input('goal5');
$my_user->user_id = auth()->user()->id;
$my_user->save();
return redirect('/home')->with('success','Event Created');
}
edit page
#extends('layouts.app')
#section('content')
<div class="container">
<h1>Edit Post</h1>
{!! Form::open(['action' => ['myUserController#update', $my_user], 'method' => 'POST']) !!}
<div class="form-group">
{{Form::label('title', 'Event Name')}}
{{Form::text('goal1', $my_user->goal1, ['class' => 'form-control', 'placeholder' => 'Goal One'])}}
</div>
{{Form::hidden('_method','PUT')}}
{{Form::submit('Submit', ['class'=>'btn btn-primary'])}}
{!! Form::close() !!}
</div>
#endsection
Given that you are using a Route::resource you can type-hint your parameters by writing something like
public function update(Request $request, MyUser $myuser){
// The $myuser parameter comes from the Route::resource and can be verified using php artisan route:list in your terminal
// edit $my_user
$my_user->save();
return redirect('/home')->with('success','Event Created');
}
Update after reviewing LaravelCollective documentation for Form
Thank you Sohel0415 for mentioning that you do not need to call $my_user->id for providing the route parameter with the Form facade.
You can use this method on your code:
{{ Form::open(array('url'=>'admin/users/store' , 'method' =>'POST')) }}
and your route define by this method in web.php file:
Route::post('users/store', 'admin\UserController#store');
I'm trying to have a button pass a query to the database when it's clicked. I'd like to have this set within a Controller that also stores requests and deletes requests. I was able to write to the database using store() and destroy(), but my edit() function gives me routing trouble. What is the best method to edit records using a controller? How would you build the edit() function? Or...should I be using the Update() function? I'm a Laravel/PHP beginner, please explain your answers if you can. Thank you!!
Overview: The project is an employee records table. I want to click a button that changes the employment status of an employee. I already have buttons to add new employee and delete and employee using this same Controller.
This is the route I set for the page:
Route::resource('employees', 'EmployeeController');
This is the front end form code for the button:
$workers = DB::table('employees')->get();
#foreach($workers as $employee)
{!! Form::open(array(
'method' => 'edit',
'route' => [ 'employees.edit', $employee->id]
)
)
!!}
<button type="submit">Release </button>
{!! Form::close() !!}
#endforeach
This is my store function and destroy function:
public function store(Request $request)
{
// Confirm Both Fields Are Not Empty
$this->validate($request, [
'first_name' => 'required',
'last_name' => 'required',
]);
//Add a new employee using the request data
$employee = new Employee;
$employee->first_name = request('first_name');
$employee->last_name = request('last_name');
$employee->position = request('position');
$employee->salary = request('salary');
$employee->hire_date = request('hire_date');
//$employee->attach = request('attach');
//Save it to the database
$employee->save();
//And then redirect back to the Employees page
return redirect('/employees');
}
public function destroy($id)
{
$employee = Employee::find($id);
$destroysignal = $employee->delete();
if($destroysignal) {
return redirect('employees');
}
}
You don't edit records, you update them. In your case you need an update() function in your controller
public function update(Request $request, $id)
{
$employee = Employee::findOrFail($id);
$employee->employment_status = true; //or false or whatever your statuses are
$employee->update();
return redirect()->back()->with('message', 'Employee updated!');
}
In your form, use the update route instead
{!! Form::model($employee, [
'method' => 'PATCH',
'route' => ['employees.update', $employee->id]])
!!}
<button type="submit">Release </button>
{!! Form::close() !!}
When using resource routes, 'route' => [ 'employees.edit', $employee->id] will most like to open a page where you want to edit the object. And the route will be bound to the edit($id) function of your controller.
With that said, the edit route doesn't need a form. A simple anchor would do
Edit Employee
I have a form controlling the search bar in the websites navbar:
public function searchFormAction()
{
$form = $this->createFormBuilder()
->setAction($this->generateUrl('search'))
->setMethod('GET')
->add("value", TextType::class, array('label' => false))
->add("Search", SubmitType::class)
->getForm();
return $this->render('components/search-form.html.twig', [
"form" => $form->createView()
]);
}
As you can see, the form has a specific action path to this function:
/**
* #Route("/search", name="search")
*/
public function searchAction(Request $request)
{
return $this -> render ("post/post-search.html.twig", [
"value" => $request->query->get('value')
]);
}
For now this shouldn't do much more than just display the value on the page.
The problem is that the website fails to redirect when the form is used
So when I put foo in the search, and click submit the path looks like this:
localhost:8000/page?form%5Bvalue%5D=foo&form%5BSearch%5D=&form%5B_token%5D=PsouIRAy2QaQ8j2XO_uYrs7PcaR6jyjQN3W3_xRMdgw
Moreover if I go to localhost:8000/search and try to put anything into the search bar, no value is printed.
Here is how the form is rendered:
//search-form.html.twig
<form class="navbar-form navbar-left">
{{ form_start(form) }}
<div class="form-group">
{{ form_row(form.value) }}
</div>
{{ form_row(form.Search) }}
{{ form_end(form) }}
</form>
And placed in the base navbar:
//base.html.twig
//...
{{ render(controller(
'AppBundle:Form:searchForm'
)) }}
//...
Inspecting the element shows that the form tag has no action and method attributes
What could be the issue here and how can I fix it?
Fixed! Made a simple mistake in the twig file.
Placed the form start inside html form tags, that way the submit button would send to an empty form.
I have a few problems.
I can't seem to display the saved data inside my form inputs.
I can't get my urls to validate unique.
My controller code looks very redundant.
Getting the urls to validate unique takes priority though.
Also I created the table for sharing social links with a user one to many relationship. I think thats correct. If not, please correct me.
update Just a thought...I think I'm probably complicating things by only have a single 'type' column. It would be easier if I had a column for each type of link i.e facebook col, twitter col etc. I just didn't want empty columns if user didn't provide info for some services
Heres my code:
UPDATE I gave up and just added individual columns for the different types of urls and changed to a one-to-one relationship.
form
{!! Form::model($user_links,['method' => 'PATCH', 'action'=> ['UserController#update_social']]) !!}
<div class='row form-group'>
<div class='col-md-2'>
{!! Form::label('facebook', 'Facebook Username') !!}
</div>
<div class='col-md-7'>
{!! Form::text('facebook', '',['class'=>'form-control']) !!}
</div>
</div>
<div class='row form-group'>
<div class='col-md-2'>
{!! Form::label('twitter', 'Twitter Username') !!}
</div>
<div class='col-md-7'>
{!! Form::text('twitter', null,['class'=>'form-control']) !!}
</div>
</div>
<div class='row form-group'>
<div class='col-md-2'>
{!! Form::label('reddit', 'Reddit Username') !!}
</div>
<div class='col-md-7'>
{!! Form::text('reddit', null,['class'=>'form-control']) !!}
</div>
</div>
<div class='row form-group'>
<div class='col-md-3'>
{!! Form::submit('Save Changes',['class'=>'btn btn-md btn-success']) !!}
</div>
</div>
{!! Form::close() !!}
controllers
public function show_social(Request $request){
$user_links= $request->user()->links;
return view('user.edit.social_connect',compact('user_links'));
}
public function update_social(SocialRequest $request){
$facebook= Input::get('facebook');
$twitter= Input::get('twitter');
$reddit= Input::get('reddit');
$user = $request->user();
$this->validate($request,['url'=>'unique']);
if(Input::has('facebook')||Input::has('google')||Input::has('reddit')||Input::has('twitter'))
{
if($facebook != ""){
$link = new SocialLinks();
$link->type = 'facebook';
$link->url='https//www.facebook.com/'.$facebook;
$link->user_id=$user->id;
$link->save();
}
if($twitter != ""){
$link = new SocialLinks();
$link->type = 'twitter';
$link->url='https//www.twitter.com/'.$twitter;
$link->user_id=$user->id;
$link->save();
}
if($reddit != ""){
$link = new SocialLinks();
$link->type = 'reddit';
$link->url='https//www.reddit.com/user'.$reddit;
$link->user_id=$user->id;
$link->save();
}
return Redirect::back()->with('message','Your profile has been updated');
}
return Redirect::back();
}
my model file
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Eloquent;
class SocialLinks extends Eloquent{
protected $table= 'social_links';
protected $fillable=[
'type',
'url'
];
public function user()
{
return $this->belongsTo('App\User');
}
}
?>
my request
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class SocialRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'url'=>'unique|user_id'
];
}
}
Okay, there are a few things wrong here. Your request file is being used incorrectly. You need a model for that, unless ofcourse you're just getting "request file" and "model" mixed up. For the purpose of this comment, I'm going to use Laravel's validation method from within the controller.
Something worth noting, your "url" is not present within the form. The validation looks for a "url" parameter inside of the request, but as you do not appear to be sending that within the form, it is quite redundant. Also, when you use the "unique" validator, you need to supply a database table for it to search and check against the supplied value, in this case; url.
I've added that in, but, really it's not doing anything because the url will always be empty until you supply it in your form, so the request will always pass.
public function show_social(Request $request)
{
$user_links = $request->user()->links;
return view('user.edit.social_connect', compact('user_links'));
}
public function update_social(Request $request)
{
$facebook = $request->facebook;
$twitter = $request->twitter;
$reddit = $request->reddit;
$user = $request->user();
$this->validate($request, [
'url' => 'unique:social_links,column',
]);
if($request->has('facebook') || $request->has('google') || $request->has('reddit') || $request->has('twitter'))
{
if($facebook != ""){
$link = new SocialLinks();
$link->type = 'facebook';
$link->url = 'https//www.facebook.com/'.$facebook;
$link->user_id = $user->id;
$link->save();
}
if($twitter != ""){
$link = new SocialLinks();
$link->type = 'twitter';
$link->url = 'https//www.twitter.com/'.$twitter;
$link->user_id = $user->id;
$link->save();
}
if($reddit != ""){
$link = new SocialLinks();
$link->type = 'reddit';
$link->url = 'https//www.reddit.com/user'.$reddit;
$link->user_id = $user->id;
$link->save();
}
return Redirect::back()->with('message','Your profile has been updated');
}
return Redirect::back();
}
As you can see, I removed the type hinting for your request because what you were actually doing (from what I can tell), was type hinting the model. Your "request file" which you supplied is a model and should be in the App/ directory, and referenced using a namespace.
If you are indeed using that file as a model, then your relationship looks okay, assuming of course you've got the right foreign column setup in your database, referencing the user table.
As for your model binding not working, have you tried dumping the $user_links variable, like so: dd($user_links); - to see if it actually contains anything? As you're using a request there, I cannot tell where you're getting the information.
Hopefully this helps, if you have any more questions, feel free to ask.