Mootools - getFirst().get('text') not a function? - mootools

the HTML:
<ul id="nav">
<li id="listItem">a list item</li>
<li id="link01">list item with ID</li>
<li id="link02">another link with ID</li>
<li class="lastItem">Contact</li>
<li class="lastItem">the Very Last List Item</li>
</ul>
the JavaScript:
alert($$('.lastItem').getFirst('li').get('text'));
console returns this error:
TypeError: $$(...).getFirst(...).get is not a function
um...whut? what did i miss? if i take out the getFirst(), it works, but returns, of course, both <li> text contents... which i don't want. just want the first...
halp.
WR!

You trying to call getFirst on Elements array($$ return elements array!) the getFirst() method is only on a dom mootools element and it will return his first child
what you are looking for is this:
alert($$('.lastItem')[0].get('text'));

Related

How to render ul li value dynamically from a sample json in angular 6

I have a sample json,I need to create a sidebar using ul li tag and value comes from json.My json structure is something like this.
{"filter":{"Category1":{"value":["one","two","three"]},"Category2":{"value":["four","five","six"]}}}.I have already done in angularjs here http://plnkr.co/edit/D8M1U81tVz3UuzjWathk?p=preview , but This does not work in angular 6.Can anyone please help me,I am new in angular,Here is the code below
app.html
<ul *ngFor="(x, y) of items.filter">
<li class="parent"><b>{{x}}</b></li>
<li class="child">
<ul>
<li *ngFor="p of y.value">{{p}}</li>
</ul>
</li>
</ul>
app.ts
export class Heroes {
let items = {"filter":{"Category1":{"value":["one","two","three"]},"Category2":{"value":["four","five","six"]}}};
}
I suggest you to work with an iterable objects when you try to use *ngFor in your html component.
So, that's my solution:
<ul *ngFor="let parent of (items.filter | keyvalue)">
<li class="parent">{{ parent.key }}</li>
<ul *ngFor="let child of (parent.value.value | keyvalue)">
<li class="child">{{ child.value }}</li>
</ul>
</ul>
First of all I used the keyvalue pipe from angular (https://angular.io/api/common/KeyValuePipe) after that you are allowed to iterate your json object as you want without change it.
Also, here I leave an example of how it works (https://stackblitz.com/edit/angular-gqaaet)
You need to change the json format.
items = {"filter":
[{
"name":"Category1",
"value":["one","two","three"]
},
{
"name":"Category2",
"value":["four","five","six"]
}
]};
HTML
<ul *ngFor="let item of items.filter">
<li class="parent"><b>{{item.name}}</b></li>
<li class="child">
<ul>
<li *ngFor="let p of item.value">{{p}}</li>
</ul>
</li>
</ul>
The above code would work. *ngFor works with the iteration protocols, the json format you've added has map(filter) of map(category) of map(value) format, where the values are not obtained to be iterated.

Why is my attribute selector working when it doesn't have any whitespace in it?

MDN states the following about the [attr~=value] attribute selector:
Represents elements with an attribute name of attr whose value is a
whitespace-separated list of words, one of which is exactly value.
If liquid is not separated by whitespace, then why is it working?
[data-vegetable~="liquid"] {
color: red;
}
Ingredients for my recipe: <i lang="fr-FR">Poulet basquaise</i>
<ul>
<li data-quantity="1kg" data-vegetable>Tomatoes</li>
<li data-quantity="3" data-vegetable>Onions</li>
<li data-quantity="3" data-vegetable>Garlic</li>
<li data-quantity="700g" data-vegetable="not spicy like chili">Red pepper</li>
<li data-quantity="2kg" data-meat>Chicken</li>
<li data-quantity="optional 150g" data-meat>Bacon bits</li>
<li data-quantity="optional 10ml" data-vegetable="liquid">Olive oil</li>
<li data-quantity="25cl" data-vegetable="liquid">White wine</li>
</ul>
It's not separated by whitespace but:
a whitespace-separated list of words
Which mean a list of words where you have whitespace between and if alone no need whitespace because there is nothing to separate.
[data-vegetable~="liquid"] {
color: red;
}
<ul>
<li data-vegetable="liquid other and other">this one</li>
<li data-vegetable="liquid">and this one</li>
<li data-vegetable="liquid ">also this one</li>
<li data-vegetable="another liquid ">also this one</li>
<li data-vegetable="liquid-one">NOT this one !!</li>
<li data-vegetable="another-liquid">NOT this one !!</li>
<li data-vegetable="aliquid">NOT this one !!</li>
</ul>
For the last ones you will need *
[data-vegetable*="liquid"] {
color: red;
}
<ul>
<li data-vegetable="liquid other and other">this one</li>
<li data-vegetable="liquid">and this one</li>
<li data-vegetable="liquid ">also this one</li>
<li data-vegetable="another liquid ">also this one</li>
<li data-vegetable="liquid-one">this one too!!</li>
<li data-vegetable="another-liquid">this one too!!</li>
<li data-vegetable="aliquid">this one too!!</li>
</ul>
A list of words has separators between the words.
If the list contains only one word, there are no separators
What that means is, the attribute (data-vegetable in this case) can have multiple values, assigned to it in one string using whitespace to delimit the values, like data-vegetable="liquid foo bar", which gives data-vegetable three values 'liquid', 'foo' and 'bar'.
The selector can be used to match any of these values, so you will get this element when matching either [data-vegetable~="liquid"], [data-vegetable~="foo"] or [data-vegetable~="bar"].
It said: "whitespace-separated list of words"
That means that it is a list, separated by whitespace. But a list can have only one item. So in that case, no spaces are needed.

Ng-click not working dragula drag-drop elements

Using dragula plugin (Angular 1) link
ng-click not working moved (drag and drop to another ul) on li element
<ul dragula='"second-bag"'>
<li ng-click="fun()">Item One </li>
<li ng-click="fun()">Item Two</li>
<li ng-click="fun()">Item Three</li>
<li ng-click="fun()">Item Four</li>
</ul>
<ul dragula='"second-bag"'>
<li ng-click="fun()">Item One </li>
<li ng-click="fun()">Item Two</li>
<li ng-click="fun()">Item Three</li>
<li ng-click="fun()">Item Four</li>
</ul>
app.controller('ExampleCtrl', ['$scope', function ($scope) {
$scope.fun = function(){
alert('test');
}
}]);
It is probably the expected behaviour of dragula, becouse in order to drag the element you are actually clicking it.
The important part is why do you want to listen the clicking event of an dragula list element? If the answer is to manipulate that particular element or do another operation, dragula gives you a set of opportunities.
<div dragula='"sixth-bag"'></div>
<div dragula='"sixth-bag"'></div>
app.controller('MuchExampleCtrl', ['$scope', 'dragulaService',
function ($scope, dragulaService) {
dragulaService.options($scope, 'sixth-bag', {
moves: function (el, container, handle) {
return handle.className === 'handle';
}
});
}
]);
In this example, you are changing the className of the "handled" element. Similar to this, you can use this approach for other possible outcomes.
Links:
http://bevacqua.github.io/angular-dragula/
https://github.com/bevacqua/dragula#optionsmoves
Also as an alternative you might want to checkout the service ngDraggable for more "Angular1 style" syntax.
ngDraggable: https://github.com/fatlinesofcode/ngDraggable

how to use one class with many elements?

for some reasons i have somthing like this in my html code
id = 1
<li class="anyclass" ></li>
<li class="firstclasname + id" ></li>
<li class="scondclasname + id" ></li>
<li class="thirdclasname + id ></li>
<li class="forthclasname + id" ></li>
<li class="fifthclasname + id" ></li>
</ul>
id = 2
<li class="anyclass" ></li>
<li class="firstclasname + id" ></li>
<li class="scondclasname + id" ></li>
<li class="thirdclasname + id ></li>
<li class="forthclasname + id" ></li>
<li class="fifthclasname + id" ></li>
</ul>
can i make just one css file for this code contain something like this :
.every first calss name + what ever id {
background-image: url('/image/facebook.png');
background-repeat: no-repeat;
background-size: auto;
background-position: -277px -446px;
}
You just need to try nth-child of CSS3 property.
ul.yourClass li.firstclasname:nth-child(2){
background:url('/image/facebook.png') -277px -446px no-repeat;
background-size:auto;
}
You can use starts with [attr^=value] attribute selector.
li[class^="firstclasname"] {
background: blue;
}
<ul>
<li class="anyclass"></li>
<li class="firstclasname1"></li>
<li class="scondclasname1"></li>
<li class="thirdclasname1"></li>
<li class="forthclasname1"></li>
<li class="fifthclasname1"></li>
</ul>
<ul>
<li class="anyclass"></li>
<li class="firstclasname2"></li>
<li class="scondclasname2"></li>
<li class="thirdclasname2"></li>
<li class="forthclasname2"></li>
<li class="fifthclasname2"></li>
</ul>
For cases like this I like to use two selectors -- a common one, relevant to all the items, and a specific one to identify a single item.
An example use would be something like this:
<ul class="contact-list">
<li class="item item-1">Contact 1</li>
<li class="item item-2">Contact 2</li>
<li class="item item-3">Contact 3</li>
</ul>
In CSS you can then target the list itself, all the items or one specific item.
Edit
Apologies, I skimmed your question and missed the part about id=1 and id=2. There are a few different options depending on how many IDs there will be and whether or not this will be known.
For a short list of known ID's you could just target the individual items as I mentioned. If there are an unknown number of IDs (or the IDs themselves are unknown) you may consider using the nth-child selector.
This depends entirely on the effect you're trying to achieve, which isn't detailed in your question, but some commonly used (in the context of my example markup above) are as follows:
.contact-list:nth-child(odd) applies to every odd element, i.e. 1st, 3rd, 5th
.contact-list:nth-child(even) applies to every even element, i.e. 2nd, 4th, 6th
.contact-list:nth-child(1) applies only to the first element
.contact-list:nth-child(4n+4) applies to every fourth element
And so on. Most common requirements have been done a thousand times before and can be found with a quick google search along the lines of "CSS every second element".

Thymeleaf recursion not working

I'm trying to create a recursive list using Thymeleaf. I'm using a simple Java object to model a node which has has two fields, a description and then an array list of child nodes. I'm using the following HTML/Thymeleaf to process the structure but it isn't recursively iterating through to the next level down.
My Java code looks as follows:
public class Node {
public String description;
public ArrayList<Node> children;
}
My Thymeleaf/HTML code is as follows:
<html>
...
<body>
<div th:fragment="fragment_node" th:remove="tag">
<ul th:if="${not #lists.isEmpty(node.children)}" >
<li th:each="child : ${node.children}"
th:text="${child.description}"
th:with="node = ${child}"
th:include="this::fragment_node">List Item</li>
</ul>
</div>
</body>
</html>
If my data structure looks as follows:
Main node 1
Child node 1
Child node 2
Main node 2
Child node 3
Child node 4
I'd expect to get:
<ul>
<li>Main Node 1</li>
<li>
<ul>
<li>Child node 1</li>
<li>Child node 2</li>
</ul>
</li>
<li>Main Node 2</li>
<li>
<ul>
<li>Child node 3</li>
<li>Child node 4</li>
</ul>
</li>
</ul>
However, I only get:
<ul>
<li>Main Node 1</li>
<li>Main Node 2</li>
</ul>
Can anyone spot why this may not be working?
The cause of the problem is
You are trying to th:text and trying to add the description to a <li> as well as you are trying to th:include the fragment inside the same tag <li>.
Your th:include is replaced by the th:text as th:text is processed with priority by default.
Direct solution to your source code
.....
<li th:each="child : ${node.children}" th:inline="text" th:with="node = ${child}">
[[${child.description}]]
<ul th:replace="this::fragment_node">List Item</ul>
</li>
.....
Even thought the above will work as you want, personally I find some design issues in your thymeleaf page.
Better solution using fragment parameters
...
<ul th:fragment="fragment_node(node)" th:unless="${#lists.isEmpty(node.children)}" >
<li th:each="child : ${node.children}" th:inline="text">
[[${child.description}]]
<ul th:replace="this::fragment_node(${child})"></ul>
</li>
</ul>
...