Laravel 5 Bind data to var for menu in header.blade.php - laravel

What is the best solution for creating a menu.
I have $menudata (dynamic from dbase) and want to pass it to a heade.blade.php to generate top menu.
$menudata = Menu::all();
#foreach($menudata as $value).......
How can i achieve that? What's the best way to do it?

Add below code within the boot method of the AppServiceProvider
View::composer('*', function($view)
{
$view->with('menudata', Menu::all());
});
Here, * means all views will receive $menudata.
Now you can use this like
#foreach ($menudata as $menu).....

If the menu is visible in every page then add the following in any service provider (e.g. in the AppServiceProvider):
public function boot() {
// ...
View::share("menudata",Menu::all());
//...
}
Then you can use the menu data in any view e.g.
#foreach($menudata as $value).......

Laravel-menu provides three rendering methods out of the box. However you can create your own rendering method using the right methods and attributes.
As noted earlier, laravel-menu provides three rendering formats out of the box, asUl(), asOl() and asDiv(). You can read about the details here.
{!! $MyNavBar->asUl() !!}
You can also access the menu object via the menu collection:
{!! Menu::get('MyNavBar')->asUl() !!}

Related

Backpack for Laravel: how to add 'delete' per-line button conditionally?

I've a parent model which can have n childs
So I want to show delete button ONLY if it has not children (hasMany relationship must return 0 records).
How can I show 'delete' link in each lines of a table (in the list operation), but ONLY if a condition is valid?
The easiest option I see is to use a custom view for the Delete button, instead of the one in the package. Depending on how wide you want this change to be made:
A. If you want to do that across all CRUDs - it's easy, just publish the view by running:
php artisan backpack:publish crud/buttons/delete
This will place the file in your resources/views/vendor/backpack/crud/buttons, for you to change however you like. Inside the delete button view you have the current entry available as $entry so you can do something like $entry->children()->count() if you want. Be mindful that this will be run ONCE PER LINE so if you show 50 lines in the table for example, you'd need to find a way to optimize this.
B. If you want to do that for just one CRUD (eg. do it for Categories but not for Products), then you can do the same thing (publish the button view), but rename the button to something different like delete_if_no_children.blade.php so that it doesn't get used automatically for all CRUDs. Then use it only inside the controllers you want, inside setupListOperation(), by removing the "stock" delete button and adding yours:
// using the Backpack array syntax
$this->crud->removeButton('delete');
$this->crud->addButton('line', 'delete', 'view', 'crud::buttons.delete_if_no_children', 'end');
// using the Backpack fluent syntax
CRUD::button('delete')->view('crud::buttons.delete_if_no_children');
Use
withCount('children')
Docs: withCount
Additionally you can wrap delete buttons with blade directive
#can('destroy', $model) disabled #endcan
Docs: #can
<?php
namespace App\Policies;
use App\Models\Model;
use App\Models\User;
class ModelPolicy
{
public function update(User $user, Model $model)
{
return $model->children_count === 0;
}
}
Docs: policy
A hasMany relationship will return an empty Collection when there are no associated records. You can then proceed to call isEmpty() on the collection to verify there are no child records (children).
Example in PHP:
$parents = Parent::with('children')->get();
And then in your template you can do:
#foreach($parents as $parent)
#if($parent->children->isEmpty())
<button>Delete</button>
#endif
#endforeach

Passing View Variable to Included Layout Template in Laravel 8

This is probably something simple, but it's doing my head in.
So, my layout blade template has this:
#include('layouts.partials.sidebar')
{{ $slot }}
#include('layouts.partials.footer')
#include('layouts.partials.scripts')
I create a view which loads a template. This I assume gets parsed in $slot.
return view('request', [
'boo' => 'Hoo'
]);
No problems, the page loads and the variable 'boo' is accessible as {{ $boo }} in the 'requests' template.
But my question is, how can I pass the 'boo' variable to an included file in the layout file? In this case the following:
#include('layouts.partials.scripts')
So, in 'layouts.partials.scripts' how can I access {{ $boo }}? At the moment I just get an undefined index error.
Thank you very much for the help.
#include('layouts.partials.scripts', ['boo' => 'Hoo'])
Laravel Docs
https://laravel.com/docs/8.x/blade#including-subviews
If you have a partial like a nav, header, or sidebar, part of the master layout from which you are composing other views. It requires data that doesn't change from one view to another, like navigation links. Then, instead of passing the data from each controller method, you can define a view composer in a service provider's boot() method:
Service Provider's boot method
public function boot()
{
View::composer('layouts.partials.sidebar', function ($view) {
//$links = get the data for links
return $view->with('links', $links);
});
}
Laravel Docs
https://laravel.com/docs/master/views#view-composers

how to add common variable for laravel and pass this data to all view all views

I want to create a global variable and pass this into all view, so I can get this variable into all blade template
basically, my need is to pass my general setting controller value into my common blade view like header.blade.php
Thanks in advance
For that you will need to add some code in the App->Providers->AppServiceProvider.php like this:
public function boot()
{
view()->composer('*',function($view){
$settings = Settings::firstOrNew(['id' => '1']);
$view->with('settings', $settings );
});
}
According to Laravel documentation you can use view composer:
https://laravel.com/docs/5.8/views#view-composers
for using this feature in app > AppServiceProvider and in boot method you can use this approach for passing parameter to specific view If you have data that you want to be bound to a view each time that view is rendered. this approach meet your need perfectly. for example you want to pass a parameter named userName to header.
View()->composer('header', function ($view){
$userName= "username"
$view->with(['userName'=>$userName]);
});

Joomla MVC Module delete model

I'm a newbie on Joomla developing and I'm trying to fix an old administration module made by 'someone before me'. Module's been developed using MVC Components, it has several CRUDs and I'm stucked at deleting an item. The template view adds the toolbar icon like this:
JToolbarHelper::deleteList('', 'paises.delete', JTOOLBAR_DELETE);
It also has at the list controller (DistribuidoresControllerPaises), the getModel function:
public function getModel($name = 'Pais', $prefix = 'DistribuidoresModel', $config = array('ignore_request' => true))
{
$model = parent::getModel($name, $prefix, $config);
return $model;
}
The model class:
class DistribuidoresModelPais extends JModelAdmin
When selecting an item on the list, and clicking the trash button an empty page opens with this ending:
administrator/index.php?option=com_distribuidores&view=pais
If I come back to grid, the item still remains.
Any suggestion?
Thanks in advance
You can debug this by enabling debugging from Joomla configuration or you can try to to check with exit with in "delete" function of "paises" controller and can check you get item ids in post request or not.
Also you are using view "pais" also using model "pais" then why you are using "paises" controller for delete function, you should use "pais" controller to delete.
Also provide delete function which you are using to delete items, it may contain some issue.

Understanding Ember Views

I'm looking for some clarification on views in Ember.js
Coming from a rails background and I'm trying to ignore any preconceptions. From what I understand of the ember framework there are 5 components:
Routes: This is where we define the state of the application. The state is reflected in the URL. We can also define data loading here. Route classes are defined and on startup ember creates route objects which last for the duration of the application.
Models: This is where object data is defined. Can also define computed properties. A model object is created for each json object returned from the server.
Controllers: This mediates interactions between the models and templates/views. Controller classes are defined and on startup ember creates controller objects which last for the duration of the application. There is only ever a single instance of each controller class.
Templates: These describe the generated markup.
Views: These are specific templates or dom elements relating to a model. These are used to define interface events and send them to the controller for handling. Not sure when to create these.
As an example lets say I have a EventsController that has data loaded on the applicationRoute:
ScheduleApp.EventsController = Ember.ArrayController.extend();
ScheduleApp.ApplicationRoute = Ember.Route.extend({
setupController: function() {
this.controllerFor('events').set('content', ScheduleApp.Event.find());
}
});
Now in my template instead of iterating over each and displaying the information I want to iterate over each and create an associated view so I can add interactions to each event. I presume I would need to create a new view for each event and have it display in my template. However, I'm not sure where I create these views. Do I define a view class and then ember will create a new view object each time I call it using the view helper? Eventually I would like to use the appendTo on the view to inject my events to different places in the dom. Where would this be defined?
I've tried reading over the ember.js guide for views but it describes the context of a creating a single view. I think I want to make many views for each event and then dynamically interact with those objects.
Up to now ember has been outrageously clever so I would assume there is a built in method for generating these views. After all, most user interfaces are full of lists that require interactions. The problem is the list I'm trying to make I then want to spread over the dom depending on its attributes.
As per your code, App.EventsController has a list of events, now let us say we want the UI to have a list of events displayed and for each event say we want the view to have a delete button which deletes the event when the user clicks
One way to accomplish is by using Ember.CollectionView, the collection view as the name suggests is tailored for these sort of requirements, in many Ember examples the usage of view is not defined because ember auto-generates it for you but in some cases we might need to explicitly define a view to meed our requirements
App.EventsView = Ember.CollectionView.extend({
// It needs a list of data to iterate upon
// We are binding it to the controllers content data which
// is a list of events
contentBinding: "controller.content",
appendSpan: function(){
view = Ember.View.create({tagName: 'span'});
this.get("childViews").forEach(function(child){
view.appendTo(child);
});
},
// Now we need to also define a view template that will be
// generated for all the elements in the content array
// This could in turn be another collection view if required
// I am going to keep it simple for now
itemViewClass: Ember.View.extend({
templateName: "event",
deleteEvent: function(){
// Implement Delete
this.get("content").deleteRecord();
},
notifyUser: function(){
// The record doesn't get deleted as soon as user clicks, the request goes to
// server and server deletes the record and sends back the response to the
// client, Hence I'm using an observer here on isDeleted property of the record
if(this.get('content.isDeleted')){
alert("Record deleted Successfully");
}
}.observes('content.isDeleted')
})
})
Important Note Inside the CollectionView definition this.get("content") refers to the array of events, while in itemViewClass this.get("content") refers to the single event object
//Defining the template
//Assuming the event model has a name property
<script type="text/x-handlebars" data-template-name="event">
Name: {{view.content.name}}
<a {{action deleteEvent target="view"}} href="#">Delete Event</a>
</script>
Now when you hit your application_url/events
you'll a list of events each event has a delete button, I hope this clears some concepts
For more information about CollectionView
Update as per the comment:
If you want to append another view to each child view, you can do so by editing the template of itemViewClass as follows
<script type="text/x-handlebars" data-template-name="event">
Name: {{view.content.name}}
<a {{action deleteEvent target="view"}} href="#">Delete Event</a>
{{ view App.SomeOtherView }}
</script>
it can be a partial too as follows
<script type="text/x-handlebars" data-template-name="event">
Name: {{view.content.name}}
<a {{action deleteEvent target="view"}} href="#">Delete Event</a>
{{ partial "somePartial" }}
</script>
or if you want to do it programmatically say, you click a button in the EventsView template and on click all the childs view must have a span tag appended to it(I am very bad at giving examples)
//This is the template for App.EventsController,
//template-name = "events" => view is App.EventsView and controller App.EventsController
<script type="text/x-handlebars" data-template-name="events">
<a {{action appendSpan target="view"}} href="#"> Append </a>
</script>
appendSpan is defined in the CollectionView

Resources