Vue duplicate numbers in array breaks doom element - javascript

Very weird situation, when I push any number which already exists in my array it duplicates and breaks my doom element. Array keeps normal, but doom displays something like this:
array:
my watcher :
lastWins(){
console.log(this.lastWins);
this.lastWins.shift();
}
Doom:
<ul class="gameHistoryList_rou">
<li :style="{background: historyCheckColor(win)}" v-for="win of lastWins" :key="win">{{ win }}</li>
</ul>
method to push(splice for watch):
this.lastWins.push(Math.round(Math.random() * 36));
this.lastWins = this.lastWins.splice(0);

You need to set an unique key for each item.
Try this:
<ul class="gameHistoryList_rou">
<li :style="{background: historyCheckColor(win)}" v-for="(win, index) of lastWins" :key="index">{{ win }}</li>
</ul>

Related

CSS exclude cascade classes

Web Mind Help! I have html with many lists looks like
<li>A.</li>
<li>B.</li>
<li><a class=tr href="#">C.</a></li>
<li class=tr>D.</li>
<li class=notr>E.</li>
I want select all untranslated innerText
document.querySelectorAll("li:not(.notr):not(.tr)")
Problem is if class TR not in LI i cannot filter it
li:not(.notr):not(.tr)+li>a:not(.tr) - returns empty NodeList
It seems to be a simple question but I'm confused
Like I said in the comments, the solution is to fetch this collection first, then refine the results by running another filter over that.
let rawresult = document.querySelectorAll("li:not(.notr):not(.tr)");
console.log('raw results:');
rawresult.forEach(el => console.log(el.innerText));
let refinedresult = [];
rawresult.forEach(function(el) {if (el.querySelector(".notr,.tr") == null) refinedresult.push(el);});
console.log('refined results:');
refinedresult.forEach(el => console.log(el.innerText));
<ul>
<li>A.</li>
<li>B.</li>
<li><a class=tr href="#">C.</a></li>
<li class=tr>D.</li>
<li class=notr>E.</li>
</ul>

How to change the id of a unordered list of object type in jQuery object

I'm new here and I'd like to ask a question about jQuery.
I have the unordered list like:
<ul id="pages">
<li id="number1">
contains sub table a
</li>
<li id="number2">
contains sub table b
</li>
<li id="number3">
contains sub table c
</li>
<li id="number4">
contains sub table d
</li>
</ul>
And I'd like to add a different ID (new id will be same out of these id but it will be shuffle as per my requirements) to every li displayed in this <ul> (eg
<li id="number3">contains sub table d</li>
...)
Is there a way how to achieve this via jQuery?
I tried it using a for loop and this object but when i try to shuffle. Its duplicating the sub tables becouse of jQuery has child/nextsybling data inside this every object.
Basically you should get all ids, shuffle them and reassign back to DOM elements:
const $items = $('#pages li');
const ids = $items.map((i, { id }) => id);
const shuffledIds = shuffle(ids); // This is your shuffle function
$items.each((i, e) => {
e.id = shuffledIds[i];
});

List items from HTML XPath

I need to list items returned from evaluating an Xpath. I'd like to return the tweets in a list, so I can further evaluate their elements. How do I do this?
My code is:
var navigable_stream = '//*[#id="stream-items-id"]';
var FIRST_RECORD = document.evaluate(navigable_stream, document, null, XPathResult.ANY_TYPE, null).iterateNext();
console.log(FIRST_RECORD);
And the returned HTML is very long. But it has lots of tweets with different ids. Here's a picture to show what I mean:
Update
" Is there a way to match the first part of the element id i.e. 'stream-item-tweet"?"
Yes, by using referencing the partial #id as an attribute:
var tweet = document.querySelectorAll("[id^=stream-item-tweet]");
Note the ^= means that the beginning of the #id must match stream-item-tweet
Having answered the question I'd like to add that there may be a better alternative by using the class of each <li>:
var tweet = document.querySelectorAll('.js-stream-item')
Something looks invalid on the classList:
class="js-stream-item stream-item stream-item"
.stream-item is repeated twice...maybe it's best to avoid class in your circumstance.
Anyways, knowing the first way should work and maybe the second way might, tweet is now a NodeList which needs to be handled by a loop or it needs to be converted to an array so it can be processed by an array method.
Demo 2 shows how the latter is done.
Just guessing, since there's no way I can test it myself, that if that's what you can get on the console, then you could maybe use .toString() then parse and append it to the DOM.
Demo 1
Not possible to make an actual functioning Demo
var navigable_stream = '//*[#id="stream-items-id"]';
var FIRST_RECORD = document.evaluate(navigable_stream, document, null, XPathResult.ANY_TYPE, null).iterateNext();
console.log(FIRST_RECORD);
var str = FIRST_RECORD.toString();
document.getElementById('dock01').insertAdjacentHTML('beforeend', str);
<section id='dock01'></section>
Demo 2
/* Collect all elements with an #id that starts with "tweet"
|| Convert NodeList into an array
*/
var tweets = Array.from(document.querySelectorAll("[id^=tweet]"));
/* filter() the array tweets
|| if an item has data-id = "retweet"
|| add it to the new array retweets
*/
var retweets = tweets.filter(function(t) {
return t.dataset.id === "retweet";
});
console.log(retweets);
/* The lazy way to add text */
li::after {
content: attr(id);
}
/* This is just so the console results don't obscure the Demo*/
.as-console-wrapper {
width: 70%;
margin-left: 30%;
}
.as-console-row:after {
display: none !important;
}
<ol>
<li id='tweet-51515151' data-id='retweet'></li>
<li id='tweet-57885157' data-id='tweet'></li>
<li id='tweet-51677459' data-id='tweet'></li>
<li id='tweet-51890331' data-id='retweet'></li>
<li id='tweet-51515337' data-id='retweet'></li>
<li id='tweet-51593051' data-id='retweet'></li>
<li id='tweet-51333333' data-id='tweet'></li>
<li id='tweet-51534152' data-id='tweet'></li>
<li id='tweet-51599951' data-id='tweet'></li>
<li id='tweet-54785151' data-id='retweet'></li>
<li id='tweet-56785199' data-id='retweet'></li>
<li id='tweet-51557844' data-id='tweet'></li>
<li id='tweet-51510000' data-id='retweet'></li>
</ol>

Filter the list with letter in angular js

I have a list displayed in table where I need to filter the result with first letter of name,above the list I have a letter A B C D and so on.
After click the letter list will be filter by its first name
For ex: list details are Apple Boy Bridge
after click A, Apple will be displayed
Instead of fruit, I had to filter names of countries to display their sales representatives:
'use strict';
angular.module('sodemo')
.filter('firstLetter', function () {
return function (input, letter) {
input = input || [];
var out = [];
input.forEach(function (item) {
//console.log("current item is", item, item.charAt(0));
if (item.charAt(0).toLowerCase() == letter) {
out.push(item);
}
});
return out;
}
});
A quick way to generate an array with letters of the alphabet:
$scope.alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
and the view, which also sets a different background colour if the letter is active:
<button type="button" class="btn-alphabet btn btn-default" ng-repeat="letter in alphabet" ng-click="setActiveLetter(letter)" ng-class="{'btn-primary': letter==activeLetter}">{{letter}}</button>
I filtered elements of the array of countries like this:
<ul class="list-group countries-salesreps" >
<li class="list-group-item" ng-repeat="country in filteredCountriesArray = (countriesArray | firstLetter:activeLetter)" ng-click="showSalesRep(country)" ng-class="{'btn-primary': country==currentCountry}">{{country}}</li>
</ul>
You can check if there are elements in the filtered list using .length:
<div class="alert alert-warning" ng-hide="filteredCountriesArray.length">No available countries starting with <em>{{activeLetter}}</em></div>
So the question has been answered but I came across this looking for an answer and being quite new to angular found it kind of hard to read and understand properly. I then found this tutorial explaining filters and how they work in general and in his examples he creates a 'startsWithLetter' filter which I found quite useful: http://toddmotto.com/everything-about-custom-filters-in-angular-js/
Just thought I would post it in case anyone had trouble understanding like I did.
this is old but maybe this plunker can help, using angular's filter filter.
Define an expression like so:
// Filter Expression
this.filterActive = function(value){
if (self.active) {
return value.charAt(0).toLowerCase() === self.active;
}
return true;
}
Then in html:
<ul>
<li ng-repeat="country in ctrl.countries | filter:ctrl.filterActive" ng-bind="country"></li>
</ul>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
<ul>
<li ng-repeat="name in list | filter:letterFilter">
{{name.firstName}}
</li>
</ul>
try above code this is simple to implement:

Angular factory filter - Can't get data passed to the filter

I'm looking through the Angular docs and I can't better documented stuff.
My problem is as follows:
I have a filter:
.filter('filteringService', function () {
return function (photos, categsList) {
if (photos !== undefined) {
var filteredPosts = [];
console.log('Categories or Selected Categories:');
console.log(categsList);
//DEVEL Only, assign a SEARCH value, can't pass the data from the list now.
categsList = 'people';
if (categsList === undefined) {
for(i=0; i < photos.length; i++) {
filteredPosts.push(photos[i]);
}
} else {
console.log('Trying to push a category slug to search for.');
//TASK: Convert in multiple possible selections.
filteredPosts = [];
}
console.log('Filter returns ' + filteredPosts.length + ' posts');
return filteredPosts;
}
};
});
And I have the template
<div class="photos">
<div class="filters">
<ul>
<li><a>ALL</a></li>
<li ng-repeat="category in categsList">
<a ng-checked="category[0]" ng-model="category[0]">{{ category[1] }}</a>
</li>
</ul>
</div>
<ul class="photos-list">
<li ng-repeat="photo in photos|filteringService:category">
<h1>{{ photo.title }} click LINK</h1>
<ul class="categories">
<li ng-repeat="category in photo.categories">
{{ category.title }}
</li>
</ul>
</li>
</ul>
</div>
There's a huge object with posts called photos and then there's a category list called categsList.
The photos object has the items from the categs list in it. I WANT to be able to filter with the CLICKED element through that list, and maybe multiple filter, but first to pass on the actual filter value to the filter service, I can't seem to do that.
How should I do that?
Apparently I managed to pass the filter value, in a dirty way (I GUESS), like this
<a ng-bind="category.slug" ng-click="returnFilter(category.slug);" ng-model="category.slug">{{ category.title }}</a>
it goes here
$scope.returnFilter = function(theSlug) {
$scope.filterBy = theSlug;
};
and it comes out here
<li ng-repeat="photo in photos|filteringService:filterBy">
It's working, but Is this correct?
EDIT: Also with this way in mind, I could pass an array as theSlug so I can do multiple filtering, and when clicking two times on the same item it would get it out of the array. hmmm
EDIT 2:
Let's say the resulting array is under 15 items, could do I run some action in the controller knowing this?
Actually the other way around, could I query from the controller the resulting array that the filter outputs?
I can't $watch the first array, I guess the filter creates a new array and puts those results in page. How could I watch the resulting array for changes and do stuff in the controller?

Categories