how to pass values from controller to layout file in yii2 - yii2

I'm trying to pass a variable value from controller to my main.php layout file but i keep getting error Undefined variable: contentWrapperBackground. below is my code
controller
public function actionList()
{
$contentWrapperBackground = "ff4400;";
$contentBackground = "3c8dbc;";
return $this->render('list', [
'contentWrapperBackground' =>$contentWrapperBackground,
'contentBackground' => $contentBackground,
]);
}
and in my layout file like this
<div class="content-wrapper" style="background-color:#<?=$contentWrapperBackground?>">
<!-- Content Header (Page header) -->
<!-- Main content -->
<section class="content" style="background-color:#<?=$contentBackground?>">
but i always get error Undefined variable: contentWrapperBackground. I'm trying to change the background color of for different pages. any help on this, and am also open to another idea on how to make this work thanks

don't use session for this!
Simple solution:
class Controller extends \yii\web\Controller
{
$public $contentWrapperBackground;
$public $contentBackground;
}
class YourController extends Controller
{
public function actionList()
{
$this->contentWrapperBackground = "ff4400;";
$this->contentBackground = "3c8dbc;";
return $this->render('list', []);
}
}
in your main layout
<div class="content-wrapper" style="background-color:#<?=Yii::$app->controller->contentWrapperBackground?>">
or another option
<div class="content-wrapper" style="background-color:#<?=$this->context->contentWrapperBackground?>">

you can set param in controller
Yii::$app->view->params['paramName'] = 'data';
get data in layout
$this->params['paramName'];

Related

Custom Blazor Server Component Not Invoking the OnClick Function

I have created a layout component in the same directory as with the MainLayout component. The CustomLayout #inherits LayoutComponentBase and has #Body which gets the content to be rendered inside the layout.
As obviously expected, the layout component has its own css files and UI display is fine. I am only having a problem with the #onclick function. It cannot be invoked. Is there a way to trigger the function on button click?
The reason I want to do this is that I am creating a navigation bar which will have to show/hide a dropdown. I hope I can get some ideas on this. Appreciated.
I am calling a server function this way: #onclick="SomeFuction" or #onclick="SomeFuction" or #onclick="#(() => SomeFuction())"
LayoutComponent:
#inherits LayoutComponentBase
#Body
Home page referencing a custom layout:
[AllowAnonymous]
[Layout(typeof(CustomLayoutComponent))]
[AllowAnonymous] is just for allowing anonymous access.
I am using Blazor Server and .NET 6
Additional Information:
I have put all the code in one page so that it becomes easier to read and understand.
Here is the LayoutComponent razor component:
#inherits LayoutComponentBase
<div class="navbar" id="custom-navbar">
<div class="wrapper">
<a>Home</a>
<a>Service</a>
<button class="btn btn-primary" #onclick="ToggleProductsUI">Products</button>
</div> </div>
<!--Component to show Products UI Component. Scoped css for styling-->
<ProductsComponent TValue="string" UIState="#ProductsUIState"></ProductsComponent>
#code{
// state of the Products submenu Component
string ProductsUIState { get; set; }
// a control function for toggling the Products UI
// this function somehow is not invoked.
void ToggleProductsUI()
{
if (string.IsNullOrWhiteSpace(ProductsUIState))
{
ProductsUIState = "show-ui";
return;
}
ProductsUIState = string.Empty;
}
}
Here is the ProductsUI component code (I have removed the unnecessary event to avoid confusion. The component can be fully controlled by the parent):
public partial class ProductsComponent<TValue> {
[Parameter]
public string? UIState { get; set; } }
Blazor pages that will use the custom layout component will point to it like this:
[AllowAnonymous]
[Layout(typeof(CustomLayoutComponent))]
public partial class Index
{
}
This is working fine. The issue is in the CustomLayoutComponent when trying to invoke the ToggleProductsUI() function
I accidentally inluded a <body> element in the layout and as such, the <script src="_framework/blazor.server.js"></script> was not being run hence the click event was not being invoked. I removed the <body> element. I was misled by the default body{} style in the underlining scopped css. Resolved.

Loop through database table in Laravel Vue js Component

This is an example of what I want to achieve in the vue component
<div v-for="emotion in emotions" class="cb-row">
<h2>{{ emotion.em_name }}</h2>
</div>
I have created a function in the EmotionsController to return all data from the table
class EmotionsController extends Controller
{
public function getEmotions() {
$emotions = Emotions::all()->get();
return $emotions;
}
}
How do I then get this data into my vue component? It's being loaded into a form
You have to refer laravel documentation first. because it gave you everything what you want.
Here's the link of your question
https://laravel.com/docs/6.x/frontend#writing-vue-components

Vue.js class bindings, inserts empty space between css classes

I am using a v-bind:class binding on a component, with the goal of turning a css class on and off depending on the truthiness of a boolean in my Vue.js component.
When I in my template declare:
<aside v-bind:class="{'--opened':sidebarVisible}" class="sidebar" id="sidebar">
Script part of my component:
<script>
import { EventBus } from "#/event-bus.ts";
export default {
data(){
return {
sidebarVisible:false
}
}
//Cut for breavity
};
</script>
I expect Vue.js to modify the class to class="sidebar--opened" but instead I get class="sidebar --opened" (with an empty space between sidebar and --opened). How can I get around this behavior?
you have to give it full name of the class as this line will add a separate class to it. so the solution would be
<aside v-bind:class="{'sidebar--opened':sidebarVisible}" class="sidebar" id="sidebar">
Note: If it doesn't work then you might have to remove class 'sidebar' explicitly.

How to add css class to body tag in layout in yii2?

I want to add css class to body tag in yii2 advanced in frontend/views/layouts/main.php how can I do it?
You can do this dynamically like this:
<body class="<?= $this->context->bodyClass; ?>">
And in main Controller (all other controllers should extend this Controller) define property:
public $bodyClass;
or for default value:
public $bodyClass = 'custom-skin';
Ofc you can override this property in any extending controller by redefining it:
public $bodyClass = 'custom-skin-2';
In init:
public function init() {
parent::init();
$this->bodyClass = 'custom-skin-2';
}
In specific action:
public function actionView()
{
$this->bodyClass = 'custom-skin-3';
return $this->render('view');
}
You add your class simply to body tag
<body class="yourClass">
Another possible solution would be using the variable $params in your view.
Example
In your view you can define:
$this->params['bodyClass'] = 'yourclass';
And then, in your layout file, you'd go:
[.. head and other codes ..]
<body <? if(isset($this->params['bodyClass'])) echo 'class="' . $this->params['bodyClass'] . '"'; ?>>
<?php $this->beginBody() ?>
[.. rest of your code ..]
Notice that
I'm suggesting you to use the if so it only puts the class if it the $params['bodyClass'] is set in your view.
Also, you can use whatever name you want in the place of bodyClass.
This example will output <body class="yourclass">
Cheers.

Is it possible to impact visibility of a DOM element outside of view?

My question is very similar to Hide element outside the ng-view DOM based on route
If possible I would like to have a TypeScript solution that allows to assign a value to ng-show property of an element outside of ng-view from my existing controllers.
I tried assigning a value to $rootScope property but it was not visible in index.html outside of the view.
Here's what I tried in controller constructors:
$rootScope.isForm = "true"; in one, and $rootScope.isForm = "false"; in another.
Inside my index.html I have the following:
<div class="navbar navbar-inverse">
....
<form <form class="navbar-form navbar-input-group" ng-show="$rootScope.IsForm">
...
</form>
...
</div>
...
<div "ng-view">
...
</div>
How should I go about it? Is there still a solution using $rootScope?
You can get the $rootScope inside your controllers and modify it there. i.e.
class FooController{
static $inject = ['$rootScope'];
constructor(public $rootScope){
// You can also do this based on some user action.
// Just a demo of how :
this.$rootScope.IsForm = true;
}
}