Blade #include directive - laravel

Blade's #include directive, allows you to easily include a Blade view from within an existing view. All variables that are available to the parent view will be made available to the included view. How can I hide parent values from the included view? I want to only use the variables sent to it or else, use the default variables.
For example, consider the following view. that can access a variable named $title
<a class="btn btn-danger" href="{{$url or URL::previous()}}"><i class="fa fa-arrow-left"></i>
{{$title or 'Save'}}
</a>

Not the prettiest solution, but I think I would handle it by putting all of those vars in an array:
<a class="btn btn-danger" href="{{$myData['url'] or URL::previous()}}"><i class="fa fa-arrow-left"></i>
{{$myData['title'] or 'Save'}}
</a>
and then including the view: #include('view', ['myData' => null])
Note, this is untested.

Related

Thymeleaf th:onclick event - calling confirm function

I am new to Thymeleaf. Recently I stumbled in the following situation. Here is a piece of my Thymeleaf html page:
<!-- an delete button link -->
<a th:href="#{/employees/delete(employeeId=${tempEmployee.emplId},firstName=${tempEmployee.firstName},lastName=${tempEmployee.lastName})}"
class="btn btn-danger btn-sm py-1 "
th:onclick="if(!(confirm('Are you sure you want to delete this employee ?') )) return false" >
Delete
</a>
This code works fine as intended. However I want to add employee name as part of the confirmation. Here is the code:
<!-- an delete button link -->
<a th:href="#{/employees/delete(employeeId=${tempEmployee.emplId},firstName=${tempEmployee.firstName},lastName=${tempEmployee.lastName})}"
class="btn btn-danger btn-sm py-1 "
th:onclick="if(!(confirm('Are you sure you want to delete this employee ' + '\'+${tempEmployee.firstName}+\'' +'?' ) )) return false" >
Delete
</a>
Unfortunately the result is:
Are you sure you want to delete this employee
'+${tempEmployee.firstName}+'.
Looks like Thymeleaf does not recognize ${tempEmployee.firstName}. It has no problem with it in th:href tag but does not like it in th:onclick.
I would appreciate if somebody can turn me into the right direction.
Not sure exactly what the problem is (though it may be related to onclick vs th:onclick. Regardless, I think a format more like this will work (with some added benefits like no JavaScript injection).
<!-- an delete button link -->
<a
th:href="#{/employees/delete(employeeId=${tempEmployee.emplId},firstName=${tempEmployee.firstName},lastName=${tempEmployee.lastName})}"
class="btn btn-danger btn-sm py-1 "
th:data-confirm-delete="|Are you sure you want to delete this employee ${tempEmployee.firstName}?|"
onclick="if (!confirm(this.getAttribute('data-confirm-delete'))) return false"
>
Delete
</a>
(Notice I'm using onlick and not th:onclick.
Instead of this line in above code ---onclick="if (!confirm(this.getAttribute('data-confirm-delete'))) return false">
You can write as:
onclick="return confirm(this.getAttribute('data-confirm-delete'))"

Laravel WhereIn Doesn't Accept Array Value

I have this on my blade file:
{{ Form::open(['route' => 'my_route_name']) }}
<button type="submit" class="btn btn-sm btn-success">
<i class="fa fa-file-excel-o" aria-hidden="true"></i> Download
</button>
{{ Form::hidden('my_ids', $my_ids) }}
{{ Form::close() }}
Checking on the chrome's developer mode, the value of my hidden textbox named my_ids is:
[1,2,3,4,5,6]
Upon clicking the Download button, it goes on my controller:
$results= Model::whereIn('id', $request->my_ids)->get();
This is where I am getting an error.
DD-ing dd($request->my_ids) on my controller gives me "[1,2,3,4,5,6]".
However, if I just put the values directly on the eloquent query like below, it would work.
$results= Model::whereIn('id', [1,2,3,4,5,6])->get();
Am I missing something here?
Your dd shows that $request->my_ids is a string, therefore you must parse it before you use it as array.
Try
$results= Model::whereIn('id', json_decode($request->my_ids))->get();

Laravel: How to create link buttons on a view dynamically?

I'm making a College Administration website where a professor can log in.
I have a dashboard, where my dynamically generated button should be placed: (right now it just has dummy buttons!)
Generated by this view file, which I will have to modify soon:
<div class="container d-flex flex-column align-items-center justify-content-center">
<h1>IA DASHBOARD</h1>
<br>
<div class="grid2">
SUBCODE 1</button>
SUBCODE 2</button>
SUBCODE 3</button>
</div>
Tables in the Database:
the table iamarks contains the data (student info, and marks) that is to be displayed after /subcode/{subcode} narrows it down to records of just the students that are in the class assigned to current logged-in professor.
classroom_mappers is a table used to map a professor to a classroom with a subject. It makes sure that one classroom only has one professor for a particular subject.
the routes currently in my web.php:
route::get('/ia', 'IAController#show')->middleware('auth');
Route::get('/subcode/{subcode}', 'IAController#showTable')->middleware('auth');
...and these are the methods inside my controller:
//shows buttons to the user:
public function show(){
$subcodes = DB::table('classroom_mappers')
->select('subcode')
->where([['PID','=', auth()->user()->PID]])
->get();
return view('ia',compact('subcodes'));
}
//when user clicks a button, subcode is to be generated and a table is to be shown:
//it works, I tried it by manually typing in subcode value in URL.
public function showTable($subcode){
$sem = DB::table('classroom_mappers')
->where([['PID','=', auth()->user()->PID],
['subcode','=',$subcode]])
->pluck('semester');
$division = DB::table('classroom_mappers')
->where([['PID','=', auth()->user()->PID],
['semester','=',$sem],
['subcode','=',$subcode]])
->pluck('division');
$data = DB::table('iamarks')
->where([['semester','=',$sem],
['division','=',$division],
['subcode','=',$subcode]])
->get();
return view('subcode',compact('data'));
}
My Problem:
To be able to generate the {subcode} in the URL dynamically, I want to create buttons in the dashboard using the data $subcodes. The controller hands over the $subcodes (an array of subject codes which belong to logged in professor) which are to be made into buttons from the show() method.
The buttons should have the name {subcode} and when clicked, should append the same subject code in the URL as {subcode}.
How do I make use of $subcodes and make the buttons dynamically?
How do I make sure the buttons made for one user are not visible to another user?
I managed to find the solution, thanks to Air Petr.
Apparently, you can't nest blade syntax like {{some_stuff {{ more_stuff }} }} and it generates a wrong php code. I modified the solution by Air Petr to:
<div class="grid2">
#foreach ($subcodes as $subcode)
<a href="<?php echo e(url('/subcode/'.$subcode->subcode));?>">
<button class="btn btn-outline-primary btn-custom-outline-primary btn-custom">
<?php
echo e($subcode->subcode);
?>
</button>
</a>
#endforeach
</div>
It generates the buttons perfectly. The buttons for one user are not visible to another, since I'm using PID constraint in a query (['PID','=', auth()->user()->PID]).
Pass the passcodes array to view:
$subcodes = []; // Array retrieved from DB
return view('subcode', compact('subcodes'));
And in subcode.blade.php, loop through each subcode:
<div class="grid2">
#foreach($subcodes as $subcode)
<a href="{{ url('/subcode/' . $subcode->subcode) }}">
<button class="btn btn-outline-primary btn-custom-outline-primary btn-custom">SUBCODE {{ $subcode->subcode }}</button>
</a>
#endforeach
</div>
You can loop your codes to create buttons. Something like this (it's for "blade" template engine):
<div class="grid2">
#foreach ($subcodes as $subcode)
{{ $subcode->subcode }}</button>
#endforeach
</div>
Since you're using PID constrain in a query (['PID','=', auth()->user()->PID]), you'll get buttons for that specific PID. So there's no problem.

VueJS routing on click to chapter quiz

I am new to vuejs. I need to create a router link quiz with path /chapter/{{id}}/quiz. it will open another component
Path
{ path: '/chapter/:id(\\d+)/quiz', component: require('./components/Quiz.vue') },
router link
<a href="#" #click="editModal(chapter)">
<i class="fa fa-edit blue"></i>
</a>
/
<router-link :to="/chapter/{{chapter.id}}/quiz">
<i class="fa fa-question-circle blue"></i>
</router-link>
Currently I am getting error
Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of <div id="{{ val }}">, use <div :id="val">
You cannot use {{ }} for attribute values. So for your router-link component you will have to use javascript string concatenation to add the chapter.id or use a computed property to generate the url.
<router-link :to="'/chapter/' + chapter.id + '/quiz'">
Or if you are using es6 you can use template literals:
<router-link :to="`/chapter/${chapter.id}/quiz`">

Laravel how to make that id would not be shown through inspect

I have form like this
<form action="{{ url('/reviews/delete', ['id' => $review->id]) }}"method="POST">
{{ method_field('DELETE') }}
{!! csrf_field() !!}
<a class="delete right-button"> <i class="fa fa-trash-o" aria-hidden="true"></i> </a>
</form>
When I use inspect I see the id and if I change it I can delete different record depends on which id I fill into inspection. How to avoid this?
You can check in the controller like so
abort_if($user->id !== $review->user_id, 404)
personally I like using policies https://laravel.com/docs/5.6/authorization#writing-policies
$this->authorize('delete', $review);
The thing is that HTML already renders the form and when you submit it, request reads the URL inside the action and goes there, so there is no 'real' answer on how to prevent it, but you can put some validation in the FormRequest.
If you want to go further you can create Model Policy and check if the review belongs to the user which is trying to remove it, or some other kind of validation.

Resources