Why does riot.js break css? - css

In order to learn riot.js I started from well-known bootstrap navbar example. Then I added my custom tag using riot.js:
<script type="riot/tag">
<menu-item>
<li><a href={this.href}><yield/></a></li>
this.href = opts.href
</menu-item>
</script>
<script src="https://cdn.jsdelivr.net/g/riot#2.2(riot.min.js+compiler.min.js)"></script>
<script>
riot.mount('*')
</script>
Finally I tried to use my new tag, replacing
<li>JavaScript</li>
by
<menu-item href="http://getbootstrap.com/javascript">JavaScript</menu-item>
Result is broken. Why? (original non-broken example can be found here: jsfiddle.net/0hp9pwpu)

Your riot tag markup is inserted into your riot tag i.e. what happens is
ul
li
from your working example is actually
ul
menu-item
li
in your non-working example. Since bootstrap styles the navigation items expecting a certain hierarchy, your result is broken.
This was raised as an issue (https://github.com/riot/riot/issues/295) and closed using https://github.com/riot/riot/pull/569 i.e. instead of using the riot tags directly there is an option to add the riot tag as an attribute. So something like
<li riot-tag="menu-item" href="http://getbootstrap.com/javascript">JavaScript</li>
Admittedly, it is not as semantic
Fiddle - http://jsfiddle.net/86khqhwu/

Bootstrap is not adapted for use with Riot.js
Your resulted html is :
<menu-item href="http://getbootstrap.com/javascript">
<li>
JavaScript
</li>
</menu-item>
Bootstrap css is broken ...

Perhaps not so elegant, but in riot 2.3.13 I'm using something like this in a .tag file:
<menu-bar>
<ul list="<yield/>">
<li each={ item in items }>
{ titles[item] }
</li>
</ul>
<script>
this.titles = {
inventario: 'Inventario',
resguardos: 'Resguardos',
catalogos: 'Catálogos',
reportes: 'Reportes',
configurar: 'Configurar',
utilidades: 'Utilidades'
}
this.items = null
this.on('mount', function () {
var el = this.root.querySelector('ul')
this.items = el.getAttribute('list').trim().split(/,\s?/)
el.removeAttribute('list')
this.update()
})
</script>
</menu-bar>
Now, in the HTML page:
<menu-bar>
inventario,resguardos,catalogos,reportes
</menu-bar>
Works.

Related

Adding and Removing Styles to li group using Angular 2

<ul>
<li (click)="AddColor($event)">ONE</li>
<li (click)="AddColor($event)">TWO</li>
<li (click)="AddColor($event)">THREE</li>
</ul>
AddColor(e){
e.srcElement.style.color="blue"
}
I have the above list when i click any one of the li item out of 3, the clicked label color should be changed. when i click another all item colors should be revert back to original and change color of current clicked item.
#Mehdi said, you should not access DOM directly untill there is a need.
Always keep in mind, drive your view with data rather than accessing
DOM directly
I have forked and working snippet https://plnkr.co/edit/fgINMc?p=preview
When using Angular, you don't want to directly manipulate the DOM element. Rather let angular deal with it.
In your example, you can generate your list from an array you declare in the code like so
export class YourClass{
links:any;
activeLink = -1;
//...
constructor(){
this.links = ['ONE','TWO','THREE']
}
//...
}
and then in your template you could have :
<ul>
<li *ngFor="let link of links; let i = index"
(click)="activeLink = i"
[ngClass]="activeLink == i? 'blue' : '' " >
</li>
</ul>
and declare a css class blue :
.blue{
color:blue;
}

ng-class doesn't set image-background after rendering

I'm looking to set the background image of a div dynamically using ng-style. There are a couple of answers, but none work for me.
I've realised that for a simple case as shown below, there's no problem
<li ng-style="{'background-image': 'url({{ image.source }})'}">...</li>
where $scope.image = ... is defined. Or even more straightforward:
<li ng-style="{'background-image': 'url(http://example.com/image.png)'}">...</li>
But supposing you have the following:
<li ng-style="{'background-image': 'url({{ item.image_url }})'}">...</li>
and in your controller:
$scope.item = undefined;
Items.get({id: 1})
.then(function (item) {
$scope.item = item;
});
Item becomes available after the template has been rendered. And I find that angular just sets the background-image to the host url
<li ng-style="{'background-image': 'url({{ item.image_url }})'}" style="background-image: url(http://localhost:3000/);">
</li>
I could use a custom directive for this, but if there's a simple way of getting this to work, I'd prefer this over a directive.
Here's a plunker demonstrating the issue:
http://plnkr.co/edit/5JsK4njQi7Kc3ShUtRIw?p=preview
ng-style already binds the scope variables, so you don't need to add the curly braces, but could simply concat the correct string value:
ng-style="{'background-image': 'url(' + item.image_url + ')' }"
http://plnkr.co/edit/b9htGOTY6LBeHQMQNYXV?p=preview
ng-style="{'background-image': 'url({{item.image_url}})' }"
Plunker
<div ng-if="item.image_url" class="img-div" ng-style="{'background-image': 'url({{item.image_url}})' }"></div>
Use ng-if so when item.image_url get value after that your element is get rendered.
Plunker example

Style on Last Words

I have a long list of <li>s. A piece of JQuery code below helps me to style the last words of each <li>. Please take a look here
The issue now is I don't want it apply the style to the last <li>.
Could could I do that?
Here is my whole code. Please take a look
<html>
<script>
$(document).ready(function(){
$('li').each(function(){
var $this = $(this), text=$this.text().trim(), words = text.split(/\s+/);
var lastWord = words.pop();
words.push('<span class="Red">' + lastWord + '</span>');
$this.html(words.join(' '));
});
});
</script>
<style>
.Red{color:red}
</style>
<body>
<li>my holy tag galore</li>
<li>my sandwich is balloney</li>
<li>the expected is not to be </li>
<li>oh REALLY? </li>
<script type="text/javascript" src="JQuery-1.10.2.js"></script>
</body>
</html>
Thank you very much!
The only problem I see is your "Red" and "Bold" classes might not really be defined actually. I've tested your code myself and it works just fine - it adds the said classes to the last word.
However, just to keep it simple (um, alright ... for the RegEx's sake) you could use the replace function, just like this:
$('li').click(function(){
var $t = $(this);
$t.html($t.text().trim().replace(/(\w+)[.!?]?\s*$/, "<b>$1</b>"));
});
It surrounds the last word with <b></b> tags. Just replace them with whatever you like. The click event is also for the sake of testing, you can always change it to each function or anything else, really.
Here's a break down on how this RegEx actually works:
https://stackoverflow.com/a/3648147/1368043

bootstrap fixed header when scrolling down

I am working within bootstrap's core admin structure and have a main header at the top of the page and then a sub header beneath it. I am trying to allow that sub header to fix to the top of the page when the user scrolls down so they can always see that information, but I am having a bit of trouble.
The section I would like to stick to the top looks like this.
<div class="area-top clearfix" >
<div class="pull-left header">
<h3 class="title"><i class="icon-group"></i>Dashbord</h3>
</div><!--.header-->
<ul class="inline pull-right sparkline-box">
<li class="sparkline-row">
<h4 class="blue"><span> Cover Designs</span> 4</h5>
</li>
<li class="sparkline-row">
<h4 class="green"><span> Video Trailers</span> 5</h5>
</li>
<li class="sparkline-row">
<h4 class="purple"><span> Web Banners</span> 5</h5>
</li>
</ul>
</div><!--.area-top-->
and I have tried so far to wrap that in another div with the navbar navbar-fixed-top classes. But that shot it to the top right away and overlapped content that needs to be seen.
I have also tried using plain css by adding position:fixed; to the current div, but that messes up the breadcrubms I have laying underneath it because it takes it out of the flow.
Is there anyway to accomplish this with just css. I know I can do a hack with jquery, but in my team I am only in charge of the css.
you can use below css to the sub header navbar.
css:
.sticky-top {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 1020;
}
Add 'sticky-top' class to sub header.
for eg: you can see the fiddle below which is similar to the question.Here second menu fixed to top when user scrolls.
https://jsfiddle.net/raj_mutant/awknd20r/6/
position:fixed is the way to go here. Can you apply a height to the div you want to be fixed and apply a margin to the breadcrumbs?
.area-top{ position:fixed; height:2em; }
.breadcrumbs { margin-top: 2.2em; }
My point of view is the following. When you ask for this :
to fix to the top of the page when the user scrolls down
It means that you need to detect when users are scrolling. Furthermore, there is no other way than js / jQuery to detect this kind of action. CSS can be a part of solution by creating a class for exemple which will stick your menu, but you'll always need a bit of js to detect when to put and to remove the class.
Here is an exemple on how to do this in jQuery :
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script type="text/javascript">
$(window).scroll(function(){
var offset = $('.area-top').offset().top;
var top = $(document).scrollTop();
if(top >= offset){
// this is where you should fix you menu
$('.area-top').addClass('fixed'); // if you have a css class which fix the element.
$('.area-top').css('position', 'fixed'); // if you don't have css class
}else{
// this is where you should unfix your menu
$('.area-top').removeClass('fixed'); // if you have a css class which fix the element.
$('.area-top').css('position', 'inherit'); // if you don't have css class
}
});
</script>
Don't forget that every "advanced" action which need to detect a change in the DOM or which need an user interaction will require some JS or PHP to deal with it. By "advanced", i'm meaning all the things that can't be natively handle in HTML.

Is it possible to set a style of link that shows only when the linked webpage is being viewed?

I got a problem like this (this is html/css menu):
Eshop | Another eshop | Another eshop
Client wants it work like this:
User comes to website, clicks on Eshop. Eshop changes to red color with red box outline. User decides to visit Another eshop, so Eshop will go back to normaln color without red box outline, and another eshop will do the red outline trick again..
I know there is A:visited but I don't want all visited menu links to be red with red box outline.
Thx for any help :)
The same that Joe Skora has written but more specific:
.red {
outline-color:red;
outline-width:10px;
}
Now you could use Javascript (in this example using jQuery) in the click-event-handler:
$('.red').removeClass('red'); // removes class red from all items with class red
$(this).addClass('red'); // adds class red to the clicked item
Another way of doing it is the use of the pseudo selector :target.
For informations about it: www.thinkvitamin.com
You can do this with plain CSS and HTML. A method we commonly use is to have a matching ID and class selector for each navigation item.
The benefit to this is that you don't have to modify your menu code per page, you modify the page itself, which you'll already be doing unless everything is fully dynamic.
It works like this:
<!-- ... head, etc ... -->
<body>
<ul class="nav">
<li>Home</li>
<li>Art</li>
<li>Contact</li>
</ul>
<!-- ... more page ... -->
</body>
Then you set up some CSS like this:
#NAV-HOME .nav-home,
#NAV-ART .nav-art,
#NAV-CONTACT .nav-contact { color:red; }
To change the "current" menu item, you can just assign the corresponding ID to an element higher in the document's structure. Typically I add it to the <body> tag.
To highlight the "Art" page, all you have to do is this:
<!-- The "Art" item will stand out. -->
<body id="NAV-ART">
<ul class="nav">
<li>Home</li>
<li>Art</li>
<li>Contact</li>
</ul>
<!-- ... more page ... -->
</body>
You can do this with CSS classes. For example, a selected class could identify the current shop, changing the color and outline. Then you can change the selection by adding/removing the class from the menu item.
Take a look here, it walks through a tutorial on building CSS menus.
Basically, it can't be done with CSS alone, some scripting would have to take place (server or client side, preferably server). As the others have suggested, add a 'selected' class (or something similar) to the active link, and define the styles for it in CSS.
For example, the links:
Eshop | Another eshop | Another eshop
The styles:
.selected {
font-weight:bold;
color:#efefef;
}
The links would be generated dynamically, using PHP for example:
<?php
foreach(array('eshop' => '#','another eshop' => '#','yet another eshop' => '#') as $title => $url) {
echo '<a href="' . $url . '"'
. ($url == $_SERVER['REQUEST_URI'] ? ' class="selected"' : null)
. '>' . $title . '</a>';
}
If you are moving to a new page in the same browser window, Zack Mulgrew and Bobby Jack both have excellent answers.
If you are opening the eshop link in a new window, there is not much you can do with css alone, and gs has a reasonable answer except for the choice of class name of (red).
Which is it?
As far as I know you can do this only by generating different code for every page (setting a different class for the current page) or by using JavaScript to change the menu after the page is loaded.
you could use and attribute selector like this...
a[href^="http:\\www.EShop"]:visted { color: red; }
By doing that you are saying any link that has a href that starts with http:\Eshop.com and has been visted apply this style.
It depends on how your pages are constructed, but the classic CSS was of doing this is with an id on the body, as well as each navigational link, so you might have something like:
eshop.html
<body id="eshop">
<ul>
<li>Eshop</li>
<li>Another eshop</li>
<li>Another eshop</li>
</ul>
</body>
and corresponding CSS:
#eshop #link-eshop, #aeshop, #link-aeshop, #eshop-three #link-eshop-three
{
color: red;
outline: 1px solid red;
}
the navigation is consistent; only the id on the body changes from page to page.

Resources