In JQuery I used parent() function to get immediate parent of any element. In loop something like this
$(this).parent();
The same I want to do in dojo my loop is like this.
dojo.query(".entryURL").forEach(function(node, index, arr){
var url = dojo.attr(node, "href");
// I want to get the parent of node, which will be ofcourse diff for each iteration
});
Someone please give me a Hint, I tried using parent.node also I'm trying to append to the parent like this
dojo.place("<span style='color:green'>URL</span>",query(node).parent(), "last");
I'm getting this error in firebug
TypeError: _365.appendChild is not a function
Regards
Aadam
Some problems here:
dojo.place() or dojo/dom-construct::place() is not compliant with the dojo/NodeList API used by dojo/query. In stead of that use modules like dojo/NodeList-manipulate or dojo/NodeList-dom. Since you're a jQuery user, I recommend using dojo/NodeList-manipulate because it mimmicks the jQuery API.
To retrieve the parent of a DOM node, you indeed use the parent() method, but that part of the API is only available if you load dojo/NodeList-traverse.
This is a working example using the feedback:
require(["dojo/query", "dojo/NodeList-traverse", "dojo/NodeList-manipulate", "dojo/domReady!"], function(query) {
query(".entryURL").forEach(function(node, index, arr){
query(node).parent().append("<span style='color:green'>URL</span>");
});
});
JSFiddle: http://jsfiddle.net/okk8unj5/
Related
i am trying a drag and drop in an iframe and to do that i need to pass xpath in find since i cant find a unique element to pass in cy.get()
currently i am trying
cy.xpath('//div[#class="unlayer-editor"]//iframe[#src]')
.should("be.visible")
.find('//div[#class = "blopockbder-coent-tols43 col-sm-12"]//div[#aria-describedby="t8ppy-tooltip-9"]')
but this isnt working
i am using cypress for automation
Not an expert on xpath, but I think .find() can't be mixed with an xpath selector.
Two things to try
// chain 2nd xpath in place of .find()
cy.get('div[class="unlayer-editor"] iframe[id="my-iframes-id"]')
.should("be.visible")
.xpath('//div[#class = "blopockbder-coent-tols43 col-sm-12"]//div[#aria-describedby="t8ppy-tooltip-9"]')
or
// use .within() instead of .find() (roughly equivalent)
cy.get('div[class="unlayer-editor"] iframe[id="my-iframes-id"]')
.should("be.visible")
.within(() => {
cy.xpath('//div[#class = "blopockbder-coent-tols43 col-sm-12"]//div[#aria-describedby="t8ppy-tooltip-9"]')
})
Other things that might need adjusting
The iframe selection generally needs a follow-up command to get it's document body (ref Working with iframes)
// get the iframe document body any select within it
cy.get('div[class="unlayer-editor"] iframe[id="my-iframes-id"]')
.its('0.contentDocument.body', { log: false }).should('not.be.empty')
.within(() => {
cy.xpath('//div[#class = "blopockbder-coent-tols43 col-sm-12"]//div[#aria-describedby="t8ppy-tooltip-9"]')
})
Some of those classes in the path like col-sm-12 are purely display-oriented and may be different if you test at different devices. Once the test works, try removing them to make the test more robust.
I apologize if this is a duplicate, just haven't been able to find anything close to this myself.
The company I work for has an online reporting system that is run by an ng-app applied directly to the body tag. I have been tasked with modifying the result that returns from this ng-app. Following code is called using onload attached to the body tag.
function getElements(){
var list;
list = document.getElementsByClassName("neutral");
[].forEach.call(list, function (listItem) {
addNeutral(listItem);
});
...
Basically, trying to find anything with class "neutral" and apply results from another function to it. The addNeutral function is basically just
element.classList.add("neutralHighlight");
This code seems to run and gathers the correct list of elements, but the new class is never added and no errors occur. So long story short, is there any way to modify the output of a ng-app using code separate from the ng-app itself? Any guidance would be greatly appreciated.
Update 3/5/20
So I implemented Shaun's response and it still isn't working properly. With some debug messages, I can see that it collects the "list" variable as an HTMLCollection. The forEach function doesn't seem to even trig
function getElements(){
var list;
list = document.getElementsByClassName("neutral");
console.log(list); //Debug - Shows in console
[].forEach.call(list, function (listItem) {
console.log(listItem); //Debug - Does not show in console
addNeutral(listItem);
});
}
function addNeutral(element){
angular.element(element).addClass("neutralHighlight");
console.log("!!!end addNeutral"); //Debug - Does not show in console
}
Update 3/9/20 -SOLUTION-
Application is returning the HTML Collection, but it displays with a length of 0 (still displays the objects, but I think that's a Firefox console thing). When trying to loop through the list items, it returns null for the first item, so the function is still being called before the Angular app loads completely.
That being said, I messed around with things a bit this morning and came to a solution! I ended up using the setInterval function with a 5 second interval (since I need it to update, I may change this to optimize it later by adding onChange items to the objects I grab initially). The setTimeout that was proposed would have worked with a delay added to it. This probably isn't the most elegant solution, and there's probably a better way to do it, but this works for anyone interested.
function getElements(){
var list;
list = document.getElementsByClassName("neutral");
for (i = 0; i <= list.length; i++){
var listItem = list.item(i);
addNeutral(listItem);
}
}
function loadFunction(){
setInterval(function(){getElements()}, 5000);
}
I added <script>loadFunction()</script> right before the closing HTML tag to execute.
Update 4/21/20 -IMPROVED SOLUTION- CSS Attributes
So this is a bit specific to my scenario, but I wanted to include it for anybody else who may come across this in the future. I was actually able to accomplish this entirely with CSS attribute selectors. The tags that I wanted to edit all had specific titles assigned to them via the ng-app provided from the company, so I was able to use CSS selectors like div [title~="NotReadyForNextCall"]{<custom styling here>} to select any block that included an agent who was not ready for their next call. This is a much better solution in terms of resources required to operate and overall performance, so I hope it helps anybody looking at this down the line!
You might be able to get around this by using the angular object in your code and adding the class on an angular.element instead. AngularJS doesn't use a virtual DOM but it does use its own node references (which is what makes it so tricky to work with outside of the framework, as Lex pointed out in the comments of your question). Try:
angular.element(element).addClass("neutralHighlight");
Yes, you have access to angular outside of the app! And a last note, addClass() is available on angular.element because AngularJS comes with jqLite.
Further investigation
It looks like the above solution works if the class 'neutral' is being added in angular via the class attribute, but it looks like your app may be adding it programmatically with the ng-class directive after the DOM has rendered.
I wrapped your getElements() function in a setTimeout():
setTimeout(getElements);
This is unfortunately not a guarantee that the ng-class update will have taken place, but what it does is it executes the function after the previous digest cycle has completed and that appears to be working.
An even safer solution would be to use document.ready but again with the angular.element wrapper. This will ensure the initial DOM state has been rendered by AngularJS, including applied directives:
angular.element(document).ready(function() {
getElements();
});
EDIT: Update 3/9/20 -SOLUTION-
The solution proposed in the answer is almost identical to the setTimeout() answer given here. The only difference is setInterval() will keep executing the code every 5 seconds until you tell it to stop.
You can do this with the following:
var loadFunction = setInterval(function() {
var el = getElements();
if (el) clearInterval(loadFunction);
}, 5000);
And just return a bool in your getElements() like so:
function getElements() {
var list;
var found = false;
list = document.getElementsByClassName("neutral");
[].forEach.call(list, function (listItem) {
addNeutral(listItem);
found = true;
});
return found;
}
See: codepen.io/shaunetobias/pen/KKpXRxq
In a tree built with jsTree, I have the text within the <a> tag sitting in a variable. I would like to check that node. How can I do so?
I am currently finding that node, using jQuery, and altering its class. However, this does not repair the parent node by making the parent undetermined in its class. I tried doing $('.colors').jstree("checkbox_repair"), but that didn't seem to do anything.
It would be great if someone could actually answer both those questions, since they are related to the same problem.
Here is a jsFiddle, illustrating the issue--> http://jsfiddle.net/thapar/5XAjU/
In js_tree there are .check_node ( node ) and .uncheck_node ( node ) functions, i think this is what you are asking for. Soe the documentation here: http://www.jstree.com/documentation/checkbox
This is an excerpt from the documentation in the link above, "how to perform an operation":
/* METHOD ONE */
jQuery("some-selector-to-container-node-here")
.jstree("operation_name" [, argument_1, argument_2, ...]);
/* METHOD TWO */
jQuery.jstree._reference(needle)
/* NEEDLE can be a DOM node or selector for the container or a node within the container */
.operation_name([ argument_1, argument_2, ...]);
So I think this syntax should work
$.jstree._reference(".colors").check_node('li#tree_3');
Also i am not sure you should be using a class to reference your tree. Probably use an ID to reference your tree, and then use this syntax:
$.jstree._reference("#colors").check_node('li#tree_3');
//EDIT: Please keep in mind that the newest version of jsTree doesn't have a function called _reference anymore. It got renamed to reference (without the leading underscore). (Last checked 24/08/2015 15:45 by #mkli90)
Link: https://www.jstree.com/api/#/?f=$.jstree.reference(needle)
If you want to check jsTree nodes on load for example like this:
$(document).ready(function()
{
$.jstree._reference('#menu').check_node('#pih2');
});
it does not work. For me works following:
$(function () {
$('#mainMenu1').bind('loaded.jstree', function(e, data){ //waiting for loading
$.jstree._reference('#menu').check_node('#pih2'); //check node with id pih2
$.jstree._reference('#menu').check_node('#pih6'); //check node with id pih6
});
});
I use jsTree 1.0-rc3 and JQuery 1.7.1.
Aloe
In current versions of jstree the following syntax works:
$("#my_tree").jstree("check_node", node_id);
I would like to add this solution, the select_node function does the same function as check_node. we can use it as follows;
$('#jstree_id').on('loaded.jstree', function() {
$("#jstree_id").jstree("select_node", ["list of nodes go here"]);
});
You can use it to select multiple nodes in an array or a single node.
I have some javascript code that looks like this:
dojo.query("#maintenanceOpData tr").forEach(function(node, index, nodelist){
if (index % 2 == 0) {
dojo.style(node, {
"backgroundColor": "#FFFFCC"
});
};
});
Everything I find in online documentation shows that dojo.style expects the ID of the DOM element, not the DOM node itself. What can I do? The only other examples show using dojo.query(...).style(...), which applies the style to all nodes. I only want to apply it to every other node, which is why I use the for-each call.
http://dojotoolkit.org/reference-guide/dojo/style.html
dojo.style(node, style, value);
node:
id or reference of the DOM node to get/set style for
EDIT: Works for me
Which version of Dojo are you using? Like JIP says, the code you've pasted should work fine ( http://jsfiddle.net/4HXMF/ ), given that you're using a recent version of Dojo.
Dojo query actually supports many of the new selectors, so you can in fact do:
dojo.query("#maintenanceOpData tr:nth-child(odd)").style("backgroundColor", "#FFFFCC");
I have an object decorated with [DataContract] attribute and my WCF service is returning this as JSON like this:
{"GetCommentsByPostResult":[{"CommentCreated":"\/Date(1305736030505+0100)\/","CommentText":"Comment 1"},{"CommentCreated":"\/Date(1305736030505+0100)\/","CommentText":"Comment 2"},{"CommentCreated":"\/Date(1305736030505+0100)\/","CommentText":"Comment 2"}]});
Ive attempted to iterate through the CommentCreated with this jQuery code:
$(data).each(function ()
{
alert(this.CommentCreated);
});
But all I get is an alert box with 'undefined in' so I changed it to:
$(data).each(function () {
$(this.GetCommentsByPostResult).each(function () {
alert(this.GetCommentsByPostResult);
});
});
but that still doesnt work. What I want to do is iterate the CommentCreated and throw them to an alert box....
I'm not sure, but I don't think this would be the current element when calling each. Also, why are you wrapping the data variable with the jQuery function? jQuery collections are for DOM elements.
$.each(data.GetCommentsByPostResult, function (e) {
alert(e.CommentCreated);
});
Depending on how you are acquiring the data (a library? custom code?) you will most likely have to convert the JSON string first into an actual JavaScript object. Many browsers have built in methods for doing this, though you may need to take advantage of a 3rd party library to take advantage of those that do not have out-of-box support. I would recommend JSON-js as it follows the same syntax as those found built into some browsers.
var obj = JSON.parse(data);
Once you have this object, you can now access the data with standard JavaScript dot or bracket notation:
var comments = obj.GetCommentsByPostResult; // or...
var comments = obj['GetCommentsByPostResult'];
Those two lines are equivalent. To iterate the comments, as you are trying to do, you could try:
$.each(obj.GetCommentsByPostResult, function (e) {
alert(e.CommentCreated);
});
Also, I would recommend using console.log() instead of alert(), and a browser that supports inspection of the logged objects. This would be FireFox with the Firebug extension, or Chrome with their developer tools (Ctrl-Shift-J to activate). Not sure about the status of this type of tool in IE9, though I would not be surprised if there was an equivalent tool there as well.