I have an enter selection with two elements that I want to prepend to a svg container such that the order of the two elements is maintained. I have tried using insert using the :first-child selector like this
var newlayers = layer.enter();
newlayers.insert("g",":first-child")
As a result of using the :first-child selector the second element in the enter selection ends up being the first element in the svg container after insertion. How can I avoid this behavior?
Ok I was able to reorder the elements using .sort after the insert selection is created in this way:
var newlayers = layer.enter();
newlayers.insert("g",":first-child")
.sort(function(a,b){ return b-a; });
This leaves the ordering of the data intact while only reordering the inserted elements in DOM. I went down the route of reordering the data returned on enter() itself and that opened a whole new bunch of other problems.
Related
Below is the approach I have used in order to select values from a dropdown using nightwatch.As you can see this is not a good approach. We can't select the specific value from dropdown unless we click on the exact element.
this.useXpath();
this.click('(//td[#class="styles_selectDropdownContainer__2Vrns"])[1]')
this.useCss();
this.click('#react-select-6-option-1')
In selenium java there is a very good option like below
Select fruits = new Select(driver.findElement(By.id("fruits")));
fruits.selectByVisibleText("Banana");
I want to know of there is a similar approach can be used in nightwatch as well?
This is not built up using Select and Option tag so inbuilt selenium functions wouldn't work. Work around would be to click first on the parent span and then in list store every div (which is option), iterate the loop and for each web element if text matches with your desired text you can click on it.
Code :
this.useCss();
this.click("span[aria-live='polite']")
Now store options in a list :
var elements = document.querySelectorAll('.elements'); // use
//div[contains(#class,'option')] as element selector.
Now iterate the list :
// Iterate over them.
[].forEach.call(elements, function (element) {
// Manipulate each element.
element.click();
});
});
it's possible to get hidden nodes or edges??
i tried to get by making a filter but it doesn't work becaus there is no property hidden in edges dataset.
Thanks.
var HidenEdgesIds = edges.getIds({
filter: function (item) {
return ((item.hidden == true);
}
});
this is a part of my code.
Based on the documentation of DataSets and Edges something like that should work (untested):
var hiddenEdgeIds = edges.getIds({
filter: function (item) {
return item.hidden == true;
}
});
Update
Do you set the hidden property, when you add the edges to your dataset?
Hidden nodes are... hidden. It's something used internally in the Network to render beautifully curved edges.
Why do you need access to the hidden nodes?
UPDATE: if I understand you correctly you have two types of nodes, one of which you can toggle to be displayed or hidden. To achive that, you can simply create your nodes with ids you choose, and to show/hide them update the nodes hidden property. You should not try to use the internally used hidden nodes, but simply create your own group with nodes that you toggle visible/hidden.
I am using clone to add new row to the DOM table dynamically from a button click event like below mentioned. but i want to append the cloned node to a specific row position in the DOM table. i know i can do that by using "insertrow" option but i want to use this using clone.
var newNode = tblBody.rows[1].cloneNode(true);
tblBody.appendChild(newNode);
is there any way to insert or append the "newNode" in a position i dynamically choose rather appending it as last row.
Use .insertBefore() from tblBody, and pass the newNode as teh first argument, and the child of tblBody before which the node should be inserted as the second argument.
// put this node----v before this----v
tblBody.insertBefore(newNode, tblBody.rows[i]);
If tblBody.rows[i] is null or undefined, then .insertBefore() will just behave like .appendChild(), and put it at the end.
node.insertBefore() is what you are looking for: https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore
In your source code you can define tfoot before tbody but in the browser tfoot will still be displayed last:
<table>
<thead><tr><th>i get displayed first</th></tr></thead>
<tfoot><tr><td>i get displayed last</td></tr></tfoot>
<tbody><tr><td>i get displayed second</td></tr></tbody>
</table>
Now, I want to grab the tr elements of this table in their visual order, not the order they have in the html. So this of course does not do the trick:
var rows = $('table tr');
jQuery goes through the table and adds the tr elements in the order they appear in the source code.
I thought I could make separate blocks and concatenate them to get the right order:
var header = $('table>thead>tr');
var body = $('table>tbody>tr');
var footer = $('table>tfoot>tr');
var rows = $().add(header).add(body).add(footer);
Strangely enough the order is still the same as if I did $('table tr')! How can this be?
I've also illustrated the problem in a jsFiddle: http://jsfiddle.net/nerdess/sKewX/2/
If you want to have the elements in the exact order you want, you need to build the result manually. I've modified your code in the fiddle: http://jsfiddle.net/lechlukasz/sKewX/3/
var header = $('table>thead>tr');
var body = $('table>tbody>tr');
var footer = $('table>tfoot>tr');
var apppend = function(arr, items) {
for (var i=0;i<items.lenght;i++)
arr.push(items[i])
}
var rows = []
append(rows, header)
append(rows, body)
append(rows, footer)
console.log(rows);
Element selectors look at the DOM, so they will only return the elements in the order they appear in the DOM.
If you want them in the VISUAL order you'll have to determine the positioning of each item yourself.
See: Determining an element's absolute on-document position
From documentation for add() method:
Do not assume that this method appends the elements to the existing
collection in the order they are passed to the .add() method. When all
elements are members of the same document, the resulting collection
from .add() will be sorted in document order; that is, in order of
each element's appearance in the document. If the collection consists
of elements from different documents or ones not in any document, the
sort order is undefined. To create a jQuery object with elements in a
well-defined order, use the $(array_of_DOM_elements) signature.
So yes, it will appear the same as $('table tr');
Because $('table tr') will only look for code (it has nothing to do with the console).
Now because you add the body to var rows before you add the footer, it is logical that the display will be different from the code.
It's the same as publishing a book and then telling the readers to read page 3 before page 2:
Now the readers ('the console') know the correct order, but the book still retains a wrong order of page numbers.
So to make life easy: try to keep code and display as parallel as possible. Hence try to keep the same order in both to avoid unnecessary complexity.
Here's an example using the insertion sort algorithm (http://en.wikipedia.org/wiki/Insertion_sort). By design, add() collects the elements in the DOM order.
The idea is to sort the elements based on how they'd be seen visually (using their offset).
JsFiddle: http://jsfiddle.net/Pv4tj/
I have a bunch of text areas that are children of a div that has an id. I want to get the text in each of those text areas in an array - so is there a way in jquery to get all the children that are of a certain type(in this case text area) of a certain parent?
I've tried this -
$("#optionGroup_0").children('input[type=text], textarea');
but that returns an empty array. I think the above method would work if I had the right selector for a text area, but I'm not sure.
Can anyone help?
You can do it like so:
var array = $("#optionGroup_0 textarea").map(function() {
return $(this).val();
}).get();
See working demo
.find() is every descendant, where .children() goes only one level deep. See: api.jquery.com/find
$("#optionGroup_0").find('input[type=text], textarea');