Bad title, I know, but it's hard to explain in few words.
I'm automating on nightwatch and ran into something that has me stumped as I'm used to coding on JS only for automation. Normally, it's easy to verify that an element is present, or that an element is not. But for this, I have an html element that shows that results of a search and I need to verify that the results contain only elements
So, I need to make sure that all result-item on the entity-results div only have results with hint-val-fragment match equal to -1000000.0 and hint-prop equal to cpuLimit:, in this example.
<div class="results" style="">
<!---->
<div>
<div class="results-set-title">Results</div>
<!---->
<div class="entity-results">
<div class="result-item">
<div class="result-item-label">
<div class="result-item-name">Resources</div>
<div class="result-item-source"><span>source:</span> <span>cz0</span></div>
</div>
<div class="result-item-hint">
<div class="hint-prop">cpuLimit:</div>
<div class="hint-val">
<div class="hint-val-fragment">
</div>
<div class="hint-val-fragment match">
-1000000.0
</div>
<div class="hint-val-fragment">
</div>
</div>
</div>
</div>
<div class="result-item">
<div class="result-item-label">
<div class="result-item-name">Resources</div>
<div class="result-item-source"><span>source:</span> <span>cz0</span></div>
</div>
<div class="result-item-hint">
<div class="hint-prop">cpuLimit:</div>
<div class="hint-val">
<div class="hint-val-fragment">
</div>
<div class="hint-val-fragment match">
-1000000.0
</div>
<div class="hint-val-fragment">
</div>
</div>
</div>
</div>
<div class="result-item">
<div class="result-item-label">
<div class="result-item-name">Resources</div>
<div class="result-item-source"><span>source:</span> <span>cz0</span></div>
</div>
<div class="result-item-hint">
<div class="hint-prop">cpuLimit:</div>
<div class="hint-val">
<div class="hint-val-fragment">
</div>
<div class="hint-val-fragment match">
-1000000.0
</div>
<div class="hint-val-fragment">
</div>
</div>
</div>
</div>
<div class="result-item">
<div class="result-item-label">
<div class="result-item-name">Resources</div>
<div class="result-item-source"><span>source:</span> <span>cz0</span></div>
</div>
<div class="result-item-hint">
<div class="hint-prop">cpuLimit:</div>
<div class="hint-val">
<div class="hint-val-fragment">
</div>
<div class="hint-val-fragment match">
-1000000.0
</div>
<div class="hint-val-fragment">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Below I've defined isValid, which is applied to every element in an array passed to allValid. This function can be applied after there's been an update on the DOM and you need to recheck the elements:
const isValid = elem => {
const val = elem.getElementsByClassName('hint-val-fragment match')[0].innerHTML.trim()
const hint = elem.getElementsByClassName('hint-prop')[0].innerHTML.trim()
return (
val === '-1000000.0'
&& hint === 'cpuLimit:'
)
}
const allValid = arr => arr.every(isValid)
const parent = document.getElementsByClassName('entity-results')[0]
const children = Array.from(parent.children)
const allAreValid = allValid(children)
Related
I would like to archive the below by using JavaScript (or with jQuery). Here is the HTML structure:
<div class="score-set">
<div class="score-item">A<div id="score">96+</div></div>
<div class="score-item">B<div id="score">99</div></div>
<div class="score-item">C<div id="score">99</div></div>
<div class="score-item">D<div id="score">96-</div></div>
</div>
<div class="score-set">
<div class="score-item">A<div id="score">86</div></div>
<div class="score-item">B<div id="score">88</div></div>
<div class="score-item">C<div id="score">90</div></div>
<div class="score-item">D<div id="score">90+</div></div>
</div>
<div class="score-set">
<div class="score-item">A<div id="score">83-</div></div>
<div class="score-item">B<div id="score">83+</div></div>
<div class="score-item">C<div id="score">76</div></div>
<div class="score-item">D<div id="score">78</div></div>
</div>
The JavaScript will do the modification, and the desired results will be B 99 C90 A 83- , which looks like:
<div class="score-set">
<div class="score-item">B<div id="score">99</div></div>
</div>
<div class="score-set">
<div class="score-item">C<div id="score">90</div></div>
</div>
<div class="score-set">
<div class="score-item">A<div id="score">83-</div></div>
</div>
The rules are:
Ignore all non-number in id="score", eg. + and -, and do the ranking.
Show one highest score item.
If two score items are the same in a set, show just one according to the div item sequence inside <div class="score-set">, ie. in the above example A > B > C > D.
When writing the result, write the original div item, including + or -.
To be able to do this, it would be best to get each individual score-set and treat one after another.
For each score item, we need to first get the score and transform it (Array#map) into a number with no digits (.replace(\/D+/g, ''))and memorize the score item html object.
Number(scoreItem.querySelector('div').innerText.replace(/\D+/g, ''))
We can then sort the remaining ones in descending order and simply take the first one of the list. Can be done with Array#sort and destructuring assignment.
.sort(({ score: scoreA }, { score: scoreB }) => scoreB - scoreA)
Then finally we update the score set html.
scoreSet.innerHTML = '';
scoreSet.appendChild(scoreItem);
const scoreSets = document.getElementsByClassName('score-set');
for(const scoreSet of scoreSets){
const [{ scoreItem }] = Array
.from(scoreSet.getElementsByClassName('score-item'), scoreItem => ({
scoreItem,
// it would be better here to access the score using the id
// but `score` is used multiple times which makes getting
// the score element unreliable
score: Number(scoreItem.querySelector('div').innerText.replace(/\D+/g, ''))
}))
.sort(({ score: scoreA }, { score: scoreB }) => scoreB - scoreA)
scoreSet.innerHTML = '';
scoreSet.appendChild(scoreItem);
}
<div class="score-set">
<div class="score-item">A
<div id="score">96+</div>
</div>
<div class="score-item">B
<div id="score">99</div>
</div>
<div class="score-item">C
<div id="score">99</div>
</div>
<div class="score-item">D
<div id="score">96-</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div id="score">86</div>
</div>
<div class="score-item">B
<div id="score">88</div>
</div>
<div class="score-item">C
<div id="score">90</div>
</div>
<div class="score-item">D
<div id="score">90+</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div id="score">83-</div>
</div>
<div class="score-item">B
<div id="score">83+</div>
</div>
<div class="score-item">C
<div id="score">76</div>
</div>
<div class="score-item">D
<div id="score">78</div>
</div>
</div>
This can be MUCH simplified
Note I changed the invalid ID to class="score"
If you cannot do that, then change .querySelector(".score") to .querySelector("div")
document.querySelectorAll('.score-set').forEach(scoreSet => {
const scores = [...scoreSet.querySelectorAll(".score-item")];
scores.sort((a,b) => parseInt(b.querySelector(".score").textContent) - parseInt(a.querySelector(".score").textContent))
scoreSet.innerHTML ="";
scoreSet.append(scores[0])
})
<div class="score-set">
<div class="score-item">A
<div class="score">96+</div>
</div>
<div class="score-item">B
<div class="score">99</div>
</div>
<div class="score-item">C
<div class="score">99</div>
</div>
<div class="score-item">D
<div class="score">96-</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div class="score">86</div>
</div>
<div class="score-item">B
<div class="score">88</div>
</div>
<div class="score-item">C
<div class="score">90</div>
</div>
<div class="score-item">D
<div class="score">90+</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div class="score">83-</div>
</div>
<div class="score-item">B
<div class="score">83+</div>
</div>
<div class="score-item">C
<div class="score">76</div>
</div>
<div class="score-item">D
<div class="score">78</div>
</div>
</div>
Is it possible using just JS (or possibly with jQuery) to get the next open html element?
In the snippet below, if I click on any div it'll give me the id of that div. I want it to get the next open element id, so e.g.
if I click on page123 it should give me 123efter
if I click on 123efter it should give me 13
I don't want the next sibling within the encapsulating div, which is all I've managed to do so far!
document.addEventListener("click", function(event) {
console.log(event.target.id);
}
);
.efter{
min-height:20px;
}
.efter:hover{
background-color:beige;
}
<div>
<div id="1">
home
<div id="1efter" class="efter"></div>
<div id="11">
page11
<div id="11efter" class="efter"></div>
</div>
<div id="12">
page12
<div id="12efter" class="efter"></div>
<div id="121">
page121
<div id="121efter" class="efter"></div>
</div>
<div id="122">
page122
<div id="122efter" class="efter"></div>
</div>
<div id="123">
page123
<div id="123efter" class="efter"></div>
</div>
</div>
<div id="13">
page13
<div id="13efter" class="efter"></div>
</div>
</div>
</div>
I first create a flat array divs with all existing div ids. In the click event handler I then look up the clicked element's successor id.
const divs=[...document.body.querySelectorAll("div")].map(d=>d.id);
document.addEventListener("click", function(event) {
console.log(divs[divs.indexOf(event.target.id)+1]);
}
);
.efter{
min-height:20px;
}
.efter:hover{
background-color:beige;
}
<div>
<div id="1">
home
<div id="1efter" class="efter"></div>
<div id="11">
page11
<div id="11efter" class="efter"></div>
</div>
<div id="12">
page12
<div id="12efter" class="efter"></div>
<div id="121">
page121
<div id="121efter" class="efter"></div>
</div>
<div id="122">
page122
<div id="122efter" class="efter"></div>
</div>
<div id="123">
page123
<div id="123efter" class="efter"></div>
</div>
</div>
<div id="13">
page13
<div id="13efter" class="efter"></div>
</div>
</div>
</div>
As an alternative, and as tagged jquery, you can use jquery's collection.index(element) overload to get the index within a collection.
As a one liner:
console.log($("div").eq($("div").index(this) + 1))
Updated snippet:
$("div").click(function(evt) {
evt.stopPropagation();
// Get once so it's not run multiple times
var divs = $("div");
var idx = divs.index(this);
var result = divs.eq(idx+1)
// do something to demo
console.log(idx, result.attr("id"));
$(".active").removeClass("active");
result.addClass("active");
});
.efter{
min-height:20px;
}
.efter:hover{
background-color:beige;
}
.active { background-color:yellow; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div id="1">
home
<div id="1efter" class="efter"></div>
<div id="11">
page11
<div id="11efter" class="efter"></div>
</div>
<div id="12">
page12
<div id="12efter" class="efter"></div>
<div id="121">
page121
<div id="121efter" class="efter"></div>
</div>
<div id="122">
page122
<div id="122efter" class="efter"></div>
</div>
<div id="123">
page123
<div id="123efter" class="efter"></div>
</div>
</div>
<div id="13">
page13
<div id="13efter" class="efter"></div>
</div>
</div>
</div>
I am attempting to make a searchable database with list.js but the search function is not working. I am not sure if I initialized it correctly or what I am doing wrong. I am sure it is something obvious but I would love another set of eyes.
Here is my HTML
<body>
<div class="hof-list">
<input class="search" placeholder="Search for a member..."/><br>
<div class="list">
<div class="objects">
<div class="name">Lucille Ball</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">Jeremy Jacobs</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">Russell Salvatore</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">John Albright</div>
<div class="year">2017</div>
</div>
<div class="objects">
<div class="name">Lousie Bethune</div>
<div class="year">2017</div>
</div>
<div class="objects">
<div class="name">Glenn Curtis</div>
<div class="year">2017</div>
</div>
<div class="objects">
<div class="name">John Oishei</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">Mary Burnett Talbert</div>
<div class="year">2017</div>
</div>
</div>
</div>
</body>
Here is my script
var options = {
valueNames: ['name', 'year']
};
var hoflist = new List('hof-list', options);
According to docs it expects the following parameters: new List(id/element, options, values); where id/element is
id or element *required Id the element in which the list area should be initialized. OR the actual element itself.
So you should pass there an actual id (so you need to change it in your html), or, you can pass there an element with
new List(document.querySelector('.hof-list'), options)
I have created a testimonial section for a website. This is a project I am building as part of my portfolio, it isnt really for a client.
Nonetheless, what I am trying to achieve is for each of these testimonials to appear within its parent div one by one. I have put them in their own seperate divs then used a counter and function to iterate through them appearing individually, however something does not seem to be working (and the console does not seem to be logging any errors).
My code is provided below. Many thanks for the help.
HTML:
<div class="row text-center">
<div class="col-md-12" id="customerreviews">
<div class="customercomment text-center">
<p>"TEXT 1"</p>
<h4>Rachel Smith<span class="location"> (Manchester)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 2"</p>
<h4>Darren Wise<span class="location"> (London)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 3"</p>
<h4>Arif Akhtar<span class="location"> (Leeds)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 4"</p>
<h4>Jason Hardy<span class="location"> (London)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 5"</p>
<h4>Michelle Rousey<span class="location"> (Birmingham)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 6"</p>
<h4>Jermaine Clarke<span class="location"> (Bristol)</span></h4>
</div>
</div>
</div>
JAVASCRIPT:
var testimonials = $(".customercomment");
var testimonialsDiv = $("#customerreviews");
var currentTestimonial = 0;
function switchComments(){
if (currentTestimonial == testimonials.length-1){
currentTestimonial = 0;
}
$(testimonials[currentTestimonial]).fadeIn("fast",function(){
$(testimonials[currentTestimonial]).delay(5000).fadeOut("slow");
currentTestimonial++;
})
}
switchComments();
EDIT the code is fading in the first element with class "testimonials", but after it fades out, nothing else appears.
Use Jquery when you gain elements.
var testimonials = $(".customercomment");
var testimonialsDiv = $("#customerreviews");
function switchComments(){
var ix, ixLen;
for(ix = 0, ixLen = testimonials.length; ix < ixLen; ix++){
$(testimonials[ix]).delay(1000 * ix).fadeIn("slow");
}
}
switchComments();
.customercomment{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row text-center">
<div class="col-md-12" id="customerreviews">
<div class="customercomment text-center">
<p>"TEXT 1"</p>
<h4>Rachel Smith<span class="location"> (Manchester)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 2"</p>
<h4>Darren Wise<span class="location"> (London)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 3"</p>
<h4>Arif Akhtar<span class="location"> (Leeds)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 4"</p>
<h4>Jason Hardy<span class="location"> (London)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 5"</p>
<h4>Michelle Rousey<span class="location"> (Birmingham)</span></h4>
</div>
<div class="customercomment text-center">
<p>"TEXT 6"</p>
<h4>Jermaine Clarke<span class="location"> (Bristol)</span></h4>
</div>
</div>
</div>
I have a div containing 3 options that can be active, and when one of them is selected(becomes active) the connector/lines associated with that element should trigger and initiate the animation. So far I have it displayed but can't figure out how to fire the animation every time the first option becomes active, and disable it when it isn't active.
CodePen
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<div class="demo">
<div class="demo__content">
<h2 class="demo__heading">Assessment <small></small></h2>
<div class="demo__elems">
<div class="demo__elem demo__elem-1">Novice Assessment</div>
<div class="demo__elem demo__elem-2">Intermediate Assessment</div>
<div class="demo__elem demo__elem-3">Advanced Assessment</div>
<span class="demo__hover demo__hover-1 active"></span>
<span class="demo__hover demo__hover-2 active"></span>
<span class="demo__hover demo__hover-3 active"></span>
<div class="demo__highlighter">
<div class="demo__elems">
<div class="demo__elem">Novice Assessment</div>
<div class="demo__elem">Intermediate Assessment</div>
<div class="demo__elem">Advanced Assessment</div>
</div>
</div>
<div class="demo__examples">
<div class="demo__examples-nb">
<div class="nb-inner">
<div class="example example-adv">
<div class="example-adv">
<div class="example-adv__top">
<div class="example-adv__top-search"></div>
</div>
<div class="example-adv__mid"></div>
<div class="example-adv__line"></div>
<div class="example-adv__line long"></div>
</div>
</div>
<div class="example example-web">
<div class="example-web__top"></div>
<div class="example-web__left"></div>
<div class="example-web__right">
<div class="example-web__right-line"></div>
<div class="example-web__right-line"></div>
<div class="example-web__right-line"></div>
<div class="example-web__right-line"></div>
<div class="example-web__right-line"></div>
<div class="example-web__right-line"></div>
</div>
</div>
<div class="example example-both">
<div class="example-both__half example-both__left">
<div class="example-both__left-top"></div>
<div class="example-both__left-mid"></div>
</div>
<div class="example-both__half example-both__right">
<div class="example-both__right-top"></div>
<div class="example-both__right-mid"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
document.addEventListener('DOMContentLoaded', function() {
$(document).ready(function() {
$('.demo__hover').on('click', function() {
$that = $(this);
if ($('.demo__hover.active').length > 0) {
$('.active').removeClass('active');
}
$($that).addClass('active');
})
})
});
I strongly suggest to refactor my code but I edited your pin, adding a class that block animation by default:
.block-anim {
animation: none !important;
}
and some dirty JS that deal with it
https://codepen.io/ThomasTognacci/pen/POqRJa