How to send information from the vue.js file to the controller like an id? Laravel - Inertia-vue - laravel

I'm trying to open a page from a button, but I need to send the id of the item where the button is in. For context this is a discussion forum page, in the users dash they are shown the forums they can comment on and there is a button on the bottom of each, what I need to send is that forums id, so that when they click on the button it takes them to the correct forum view.
How can I do this?
I'm trying different ways
<el-button type="primary" #click="submit(f.id)">
Answer
</el-button>
submit($id) {
var link = 'comments/' + $id;
this.$inertia.visit('comments/' + $id, {
$id,
});
},
<inertia-link class="el-button el-button--warning"
:href="'comments/' + f.id">
Answer
</inertia-link>
In my routes web.php
Route::resource('comments', 'ReplyController');
Route::get('comments/{id}', 'ReplyController#index');
The index in the controller
public function index($id)
{
$forum = DiscussionForum::where('id', $id)
->with('comment', 'user')->first();
$comment = Reply::with('discussionForum', 'user')
->where('discussion_forum_id', $forum->id)
->orderByDesc('updated_at')->get();
return Inertia::render('Forum/Comment.vue', [
'forum' => $forum,
'comments' => $comment
]);
}
This is not working, the redirect shows me a blank window inside the main page? How can I send the forum id correctly?

The best way to do this is to add a name to the route so:
Route::get('comments/{id}')->name('comments')->uses('ReplyController#index');
Then you can pass your id in the inertia-link in this way:
<inertia-link class="el-button el-button--warning"
:href="route('comments', { f.id })">
Answer
</inertia-link>
This way can be used with Ziggy as mentioned in the docs.
https://inertiajs.com/routing

Use the emit function here: https://v2.vuejs.org/v2/guide/components-custom-events.html
Something like this:
yourMethod() {
this.$emit(
"someName",
this.id
);
}

Related

Correctly redirect to another page with inertia?

I"m trying to redirect on click to another page, for some reason it's not working. This is the code on my vue where the redirect buttons are. I've tried two different ways and neither are working.
<el-row class="import-btn">
<a :href="'/imports/teachers'">
<el-button type="warning">
Importar
</el-button>
</a>
</el-row>
<el-row class="import-btn">
<el-button type="warning" #click="redirectStudents()">
Importar
</el-button>
</el-row>
redirectStudents() {
this.$inertia.visit('/imports/students');
},
I have the web.php routes like this
Route::resource('imports/students', 'ImportStudentController');
Route::resource('imports/teachers', 'ImportTeacherController');
In both the controllers I currently just have the index() filled
public function index()
{
return Inertia::render('Import/Students');
}
public function index()
{
return Inertia::render('Import/Teachers');
}
In the vue files for Teachers and Students I have basic layout and titles for those pages, so they're not empty.
When I click on the <a :href=""> button I get redirected to the link but the page is totally blank and when I click on the other button it opens up like a window inside also blank.
What is the correct way to fix this?
Links
Creating a link in Inertia.js is pretty straight-forward. It has a custom tag as to denote that it's something that falls into the domain of the framework.
<inertia-link href="/">Home</inertia-link>
UPDATE: Since version 0.7.0 of inertia-vue and version 0.5.0 of inertia-vue3 there has been a breaking change with an update to how links work.
For your Vue.js 2 components:
import { Link } from '#inertiajs/inertia-vue'
<Link href="/">Home</Link>
For Vue.js 3 components:
import { Link } from '#inertiajs/inertia-vue3'
<Link href="/">Home</Link>
Under the hood there is a <a> tag, which also means that all attributes passed will be sent to that underlying <a> tag.
Redirect
If all you're really looking for is a simple link-click - and not a redirect per se - then you're fine with the above code.
If you're instead interesting in a redirect - for example after updating a user or the something similar - then simply using the Redirect facade like you would do in any other Laravel application is sufficient.
class UsersController extends Controller
{
public function store()
{
User::create(
Request::validate([
'name' => ['required', 'max:50'],
'email' => ['required', 'max:50', 'email'],
])
);
return Redirect::route('users');
}
}
If you've installed the Inertia.js laravel adapter package, then this redirect will return a 303 status code, which is the same as a 302 status code, except that the request is changed into a GET request.
Hope this helps!

Laravel 5.6 Like Button

I'm using this package here in Laravel 5.6 to add likes system in my project.
I have updated the models as per their documentation. However, I'm confused on how to use this package.
I have added tried the following which adds the logged in user to the particular article likes list when he visits the link.
public function show(ArticleCategory $articlecategory, $slug)
{
$categories = ArticleCategory::all();
$article = Article::where('slug', $slug)->first();
$user = User::first();
$user->addFavorite($article);
return view('articles.show', compact('article', 'categories'));
}
And in my user dashboard, I'm able to pull up all the articles which are liked by the user with
$user = Auth::user();
$favoritearticles = $user->favorite(Article::class);
But I'm looking for a functionality where I have a button on the article page where when a logged user clicks on it, he is added to the likes list. I haven't tried this before so stuck at this point.
I replaced
$user->addFavorite($article);
with
$user->toggleFavorite($article);
but that just toggles the favourite list. I mean when I visit the link once, the logged in user is added to the likes list. When I visit the link for the second time, the logged in user is removed from the likes list. The cycle is repeated.
Could anyone explain to me how to achieve the like functionality with a button?
you're almost there,
You have to add a button and on click you will trigger an AJAX request to the server to perform what you want without refreshing the page, here is an example:
First you'll add a button and give it an ID or class:
<button class="like">Like</button>
Then the moment you click on it, you'll call the url which you need to replace with the route to your function,
Then you have to declare a method like so:
public function like($slug)
{
$article = Article::where('slug', $slug)->first();
$user = \Auth::user(); //to get authenticated user...
$user->toggleFavorite($article); // toggle so if u already like it u remove it from the liked table
return response()->json(['status': 1])
}
And of course add the route to your routes.php:
Router::get('like/{slug}',"ArticleController#like");
then add the function (jQuery is used here) to hook the AJAX call
$('.like').on('click', function(){
$.ajax({
type: "GET",
url: 'wwww.example.com/articles/slug',
data: {slug: 'the slug'},
success: function(data){
alert('its done')
},
});
})
Create a form in you article page with a button
<form action="{{url('favorite/{$post->id}')}}" method="post">
#if($post->isFavorited())
<button type="submit">Remove from favorite</button>
#else
<button type="submit">Add to favorite</button>
#endif
</form>
create the favorite route and controller
Router::post('favorite/{id}',"ArticleController#toggleFavorite");
public function toggleFavorite($id) {
$article = ArticleCategory::find($id);//get the article based on the id
Auth::user()->toggleFavorite($article);//add/remove the user from the favorite list
return Redirect::to('article/{$id}');//redirect back (optionally with a message)
}

Laravel show username instead of id on edit profile

When the user has to edit their profile it shows the id like so Click to see the photo
that is not what I want. I want to replace it with the profile username and remove the edit part. I really hope someone is understanding what I'm asking for. let me show you what I am looking for something like this "localhost/lary/quickstart/public/profile/username"
here is what i have in my code
public function edit($id)
{
$pro=Profile::find($id);
return view('layouts.profileedit')->with('pro',$pro);
}
<span class="glyphicon glyphicon-pencil"></span>
Change your routes file as follows:
Route::resource('profile', 'ProfileController', ['except' => ['edit']]);
Route::get('/profile/{username}', 'ProfileController#edit');
Then change your ProfileController as follows
public function edit($username)
{
$pro=Profile::where('username', $username)->firstOrFail();
return view('layouts.profileedit')->with('pro',$pro);
}

how construct route pattern for an unknown number of tags - Laravel & Conner/Taggable

I have a blog and a quotationfamous sayings repository on one site.
The quotations are tagged and the entries are tagged too.
I use this rtconner/laravel-tagging package.
Now, what I want to do is to display ALL Quotation models which share the same tags as article.
The Eloquent syntax is simple, as the original docs provide an example:
Article::withAnyTag(['Gardening','Cooking'])->get();
possible solution
Optional routing parameters. The asker-picked answer in this question gives a solution:
//in routes.php
Route::get('/{book?}/{chapter?}/{topic?}/{article?}', 'controller#func');
//in your controller
public function func($book = null, $chapter = null, $topic = null, $article = null) {
...
}
my problem
In my app the shared tags might count more than 3 or 5. I will soon get an example with even 10 tags. Possibly more
My question
Does it mean that I have to construct an URL with 10 optional routing parameters? Do I really need sth like this:
Route::get('quotations/tags/{tag1?}/{tag2?}/{tag3?}/{tag4?}/{tag5?}/{tag6?}/{tag7?}', 'controller#func');
my question rephrased
I could create a form with only a button visible, and in a hidden select field I could put all the tags. The route would be a POST type then and it would work. But this solution is not URL-based.
I think you could process the slashes, as data:
Route::get('quotations/tags/{tagsData?}', 'controller#func')
->where('tagsData', '(.*)');
Controller:
public function controller($tagsData = null)
{
if($tagsData)
{
//process
}
}
Ok, this is my solution. As I have a tagged model, I dont't need to iterate through tags in url to get the whole list of tags.
The enough is this:
// Routes file:
Route::get('quotations/all-tags-in/{itemtype}/{modelid}', 'QuotationsController#all_tagged_in_model');
Then in my controller:
public function all_tagged_in_topic($itemtype, $id) {
if($itemtype == 'topic') {
$tags = Topic::find($id)->tags->pluck('name')->all();
$topic = Topic::find($id);
}
if($itemtype == 'quotation') {
$tags = Quotation::find($id)->tags->pluck('name')->all();
$quotation = Quotation::find($id);
}
// dd($tags);
$object = Quotation::withAnyTag($tags)->paginate(100);;
And it is done.
Now, the last issue is to show tags in the URL.
TO do that, the URL should have an extra OPTIONAL parameter tags:
// Routes file:
Route::get('quotations/all-tags-in/{itemtype}/{modelid}/{tags?}', 'QuotationsController#all_tagged_in_model');
And in the {url?} part you can just write anything which won't break the pattern accepted by route definition.
In your view you might generate an URL like this:
// A button to show quotes with the same set of tags as the article
// generated by iteration through `$o->tags`
<?php
$manual_slug = 'tag1-tag2-tag3-tag4`;
?>
<a href="{{ URL::to('quotations/all-tags-in/article/'.$o->id.'/'.$manual_slug) }}" class="btn btn-danger btn-sm" target="_blank">
<i class="fa fa-tags icon"></i> Tagi:
</a>

Laravel back using {{ URL::previous() }} doesn't work if there are validation errors

I want to make a cancel button on a simple CRUD edit form. However it seems that when there are validation errors the cancel button does not work.
I guess because it routes from controller#edit to controller#update the button just goes to controller#edit again instead of the actual previous page. Is this normal or did I do something wrong? How do I make it work?
attendee/edit.blade.php
<div class=pull-right>
{{Form::submit('Update',array('class'=>'btn btn-success'))}}
<a href = "{{URL::previous()}}" class = 'btn btn-warning'>Cancel</a>
</div>
{{ Form::close() }}
routes.php
Route::get('user/attendees', 'UserController#getAttendees');
Route::resource('attendee', 'AttendeeController');
attendee controller
public function edit($id)
{
$user = Auth::user();
if(empty($user->id))
return Redirect::to('/');
//return if attendee doesn't belong to user
if( !($user->attendee->contains($id)) )
return Redirect::to('user/index')->with( 'error', 'attendee id error.' );
$attendee = Attendee::find($id);
return View::make('attendees.edit', compact('attendee'));
}
/**
* Update the specified attendee in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
$attendee = Attendee::findOrFail($id);
$validator = Validator::make($data = Input::all(), Attendee::$rules);
if ($validator->fails())
{
return Redirect::back()->withErrors($validator)->withInput()->with('id', $id);
}
$attendee->update($data);
return Redirect::intended();
}
user controller
public function getAttendees()
{
list($user,$redirect) = $this->user->checkAuthAndRedirect('user');
if($redirect){return $redirect;}
// Show the page
return View::make('site/user/attendees/index', compact('user'));
}
It's actually working correctly, it's just the usage that is incorrect.
Take the following:
You submit a form at GET /attendee/edit/{id}
The form takes you to POST /attendee/edit/{id}
You fail validation and are redirected to GET /attendee/edit/{id}
You cannot link to a page using a method other than GET. Your previous route was actually POST /attendee/edit/{id} but the link will always be GET.
Instead, nominate a page to be redirected to, I usually use the index for the section.
I think you should add a hidden input, like this
{!! Form::hidden('redirect_to', old('redirect_to', URL::previous())) !!}
and use this value in your link:
cancel
Redirect::back() doesn't really accomplish the right thing when using the validator provided by Laravel. What I've done before is pass the page to redirect back to as a hidden input in the form, and simply ignore it using Input::except("return"). Here's what I mean:
// On your HTML Form
<input type="hidden" name="return" value="{{ Request::path() }}" />
// In your PHP Controller
$validator = Validator::make($data = Input::except("return"), Attendee::$rules);
if ($validator->fails())
{
return Redirect::to(Input::get("return"))->withErrors($validator)->withInput()->with('id', $id);
}
Hope that can help shed some light. Other options are returning to a higher up, such as instead of attendee/edit/{id} redirect to attendee/edit/, but it all depends on the structure of you website.
I am now using the browser back via JS in onclick. Seems to work:
<a onclick="window.history.back();">Back</a>
I used this jquery for the cancel button.
$(document).ready(function(){
$('a.back').click(function(){
parent.history.back();
return false;
});
});
May you use the Front-End validation to test the input validation without a need to reload the page. So the {{URL::previous()}} won't affected.
The simple way to do that is by using Ajax or validator.js in your Laravel cade.
Here is a full example how to use jquery ajax in Laravel 5 to test the validation, may help:
http://itsolutionstuff.com/post/laravel-5-ajax-request-validation-exampleexample.html

Resources