Variables that are defined in Livewire component but can’t be accessed in Laravel blade file - laravel-livewire

I have a controller in already done in Livewire and I’m trying to create a new Laravel controller and corresponding Laravel blade file (the purpose is that I was asked to complete the form in Laravel and then migrate it to livewire), and the question is that is it possible to access those Livewire variables into a Laravel controller and blade or need to create the new blade file and controller in Livewire right away? because I am still new in Livewire
public $application_type;
public $token;
public $application_id;
public $creditRows = [];
public $gigRows = [];
public $invIncomeRows = [];
public $loansRows = [];
public function render()
{
$country = country('my');
$states = $country->getDivisions();
$income_informations = DB::table('income_informations')->get();
$bank_names = DB::table('bank_names')->get();
$salutations = DB::table('salutations')->get();
$genders = DB::table('genders')->get();
return view('livewire.individual-loan-application-form-component',
compact('states', 'income_informations', 'bank_names', 'salutations', 'genders'));
}
Thanks a lot

Livewire works the same as Laravel when it comes to passing variables; they share the variables to the given view. If you were to include child components or parts, then the variables would be accessible there. However if you want them in a completely different view, you'd need to redefine those variables in a different controller/Livewire component.

Related

How do I pass data to a component in Laravel Livewire?

class Counter extends Component
{
public $counter = 0;
public $name;
public function mount($name)
{
$this->name = $name;
}
public function render()
{
return view('livewire.counter');
}
}
I'm trying to pass the name variable as parameter to the livewire component call like so #livewire('counter', ['name' => $name]) but receiving "Undefined variable $name" error. I have been following the livewire docs too, still same error. what could possibly be wrong? Thank you.
If $name is not defined, then it is not a property available in the blade file where you are including Livewire. Since we don't know anything about your blade file or controllers, I can't give you a direct answer. However, you should check if $name is set anywhere and if so, if it's available in your blade view. This error is not related to Livewire. If you've simply copied the docs without checking the variables, you might as well set it right away:
#livewire('counter', ['name' => 'Gilles'])

Custom form field in views

I'm trying to create a custom field for a view in Drupal 8 which allows to perform an action without changing the page (link). I guess I have to create a form inside that custom field but I do not know how to achieve it.
Any idea on how to do it or other alternative without redirecting to a route?
The view will be a list of custom entities and I need a button for each of the lines.
Thanks in advance!
Finally I solved it by following this steps:
I created a view custom field (generate:plugin:views:field with
drupal console)
I created a form (generate:form)
Then, in the view custom field render function return the form:
$form = \Drupal::formBuilder()->getForm('Drupal\test_module\Form\TestForm', $values->_entity->ID());
return $form;
It's important to notice that an incremental (dynamic) formId is needed for things to work properly. I did that by creating a static variable and a __construct() method as follows:
protected static $instanceId;
public function getFormId() {
return 'my_form_id_' . self::$instanceId;
}
public function __construct(){
if (empty(self::$instanceId)) {
self::$instanceId = 1;
}
else {
self::$instanceId++;
}
}

Laravel 5 - global Blade view variable available in all templates

How can I in Laravel 5 make global variable which will be available in all Blade templates?
Option 1:
You can use view::share() like so:
<?php namespace App\Http\Controllers;
use View;
//You can create a BaseController:
class BaseController extends Controller {
public $variable1 = "I am Data";
public function __construct() {
$variable2 = "I am Data 2";
View::share ( 'variable1', $this->variable1 );
View::share ( 'variable2', $variable2 );
View::share ( 'variable3', 'I am Data 3' );
View::share ( 'variable4', ['name'=>'Franky','address'=>'Mars'] );
}
}
class HomeController extends BaseController {
//if you have a constructor in other controllers you need call constructor of parent controller (i.e. BaseController) like so:
public function __construct(){
parent::__construct();
}
public function Index(){
//All variable will be available in views
return view('home');
}
}
Option 2:
Use a composer:
Create a composer file at app\Composers\HomeComposer.php
NB: create app\Composers if it does not exists
<?php namespace App\Composers;
class HomeComposer
{
public function compose($view)
{
//Add your variables
$view->with('variable1', 'I am Data')
->with('variable2', 'I am Data 2');
}
}
Then you can attached the composer to any view by doing this
<?php namespace App\Http\Controllers;
use View;
class HomeController extends Controller{
public function __construct(){
View::composers([
'App\Composers\HomeComposer' => ['home'] //attaches HomeComposer to home.blade.php
]);
}
public function Index(){
return view('home');
}
}
Option 3:
Add Composer to a Service Provider, In Laravel 5 I prefer having my composer in App\Providers\ViewServiceProvider
Create a composer file at app\Composers\HomeComposer.php
Add HomeComposer to App\Providers\ViewServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use View;
use App\Composers\HomeComposer;
use Illuminate\Support\Facades\Blade;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
//add to all views
view()->composer('*', HomeComposer::class);
//add to only home view
//view()->composer('home', HomeComposer::class);
}
}
Create a new Service Provider as suggested in here
Add your new Service Provider to the configuration file (config/app.php).
In the boot method of your new Service Provider use:
View::share( 'something_cool', 'this is a cool shared variable' );
Now you are ready to use $something_cool in all of your views.
Hope this helps.
Searching for solution of the same problem and found the best solution in Laravel documentation. Just use View::share in AppServiceProvider like this:
View::share('key', 'value');
Details here.
You can do this with view composers. View composers are executed when a template is loaded. You can pass in a Closure with additional functionality for that view. With view composers you can use wildcards. To make a view composer for every view just use a *.
View::composer('*', function($view)
{
$view->with('variable','Test value');
});
You can also do this without a closure as you can see in the docs.
View::composer('*', 'App\Http\ViewComposers\ProfileComposer');
The profile composer class must have a compose method.
View composers are executed when a view is rendered. Laravel has also view creators. These are executed when a view is instantiated.
You can also choose to use a BaseController with a setupLayout method. Then every view which you will load is loaded through the setupLayout method which adds some additional data. However, by using view composers you're pretty sure that the code is executed. But with the BaseController approach you've more flexibility because you can skip the loading of the extra data.
EDIT: As mentioned by Nic Gutierrez you can also use view share.
Also, you can do this in the Route.php file:
view()->share('variableName', $variable);
I would rather use middleware with the view() facade helper. (Laravel 5.x)
Middleware is easier to mantain and does not make a mess in the controllers class tree.
Steps
Create the Middleware
/app/Http/Middleware/TimezoneReset.php
To create a middleware you can run php artisan make:middleware GlobalTimeConfig
share() the data you need shared
<?php
namespace App\Http\Middleware;
use Closure;
class GlobalTimeConfig
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$time_settings = [
'company_timezone' => 'UTC',
'company_date_format' => 'Y-m-d H:i:s',
'display_time' => true,
];
view()->share('time_settings', $time_settings);
return $next($request);
}
}
Register the newly created middleware
Add the middleware to your middleware route group as per example below
/app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\GlobalTimeConfig::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
Access data from templates
Access the data from any template with the given key in the View::share() method call
eg.:
Company timezone: {{ $time_settings['company_timezone'] }}
EDIT:
Nic Gutierrez's Service Provider answer might be a better (or the best) solution.
and you can give array not just View::share('key', 'value');
can put array like View::share(['key'=>'value','key'=>'value'])
You can add in Controller.php file:
use App\Category;
And then:
class Controller extends BaseController {
public function __construct() {
$categories = Category::All();
\View::share('categories', $categories);
}
}
you can flash it into the session, you can define it in the .env file (static vars)

Nest non-blade layout in Laravel?

I have a master layout with #yield('content') but I need my controller to inject a non-blade file into the content section. How can I achieve this?
I've tried in my controller:
protected $layout = 'master';
public function showWelcome()
{
$this->layout->nest('content', 'welcome')->render();
}
Where welcome is an not a blade file. Is this possible or just a limitation of Laravel?

Why use templates in Kohana?

I don't understand the purpose of using templates in Kohana. I see almost no difference in the process of building a view with a template controller vs a regular controller, except that the template controller is tied to a given template and so is less flexible. What are the advantages?
Building view with regular controller:
Class Controller_Hello extends Controller
{
public function action_index()
{
$view = View::factory('page');
$view->page_title = 'My Hello App';
$view->content = 'hello, world!';
$view->sidebar = View::factory('parts/sidebar');
$this->response->body($view);
}
}
Building view with template controller:
Class Controller_Hello extends Controller_Template
{
public $template = 'page';
public function action_index()
{
$this->template->page_title = 'My Hello App';
$this->template->content = 'hello, world!';
$this->template->sidebar = View::factory('parts/sidebar');
}
}
Controller_Template is just an example of how you can implement your own templating-system.
It is not ready-to-use solution (at least for my projects usually). Check this one controller (it is also not ready-to-use solution but possibly it will help you understand point of extending different controllers for different purposes): http://pastie.org/2563595
I am sure there are other, maybe better solutions for templating systems. But why am I using templates in Kohana?
Think about multiple pages, all based upon one layout/design scheme. So I build a template controller using a certain view, defining layout/design, defining content, header and footer "areas". In the template controller I am loading the CSS files and script files, setting the title and meta values of the website, because every single site is using these CSS/script files with the same meta values and title.
So in every Controller extending the template controller I don't need to load the CSS/script files anew, set the meta values and title etc... But I could change all these values, maybe add a CSS file only for a single site.
Maybe all the mentioned sites have the same footer and/or header: I assign the header/footer view to the template within the template controller, so I don't need to do that in all the controller extending the template controller. Or all actions in one controller have the same header/footer, so I assignt he header and footer few in the before() function of the controller...
For me templates in kohana are a good utility for building small web applications.