How do I select an element that has a specific class and any other class? - jquery-selectors

I have this:
<div class="class1 class2">1</div>
<div class="class1 class3">2</div>
<div class="class1 class4">3</div>
<div class="class1">4</div>
I know if I want to select divs that contain multiple specific classes, I can do this:
$('.class1.class2');
and if I want to select only divs that contain only one specific class, I can do this:
$('[.class1]');
But how do I select divs that contain one specific class plus ANY other class? I need to select all divs that contain class1 plus any of the other classes, but not the div that only contains class1. And this is just a small sampling; there are several hundred classes in our site's stylesheets, so hard-coding anything is not feasible.

You could do something like this:
$('.class1').not("[class='class1']")

I do not see any only-selectors solution, but you can do something like that:
$(".class1").each(function(index, element){
var classes = $(element).attr('class').split(/\s+/);
if(classes.length > 1){
// element has other class than class1
}
});
If your code does not contain any unnecessary white characters it will work.

Related

TYPO3 write name of sys_category into class name at tx_news

I'using TYPO3 8.7 and write the name of a sys_categoryinto the class name of tx_news-template Item.html, like this:
<div class="{f:format.case(value: '{newsItem.firstCategory.title}', mode: 'lower')}"> ...
Now one of my categories has two words, like 'my category', so the classname results:
<div class="my category">
How can I remove the empty ' ' from class name in FLUID?
Thanks for your help.
Also i would think about using the category uid instead of category name. As names are brittle. An editor might rename somthing and your css code breaks. But your pretty save if you use uids
This is not possible by default - However I see the following options:
1) Create a custom ViewHelper: This would be the best solution as you don't need any 3rd party extension as dependency.
2) Misuse a different field of the category record like seo_title, description or similiar
3) You could use the replace VH of EXT:vhs, see https://fluidtypo3.org/viewhelpers/vhs/master/Format/ReplaceViewHelper.html
You could adjust your css to recognize double classes as well.
.category
.my.category
Still the way to go should be unique identifiers instead of names or titles.

Best way to declare content element uids to use them in fluid templates

I want to display some contentlement on every page with fluid templates. My solution was to create a typoscript element like:
lib.my.myelement= CONTENT
lib.my.myelement {
table = tt_content
select {
pidInList = 15
where = uid=99
}
}
and then use it in the fluid template with:
<f:cObject typoscriptObjectPath="lib.my.myelement" />
Another way is to create them directly in fluid with v:content.render or v:content.get. In this example I get all content elements on one page and save them in an array:
<v:variable.set name="contentElements" value="{v:content.get(column:'0', limit:'3', pageUid:'9', render:'FALSE')}" />
I can not use the first solution, cause on this page there will be much different languages ( I could use it, but every time a new language is added I would have work to declare all new uids of the new elements in typoscript).
The second solution would work better, cause when you translate a page the element uids change, but the pageUid does not change. But here I have the problem that I don't just need all elements, I also have to identify each element.
Here is how I use the second solution:
<v:variable.set name="contentElements" value="{v:content.get(column:'0', limit:'3', pageUid:'9', render:'FALSE')}" />
<f:for each="{contentElements}" as="contentElement" iteration="footerIteration">
<div class="column{v:math.sum(a: footerIteration.index, b: 1)}">
<v:content.render contentUids="{0:contentElement.uid}" />
</div>
</f:for>
As you can see, I use every element the same way.
lets create a simple case:
I have a page with the pageUid = 10 (this page will have translations). On every of this translations will be 3 elements. Lets say 1 element got the "id" (with id I mean something how I can identify this element) title1 and the other two elements have the id list1 and list2.
And my question now is How could I access for example list1?
I hope its understandable, if something is not clear please leave a comment.
Edit: I could use the same order on every translation for the elements and then check the iteration in the for-loop (see the second solution) to identify them. But I wonder if there a better, cleaner way.

AEM 6.0: Additional parameters when using data-sly-resource?

I am trying to implement something which I hope is relatively straight forward... I have one component (lets call it the wrapper component) which contains another component (lets call it the inner component) inside it via the data-sly-resource tag:
<div data-sly-resource="${ 'inner' # resourceType='/projectname/components/inner' }"></div>
I would like to pass in some additional parameters with this tag, specifically a parameter that can be picked up by sightly in the inner component template? I am trying to specify whether the inner templates outer html tag is unwrapped based on a parameter being passed in when the component is called via data-sly-resource.
After experimenting and perusing the sightly documentation, I can't find a way of achieving this.
Does anyone know if this is possible?
Many thanks,
Dave
You can use the Use-API to write and read request attributes if the alternatives proposed here don't work for you.
A quick example of two components where the outer component sets attributes that are then displayed by the inner component:
/apps/siteName/components/
outer/ [cq:Component]
outer.html
inner/ [cq:Component]
inner.html
utils/ [nt:folder]
setAttributes.js
getAttributes.js
/content/outer/ [sling:resourceType=siteName/components/outer]
inner [sling:resourceType=siteName/components/inner]
/apps/siteName/components/outer/outer.html:
<h1>Outer</h1>
<div data-sly-use="${'../utils/setAttributes.js' # foo = 1, bar = 2}"
data-sly-resource="inner"></div>
/apps/siteName/components/inner/inner.html:
<h1>Inner</h1>
<dl data-sly-use.attrs="${'../utils/getAttributes.js' # names = ['foo', 'bar']}"
data-sly-list="${attrs}">
<dt>${item}</dt> <dd>${attrs[item]}</dd>
</dl>
/apps/siteName/components/utils/setAttributes.js:
use(function () {
var i;
for (i in this) {
request.setAttribute(i, this[i]);
}
});
/apps/siteName/components/utils/getAttributes.js:
use(function () {
var o = {}, i, l, name;
for (i = 0, l = this.names.length; i < l; i += 1) {
name = this.names[i];
o[name] = request.getAttribute(name);
}
return o;
});
Resulting output when accessing /content/outer.html:
<h1>Outer</h1>
<div>
<h1>Inner</h1>
<dl>
<dt>bar</dt> <dd>2</dd>
<dt>foo</dt> <dd>1</dd>
</dl>
</div>
As commented by #AlasdairMcLeay, this proposed solution has an issue in case the inner component is included multiple times on the request: the subsequent instances of the component would still see the attributes set initially.
This could be solved by removing the attributes at the moment when they are accessed (in getAttributes.js). But this would then again be a problem in case the inner component is split into multiple Sightly (or JSP) files that all need access to these attributes, because the first file that accesses the request attributes would also remove them.
This could be further worked-around with a flag telling wether the attributes should be removed or not when accessing them... But it also shows why using request attributes is not a good pattern, as it basically consists in using global variables as a way to communicate among components. So consider this as a work-around if the other two solutions proposed here are not an option.
There is a newer feature that request-attributes can be set on data-sly-include and data-sly-resource :
<sly data-sly-include="${ 'something.html' # requestAttributes=amapofattributes}" />
Unfortunately it doesn't seem to be possible to construct a Map with HTL (=Sightly) expressions, and I don't see a way to read a request attribute from HTL, so you still need some Java/Js code for that.
unfortunately, no. there is no way to extend sightly functionality. you cannot add new data-sly attributes or modify existing ones. The best you can do is write your own helper using the USE API
If you just need to wrap or unwrap the html from your inner component in different situations, then you can just keep the html in the component unwrapped, and wrap it only when needed by using the syntax:
<div data-sly-resource="${ 'inner' # resourceType='/projectname/components/inner', decorationTagName='div', cssClassName='someClassName'}"></div>
If you need more complex logic, and you need to pass a value to your inner component template, you can use the selectors. The syntax for including the resource with selectors is:
<div data-sly-resource="${ 'inner' # resourceType='/projectname/components/inner', selectors='mySelectorName'}"></div>
The syntax to check the selectors in the inner component is:
${'mySelectorName' in request.requestPathInfo.selectorString}"
or
${'mySelectorName' == request.requestPathInfo.selectorString}"

Selecting last child with specific id

So here is the thing:
<div id="wrapper" > <div id="x"></div ><div id="x"></div ><div id="x"></div><div id="y"></div>
</div>
So how do i select last div with id=x not y inside of wrapper? Sorry , but i dont know how to pase code to be visible.
An ID is unique so to select it you should just be using
#x {}
I would question why you are using multiple id's though, maybe a class would be better?
Edit
Just noticed you pasted some code.
You really shouldn't be using ID's the way you are, you need to be using classes replace your id's with:
class="x"
If only for modern browsers you can use the last-of-type selector
.x:last-of-type
if going back to IE6 you can always add a class like last and then select it
class="x last"
.x.last {}
Edit For question
To use your wrapper selection you add it to the front of your selector:
#x .x.last {
/** css goodness here **/
}

Knockout.js: Multiple ViewModel bindings on a page or a part of a page

I am wondering if it is possible to use Knockout.js's ko.applyBindings() multiple times to bind different ViewModels to one part of a page. For example, let's say I had this:
<div id="foo">...</div>
...
ko.applyBindings(new PageViewModel());
ko.applyBindings(new PartialViewModel(), $('#foo')[0]);
I am now applying two ViewModel bindings to <div id="foo>. Is this legal?
You do not want to call ko.applyBindings multiple times on the same elements. Best case, the elements will be doing more work than necessary when updating, worse case you will have multiple event handlers firing for the same element.
There are several options for handling this type of thing that are detailed here: Example of knockoutjs pattern for multi-view applications
If you really need an "island" in the middle of your content that you want to call apply bindings on later, then you can use the technique described here: http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html
This is a common road block that comes when implementing JqueryMobile-SPA.
The method : ko.applyBindings(viewmode,root dom element) accepts two arguments. The second argument comes helpful when you have multiple VM's in your page.
for example :
ko.applyBindings(model1, document.getElementById("view1"));
ko.applyBindings(model2, document.getElementById("view2"));
where view1 and view2 are the root dom element for that model. For a JqueryMobile-SPA this will be the page ids for corresponding model.
The best way to do this would be use the "with" binding construct in the div that you want the partial view model to be bound. You can find it in this fiddle
<div data-bind="with: model">
<p data-bind="text: name"></p>
</div>
<div data-bind="with: anothermodel">
<p data-bind="text: name"></p>
</div>​
var model = {
name: ko.observable('somename'),
}
var anothermodel = {
name: ko.observable('someanothername'),
}
ko.applyBindings(model);​
Also check out the "with" binding documentation on the Knockout site, to look at an AJAX callback - partial binding scenario.
My english is very bad.... =)
I use Sammy to load partial views, and Knockout to bind the Model, I try use ko.cleanNode but clean all my bindings, all DOM nodes has changed when has a bind, a property __ko__ is aggregated, then i removed that property with this code, and works !!, '#main' is my node.
var dom = dom || $("#main")[0];
for (var i in dom) {
if (i.substr(0, 6) == "__ko__") {
delete (dom[i]);
break;
}
}
after use Ggle translator:
I use Sammy for the load of partial views, and Knockout for the bind the Model, I try to use ko.cleanNode but clean all my bindings, all DOM nodes has changed when they has a bind, a property ko is aggregated, then i removed that property with this code, and works !!, '#main' is my node.