how to add :before css conditionally react - reactjs

i want to conditionally add :before css selector to my dynamic product, currently its mutual fund but it can be later in future, please let me know how to do it
<div className={`${style.right_block}`}>
<ul className={`${style.three_points}`}>
<li className={`${style.mutual_fund}`} >{current_web.cat}</li>
<li className={`${style.beginner_icon}`}>{current_web.difficulty}</li>
<li className={`${style.time_icon}`}>{current_web.dur}</li>
</ul>
</div>
as you can see my product, difficulty, and dur(duration ) coming from api,
i want to chnage product :before icon based on my product,

If I understand the question correctly, you would like to conditionally add a :before css rule to a certain element?
<div className={`${style.right_block}`}>
<ul className={`${style.three_points}`}>
<li className={(yourCondition ? style.nameOfStyleInCssFileWithBeforeRule : style.normalStyle)} >{current_web.cat}</li>
<li className={`${style.beginner_icon}`}>{current_web.difficulty}</li>
<li className={`${style.time_icon}`}>{current_web.dur}</li>
</ul>
</div>

I recommend to use useState:
const [ConditinClass , setConditinClass] = useState(styles.NoBeforeStateMent);
Then to style your component :
<div className={ConditinClass} >
... your stuff
</div>
And to switch to class with before :
setConditinClass(styles.classWithBefore)
Be sure to create both classes.

Related

How to create template for cakephp paginator?

I am trying to apply bootstrap 4 pagination style in cakephp paginator helper.
It is looking very hard to me.
This my simple html that I want to apply in paginator helper
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>
I created a paginator-templates file in config location.
config/paginator-templates.php
return [
'number' => '{{text}}',
];
Then I have initialized in appView.php
public function initialize(): void
{
$this->loadHelper('Paginator', ['templates' => 'paginator-templates']);
}
After that getting below error
Config file "paginator-templates.php" did not return an array
How can I create a paginator-templates.php for apply bootstrap 4 pagination design in cakephp ? Has there any blog or example ?
What is the file returning?
One way to work around this might be to use the setTemplate() method on the helper.
https://book.cakephp.org/3/en/views/helpers/paginator.html#changing-templates-at-run-time
Using your supplied example code I've been able to get the code working in Cake 3.8.5
I wonder if you just forgot the opening <?php tag in your templates file so it's coming back as a string.

React implement active menu item in sidebar

I'm using React version 16.6.3. I need some help to implement active menu item in sidebar. I need to do this thing: when the user clicks on any <li> in sidebar, the <li> must become active (for example, it gets class "active").
If the <li> is active and have treeview class, then, inside it, set to <ul> class "show" (if any)
Here's the code:
import React , { Component } from "react"
export default class Sidebar extends Component {
constructor(props) {
super(props);
this.state = { 'activeItem': 0 }
}
render() {
return (
<div className="main-sidebar">
<section className="sidebar">
<ul className="sidebar-menu tree">
<li className="nav-divider"></li>
<li className="header">PERSONAL</li>
<li>
<a href="#">
<span>Dashboard</span>
</a>
</li>
<li className="treeview">
<a href="#">
<span>Application</span>
</a>
<ul class="treeview-menu">
<li>Chat app</li>
<li>Project</li>
<li>Contact / Employee</li>
</ul>
</li>
<li className="treeview">
<a href="#">
<span>Application</span>
</a>
</li>
</ul>
</section>
</div>
)
}
}
The first question you should ask yourself is (if not always) how you store the data of the user selection. You might have multiple activeItem because this is a tree, ex. multiple branches can be open or close at the same time. You need to look for a data structure to hold that thinking first.
Here's a simple one, give each item an id/key, <li key="1-0-0"> and then you can track onChange event of this li and then inside onChange you can use a flat array structure to store the current state of this simple tree. For example, {'1-0-0': true }
There're lots of different ways to do data part, the above one is a simple idea to get you started. And after that, based on the captured data, you can then update the children attribute of each node, ex. <li className={ getNodeAttr('1-0-0')> assuming getNodeAttr is a utility function that give you back the class name string given the node name.
You should not bind active state on a navigation sidebar because if a user type a route directly in a browser the menu item won't be highlighted.
Instead, try to bind the active state to the route with NavLink (if you use react-router):
ref: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/NavLink.js

ng-class not working in one situation. What are some possible cause of this?

I'm stuck. Cannot figured this out. This question is very simple to show, but I'm not really sure how to put it as a question, therefore I'll try my best.
First, here's the layout of my whole app (The problem lies in the Header.jsp):
<jsp:include page="../home/Header.jsp" />
<jsp:include page="../home/Modals.jsp" />
<div data-ng-view data-save-scroll-position data-position-relative-to-menu></div>
<jsp:include page="../home/Footer.jsp" />
The problem is very simple. I have the following data-ng-class in the data-ng-view section that change a tab to active if something is true (The problem is it won't work in one scenario even though it displayed true in the tab name):
<ul class="nav nav-tabs">
<li role="presentation" data-ng-class="tab.isSelected ? 'active' : ''" data-ng-repeat="tab in ctrl.tabs"
data-ng-click="ctrl.fetchBIReports(tab)">
</li>
</ul>
In the JSP that use data-ng-include for the above markup, there's a side nav to change to this page. Once clicked this side-nav, it highlighted the tab 'active' as expected (trying not to include the whole jsp):
<div class="side-navbar">
<ul>
<li class="{{ ctrl.navigate.path == 'bi/schedule' ? 'active-link' : 'normal-link'}}">
Schedule Reports
</li>
</ul>
</div>
<div class="content-right" data-ng-include="ctrl.navigate.path"></div>
content-right includes the JSP mentioned in the second markup.
So far, so good. Here's a demo of it working (including both side-navbar and content-right):
The problem is, in my Header.jsp, there's a nav bar that takes me to the same page. If it is clicked from a different page with different controller, then it works. But if I'm in the current controller and click that nav bar link, then data-ng-class does not take 'active' as its class. Here's the markup for the Header.jsp for that link:
<li class="dropdown" data-roles="['ROLE_ADMIN']">
<a href="#/bi" class="dropdown-toggle" data-toggle="dropdown" data-ng-click="ctrl.changeNavigation('bi/schedule')"
role="button" aria-haspopup="true" aria-expanded="false">BI Management<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Schedule Reports</li>
</ul>
</li>
Here is the demo of it not working even though it is printing out true in the UI:
The only problem is with this UI. All the data are populated. Records are displayed for the correct tab. Even side nav-bar is displaying the correct active class.
Your syntax for ng-class is off a bit. The format is "{ '[class-name]': [expression that evaluates to true or false] }". You can have multiple class values separated by commas each with their own expression. When an expression is true, the corresponding class is applied to the element and when it is false the class is removed from the element. The way you have written it would almost work for the plain class attribute, but you would need to include the interpolation characters: {{ and }}. Here is a very simple example to illustrate ng-class.
angular.module('app', []);
.red {
color: #fff;
background-color: #e21d1d;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app">
<label>
<input type="checkbox" ng-model="applyRedClass" /> Apply 'red' class
</label>
<div ng-class="{'red': applyRedClass}">
This is a simple example of how to use ng-class.
</div>
</div>

ng-repeat - content to show if array is empty or null

I've a deep nested ng-repeat lists, and only in the last loop I've to display alternate content if list was empty. I'm new to angular, saw some posts online please help me where can I use content if list is empty. The ng-repeat=sessions in day could be empty.
<ul class="day">
<li ng-repeat="sessions in day">
<ul class="table-view">
<li class="table-view-cell" ng-repeat="(heading, session) in sessions">
<span class="group">{{heading}}</span>
<ul class="cell">
<li class="cell-content" ng-repeat="val in session" ng-click="getSession(val.id)">
<div class="time" style="background-color:#{{val.color}}">
<span>{{val.start | date:"h:mma"}}</span>
<span>to</span>
<span>{{val.end | date:"h:mma"}}</span>
</div>
<div class="session" ng-class-odd="'odd'" ng-class-even="'even'">
<span class="name">{{val.name}}</span>
<span class="room">Room: {{val.room}}</span>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
1). CSS approach. I usually use pure CSS approach in such cases. With this markup (stripped extra-html):
<ul class="day">
<li ng-repeat="sessions in day">
...
</li>
<li class="no-sessions">
No sessions on this day.
</li>
</ul>
and CSS rules to hide .no-sessions li by default and make it visible only if there are no previous li tags:
li.no-sessions {
display: block;
}
li + li.no-sessions {
display: none;
}
So when sessions array is empty, there will be no li rendered and only no-sessions one will be visible. And if will hide as soon as there is at least one session on this day.
Demo: http://plnkr.co/edit/KqM9hfgTTiPlkdmEevDv?p=preview
2). ngIf approach. Of course you can use ngIf/ngShow directives for show no-records element when sessions array is empty:
<li ng-if="!day.length">
No sessions on this day.
</li>
I think this would work for your case:
<li ng-hide="day.length > 0">
No sessions on this day.
</li>
No extra CSS needed. Assumes day is an array.
http://plnkr.co/edit/WgDviOKjHKS1Vt5A5qrW
I would recommend handling that in your controller. Keeping your logic in the controller and javasript makes debugging easier and more manageable. I can think of 2 approaches: using ng-show/ng-hide or a condition for your day variable when its empty.
Option 1
ng-show/ng-hide approach:
$scope.isDayEmpty = function(){
return $scope.day.length > 0 ? false : true;
}
html:
<ul class="day">
<li ng-repeat="sessions in day" ng-hide="isDayEmpty">
...
</li>
<li ng-show="isDayEmpty">
No Sessions this Day
</li>
</ul>
Option 2:
ng-repeat approach
if($scope.day.length == 0){
$scope.day.push("No Sessions this Day");
}
This should get you essentially the same result. The first approach would make your CSS styling easier assuming you want to do something different in that case.
The second approach can vary in style depending on your code but thats an example of how you can do it. I don't know your javascript so I can't be more specific to your scenario.

jQuery live sibling-selector not working

I have this CSS selector, which just won't bind .live(), but works perfectly with .bind():
$('.treeView li ~ :has("ul")').prev('li')
I've read somewhere, that using the .prev() and .next() could be troublesome coupled with .live(), so I wanted to create an pure CSS selector (or ANYTHING that works with .live()!) to do the job - but I just can't figure it out!
Here's what I want to do:
Select all li-elements, which is followed by an li containing an ul.
Here's an HTML markup example, I want to select the ones where the comment says "selected"
<div class="treeView" id="processSegmentsTree">
<ul>
<li>Ostetanke</li> //selected
<li>
<ul>
<li>Tank 1</li>
<li>Tank 2</li>
</ul>
</li>
<li>Presse</li> //selected
<li>
<ul>
<li>Sub-leaf 1</li>
<li>Sub-leaf 2</li> //selected
<li>
<ul>
<li>test</li>
<li>test</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Any help is much appreciated, since this is a bit of a thorn in my eye :(
There is no such Selector to accomplish this task.
What I highly recommend you to do is to add ANYTHING as a flag to use when selecting your desired elements.
add attribute, wrapper, ANYTHING YOU WANT, then the task will be as easy as it should be.
This may work: // not css selector
$(".treeView li:has('ul')").prev();

Resources