Using String.split inline to set CSS classes in the view - css

In my model I have a field type string called god_type.
Example:
Ice,Fire
Ranged,Cannon
Fire,Ranged
I'm going to be using Isotope to filter these models based on their god_type.
I need the output HTML to look like:
<div class="item Fire Ranged">
</div>
Here's what I've tried:
#gods-list.isotope-container
- for god in #gods
.item class='#{god.god_type.split(",").each { |c| c }}'
a href='#{god_path(god)}' class='god'
img src='#{god.thumbnail.url(:thumb)}'
h2= god.name
And the resulting HTML:
<div class="item ["Fire", "Ranged"]">
...
</div>
What am I doing wrong?

I'd suggest:
.item class='#{god.god_type.gsub(/\,/, " ")}'
You could also wrap it in a method, within a decorator, or directly in the model, or even an application helper. Here's a general idea:
class God
def god_type_classes
god_type.gsub(/\,/, " ").downcase
end
end
# your view
.item class='#{god.god_type_classes}'
Noticed I've used .downcase on the string. This is just to address standard CSS naming (should be item fire ranged).

Related

Angular 2 bind all style

how can I bind a style when I don't know what is it ? I've a model with a string variable that define a style, for example:
myStyle1:string="margin-left:10px";
myStyle2:string="margin-right:5px";
how can bind these two variable to a div ?
follow doesn't work:
<div [style]="myStyle1"></div> <div [style]="myStyle2"></div>
As per my knowledge you can do like this
HTML:
<div [ngStyle]="myStyle1"></div> <div [ngStyle]="myStyle2"></div>
Code:
myStyle1={'margin-left':'10px'};
myStyle2={'margin-right':'5px'};
That work, you need transform string to object and string must be json format.
<div [ngStyle]="myStyle1"></div> <div [ngStyle]="getStyle()"></div>
Style:string="{"margin-right":"10px"}";
getStyle(){
return (JSON.parse(this.Style));
}

Add text item in two line

I have to make text wrap convert into into two line and ellipse will add if the text is more than two line.
Currently it's wrap in multiple line and view look so weird.
What i have done so far in css:
<div class="list card item-text-wrap" ng-click="getNewsDetail(new)">
<a class="item item-thumbnail-left" href="#">
<img src="http:{{new.thumbnail}}">
<h2>{{new.summary}}</h2>
<p style="padding: 0;">{{new.date | date:'EEE, MMM d yyyy'}} {{new.date |
date:'shortTime'}}</p>
</a>
</div>
This is work perfectly when text length is short but i want to make it consistent in two line and rest of part is append with dot(...).
Any help would highly appreciate.
So you cannot accomplish this using only CSS because you must use white-space: nowrap; to be able to use text-overflow: elipsis; and nowrap will not let the words wrap down multiple lines.
Here is a similar question with a Jquery solutions: CSS word ellipsis ('...') after one or two lines
Here is a page dedicated to different version of text-overflow and the different ways to handle it: http://dotdotdot.frebsite.nl/
You are going to need JQuery to do this, but luckily you gain a lot of control and may find a better visual design rather than the ellipsis.
Of course, apply any styles to the parent elements holding the text.
e.g.
<!-- HTML -->
<!-- Give class of "date" -->
<p style="padding: 0;" class="date>{{new.date | date:'EEE, MMM d yyyy'}} {{new.date | date:'shortTime'}}</p>
// Jquery
if ($('.date').height() > 50) {
var words = $('.date').html().split(/\s+/);
words.push('...');
do {
words.splice(-2, 1);
$('.date').html( words.join(' ') );
} while($('.date').height() > 50);
}

Change CSS class's property on click

I've read around a little bit and have a good start to what I ultimately want. This was helpful, along with another article which I forgot the link to. However, everything I've read ADDS a CSS class or property to an element. I want to CHANGE a property of an existing CSS class, but I don't know how to target it.
I think I want to use ng-class in one of these use cases taken from the Angular documentation:
If the expression evaluates to a string, the string should be one or more space-delimited class names.
If the expression evaluates to an object, then for each key-value pair of the object with a truthy value the corresponding key is used as a class name.
My existing code uses ng-class along with some controller logic.
HTML
<div ng-controller="ngToggle">
<div ng-class="{'inset-gray-border' : style}">
<div class="subcontainer" ng-click="toggleStyle()">{{item.name}}</div>
</div>
</div>
This currently adds the inset-gray-border class to the nested div, but I just want to change the border property in the subcontainer class.
Controller
angular.module('app').controller('ngToggle', ['$scope', function($scope) {
$scope.style = false;
$scope.toggleStyle = function() {
$scope.style = $scope.style === false ? true: false;
};
}]);
I considered using a directive, but I believe that would be overkill. I think this can be achieved in a controller.
EDIT: After further research I think jQLite can do the trick, but that would probably require a directive.
CHANGE a property of an existing CSS class
Add a css rule that does that using the new class you added using ng-class. The specificity will over ride the original rule
.subcontainer{
color : blue
}
.inset-gray-border .subcontainer{
color:red
}
Instead of a big toggleStyle function, you can write that stuff in UI side only.
Here is fiddle. As you want to change border property of .subcontainer, Overwrite that property by adding .insert-gray-border
<div ng-controller="ngToggle">
<div >
<div ng-class="{'subcontainer':true,'inset-gray-border' : style}" ng-click="style=!style">{{item.name}}</div>
</div>
</div>
The benifit of this is , it uses local scope instead of controller scope.
The best bet would be to have two CSS classes defined, one for the base (untoggled) case, another with all the properties that you want for when the property is toggled on.
In this case you may want something like:
.container .subcontainer {}
.container .subcontainer-bordered { border: solid 1px #123456}
Then your HTML code be updated to reflect this structure
<div ng-controller="ngToggle">
<div class="container">
<div class="subcontainer" ng-class="{'subcontainer-bordered': style}" ng-click="style = !style">{{item.name}}</div>
</div>
</div>

select all ids where the only difference is the number in the ID name

I have all these divs with an identical ID name except for the fact that they all have a different number at the end.
I know I can use a class but it must be an ID.
<div id="myid1">text</div>
<div id="myid2">text</div>
<div id="myid3">text</div>
<div id="myid4">text</div>
<div id="test1">text</div>
<div id="test2">text</div>
My question is using css how can I select them all but shorter than this .
#myid1,#myid2,#myid3,#myid4{
color:red;
}
Does this type of thing exist and if so how do you write it?
myid1[*]{
color:red;
}
Just use the prefix attribute selector
[id^="myid"] {
}
This selector targets any element with an ID attribute that has the prefix "myid" - quotes around the value are optional. This selector works in IE7 & above as well.
you can use begins with this attr selector.
[id^=myid] {
color:red;
}
DEMO
CSS3 should help here:
div[id^="myid"]
AND
div[id^="test"]
Yes, there's a way
<div id="myid1" class="foo">text</div>
<div id="myid2" class="foo">text</div>
<div id="myid3" class="foo">text</div>
<div id="myid4" class="foo">text</div>
<div id="test1">text</div>
<div id="test2">text</div>
and css
.foo { color:red; }
UPDATE
If those have to be IDs, try with [id^=myid]
I think it would work a lot better for you to use classes as incremental ids goes against HTML and general programming principles. You could rewrite it like so:
<div class="myid" data-id="1">text</div>
<div class="myid" data-id="2">text</div>
However, if you must keep the ids as they are, you can use the attribute selector:
[id^=myid] {
color: red;
}
In your case this would do it:
[id=^"myid"] {
//your rules
}
That selects all elements whose id attribute begins with "myid".
You're not limited to the id attribute though. In fact, you could use any other html element's attribute.
Let's say you wanted to select all <a> tags whose "href" attribute begun with "http://stackoverflow.com". The following would do it:
a[href=^"http://stackoverflow.com"] {}
There's really a ton of options. Instead of pointing them out myself I'll you link to the w3 page where all of it is detailed: http://www.w3.org/TR/selectors/#attribute-selectors
use classes in addition to the ids (if you really need the ids):
<div class="mytext" id="myid1">text</div>
<div class="mytext" id="myid2">text</div>
<div class="mytext" id="myid3">text</div>
<div class="mytext" id="myid4">text</div>
<div id="test1">text</div>
<div id="test2">text</div>
then the CSS is simple:
div.mytext {
color: red;
}

How to write regular expressions in CSS

How do I use regular expressions in CSS? I found a tutorial here for matching static strings in CSS, but I haven't been able to find one for using regular expressions to match multiple strings in CSS. (I found one here, but I couldn't get it to work. I also looked at the W3C documentation on using regular expressions, but I couldn't make sense of the document.)
I'm want to match a series of <DIV> tags whose ids start at s1 and increase by one (ie. #s1 #s2 #s3...).
I know that div[id^=s], div[id^='s'], and div[id^='s'] each perform the match as I intend it in my CSS. However, each of those also match an id of #section, which I don't want to happen. I believe that "/^s([0-9])+$/" is the equivalent PHP string--I'm just looking for it in CSS version.
There is no way to match elements with a regular expression, even in CSS3. Your best option is probably to simply use a class for your divs.
<style>
.s-div {
// stuff specific to each div
}
</style>
<div id="s1" class="s-div"><!-- stuff --></div>
<div id="s2" class="s-div"><!-- stuff --></div>
<div id="s3" class="s-div"><!-- stuff --></div>
<div id="s4" class="s-div"><!-- stuff --></div>
<div id="s5" class="s-div"><!-- stuff --></div>
Also remember that you can separate multiple class names by a space inside a class attribute.
<div class="class1 class2 class3"></div>
javascript:
/* page scrape the DIV s# id's and generate the style selector */
re=/<div\b[^>]*\b(id=(('|")?)s[0-9]+\2)(\b[^>]*)?>/ig;
alert(
document . body . innerHTML .
match(re) . join("") .
replace(re,"div[$1], ") + "{ styling details here }" );
alert(
("test with <div id=s2 aadf><DIV ID=123> <DIV adf=asf as><Div id='s45'>" +
"<div id=s2a ><DIV ID=s23 > <DIV asdf=as id=S9 ><Div id='x45' >") .
match(re) . join("") .
replace(re,"div[$1], ") + "{ styling details here }"
);
The test yields
div[id=s2], div[id='s45'], div[ID=s23], div[id=S9], { styling details here }
Note the dangling , and the case preserved S9.
If you don't want or can't use the solution posted by #zneak, you could do that editing the labels with javascript, but i'll advice you: It's a hell of work.
The following CSS will select #s0, #s1, ... , #s9 and not #section, though a browser must implement the CCS3 negation :not().
The final selection is equivalent to:
/^s[0-9]?.*[0-9]$/
which says that each id must start with s and a number and end with a number like:
s6, s42, s123, s5xgh7, ...
The :not() line vacuously excludes those ID's that do not start properly using an empty style {}.
<style>
div:not([id^=s0]):not([id^=s1]):not([id^=s2]):not ... :not([id^=s9]) {}
div[id^=s][id$=0], div[id^=s][id$=1], div[id^=s][id$=2], ... div[id^=s][id$=9] { ... }
</style>
CSS3 does not use regular expressions to define selectors BUT ...
CSS Conditional Rules Module Level 3
defines a very specific function, regexp(<string>), that parses a URL with a regular expression when creating an #document rule.
<style>
/* eliminate the alphabet except s - NB some funny characters may be left */
/* HTML id's are case-sensitive - upper case may need exclusion & inclusion */
div[id*=a], div[id*=b], div[id*=c], ..., div[id*=q], div[id*=r] {}
div[id*=t], div[id*=u], div[id*=v], div[id*=w], div[id*=x], div[id*=y], div[id*=z] {}
div[id*='_'], div[id*='-'], div[id*='%'], div[id*='#'] {}
/* s can not be embedded */
div[id*=0s], div[id*=1s], div[id*=2s], ..., div[id*=9s] {}
/* s will be followed by a string of numerals - maybe a funny char or two */
div[id^=s0], div[id^=s1], div[id^=s2], ... div[id^=s9] { ... }
</style>

Resources