when i trie to set a twitter bootstrap tooltip on a dom element
(.tooltip $( :#someid) (clj->js {:placement :left}))
I get
> Uncaught TypeError: Object function (sel, var_args) {
> var p__9921 = null;
> if(goog.isDef(var_args)) {
> p__9921 = cljs.core.array_seq(Array.prototype.slice.call(arguments, 1), 0)
> }
> return $__delegate.call(this, sel, p__9921) } has no method 'tooltip' clusty.js:23013 (anonymous function)
I am not using any advanced optimization's and don't have issues using jayq with other libs like datatables...
What am i missing?
Thanks
It looks like you've transposed the dollar sign and open paren.
(.tooltip ($ :#someid) (clj->js {:placement :left}))
(reposting Kevin's comment here so that question can be closed)
Related
In google chrome, especially now with custom elements, it became very cumbersome to select and element by hand nowadays, even though the browser knows the whole path to it already. Or is there a way that leads to a query selected for an element that I'm inspecting?
Situation:
What chrome can tell me:
What chrome is unable to create for me AFAIK:
While building an chrome extension I have found a need to uniquely locate an element when returning to a page. To do this I needed to create a query string for a selected element (custom context menu click)
While searching for a solution I found this unanswered question.
As I could not find an off the shelf solution or API to do the task I wrote the following function. It is untested in the wild, is very rough and ready (using poor node traversing techniques). I posted it in this state lest I forget and this question remains unanswered.
Create Query String For Element
A function to build a query string that will uniquely locate an element from a reference of the element.
const querytStr = createQueryStringForElement(myElement); // return string or undefined
if (querytStr) {
const element = document.querySelector(queryStr);
console.log(element === myElement); // expected result true
}
If the function fails to create a query that uniquely locates an element it returns undefined. else it returns the query string.
Example results
"#editor > div.ace_scroller > div.ace_content > div.ace_layer.ace_text-layer > div.ace_line:nth-child(45) > span.ace_punctuation.ace_operator"
"#buttons" // A UI container
"#buttons > div.buttons" // A sub UI container
"#buttons > div.buttons:nth-child(2)" // A button element by position
"#buttons > div.buttons:nth-child(3)" // A button element by position
How it works
The code assumes that the page is well formed (ids must be unique).
The query string will try to start with an id eg "#elementId" but if an element has no id the query will use the tag and class names. eg "div.my-class".
The tag and class name may not uniquely identify the element. To check if the query is unique, the query string is used to query the DOM from the elements parent.
If needed the query string will use the elements position to refine the query "div.my-class:nth-child(2)". Unfortunately this makes the resultant query string insensitive to changes in element order.
The query string is built up along each parent until it finds an element with an id or there are no more parents.
The final step uses the query to see if the query finds the correct element returning the query if successful.
The code
function createQueryStringForElement(element) {
const getElementSel = element => {
const tName = element.tagName.toLowerCase();
var i = 0, str = element.id ? "#" + element.id : sel = tName;
if (str.includes("#")) { return str}
str += element.classList.length ? "." + [...element.classList.values()].join(".") : "";
if (element.parentElement) {
const res = element.parentElement.querySelector(str);
if (res !== element) {
while (i < element.parentElement.children.length) {
if (element.parentElement.children[i] === element) {
i > 0 && (str += ":nth-child(" + (i + 1) + ")" );
break;
}
i++;
}
}
}
return str;
}
const queryPath = [];
const original = element;
do {
const subQuery = getElementSel(element);
queryPath.push(subQuery);
if (subQuery[0] === "#") { break }
element = element.parentElement;
} while (element);
const query = queryPath.reverse().join(" > ");
try {
const els = document.querySelector(query);
if (els === original) { return query }
} catch(e) { }
}
I constructed a function linked to MySQL which returns a list of children for a given parent id. I would like to output this list of children using ipywidgets.
I am having trouble linking the function to ipywidgets. So far I have:
> from ipywidgets import widgets
>
> text1 = widgets.Text()
> text2 = widgets.Text()
> button = widgets.Button(description = 'Run')
> display(text1)
> display(button) display(text2)
>
> idnum = text1.value
> text2.value= list_children(idnum)
>
> button.on_click(list_children)
The function is the following:
> def list_children(parentid):
> value = parentid
> parent_80 = session.query(Parent).get(value)
> parent_80_children= parent_80.children
> childrenlist=[]
>
> for i in parent_80_children:
> childrenlist.append(i.UWI)
>
> return childrenlist
I keep getting the following error:
AttributeError: 'NoneType' object has no attribute 'children'
as it breaks in this line:
parent_80_children= parent_80.children
The function is correct if I run the python cell so I know it's working, but it breaks when I try to click the widget box "Run". Somehow there is no link between the function and the widget box.
I would like to have the output upon clicking the "Run" widget button as the following:
1771860100
1771860200
1771860300
minus the bullet points.
Any input is appreciated.
When you use the .on_click() method of a button, you need to specify the function you want to run, which you have done correctly. However, when you click the button, the button instance itself gets passed to the function. That explains why, when you click the button, you see that error. The function thinks it is getting a parentid (probably a string or int), but actually receives an instance of ipywidgets.Button instead!
Assuming you want to take the text in the text1 widget as you did in the upper section of your code, you need to pass the Text widget to the function. So, add this to your on_click() call using a partial to specify the text field as an argument. The text widget will be the first parameter, and the Button instance will follow as the 2nd parameter. If you forget that the Button instance gets passed when writing your function definition, you will get an error along the lines of 'takes exactly 1 argument but 2 given'.
Hopefully you can take the example below and modify to suit your needs.
import ipywidgets as widgets
from functools import partial
text1 = widgets.Text()
def list_children(text_field, button):
print(text_field.value)
button = widgets.Button()
button.on_click(partial(list_children, text1))
display(text1, button)
In header.pug
block link
-var selected='Home';
-var menu = [{'title':'Home','address':'/home/home.html','child':[]},{'title':'Shopping','address':'/shopping/shopping.html','child':[{'title':'TV','address':'/tv/tv.html'},{'title':'Smartphone','address':'/smartphone/smartphone.html'}]},{'title':'About','address':'/about/about.html','child':[]}]
#navbar
+navbar(selected,menu)
In mixin.pug
//- Navbar mixin
mixin navbar(selected, menus)
ul
each menu in menus
if selected === menu.title
li.active
a(href=menu.address, title=menu.address)= menu.title
if menu.child.length > 0
+navbar(selected, menu.child)
else
li
a(href=menu.address, title=menu.address)= menu.title
if menu.child.length > 0
+navbar(selected, menu.child)
Problem:
When compile it into html, there is a error, shown in the console:
Cannot read property of undefined in the "if menu.child.length > 0" row
Edit:
Added a picture:
The problem is with the data in menu.child when you call +navbar(selected, menu.child). Objects in menu.child don't have a propety child, so when Pug try to get the length of this undefined values the error appears.
Add child property inside objects in array menu.child.
Or modify a little bit your code to change if menu.child is not undefined (I assume you don't want to, because objects without child property will not be displayed:
if typeof menu.child == typeof []
if menu.child.length > 0
+navbar(selected, menu.child)
For starters, I'm seeing two types of problems with my the functionality of the code. I can't seem to find the correct element with the function xmlXPathEvalExpression. In addition, I am receiving errors similar to:
HTML parser error : Unexpected end tag : a
This happens for what appears to be all tags in the page.
For some background, the HTML is fetched by CURL and fed into the parsing function immediately after. For the sake of debugging, the return statements have been replaced with printf.
std::string cleanHTMLDoc(std::string &aDoc, std::string &symbolString) {
std::string ctxtID = "//span[id='" + symbolString + "']";
htmlDocPtr doc = htmlParseDoc((xmlChar*) aDoc.c_str(), NULL);
xmlXPathContextPtr context = xmlXPathNewContext(doc);
xmlXPathObjectPtr result = xmlXPathEvalExpression((xmlChar*) ctxtID.c_str(), context);
if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
xmlXPathFreeObject(result);
xmlXPathFreeContext(context);
xmlFreeDoc(doc);
printf("[ERR] Invalid XPath\n");
return "";
}
else {
int size = result->nodesetval->nodeNr;
for (int i = size - 1; i >= 0; --i) {
printf("[DBG] %s\n", result->nodesetval->nodeTab[i]->name);
}
return "";
}
}
The parameter aDoc contains the HTML of the page, and symbolString contains the id of the item we're looking for; in this case yfs_l84_aapl. I have verified that this is an element on the page in the style span[id='yfs_l84_aapl'] or <span id="yfs_l84_aapl">.
From what I've read, the errors fed out of the HTML Parser are due to a lack of a namespace, but when attempting to use the XHTML namespace, I've received the same error. When instead using htmlParseChunk to write out the DOM tree, I do not receive these errors due to options such as HTML_PARSE_NOERROR. However, the htmlParseDoc does not accept these options.
For the sake of information, I am compiling with Visual Studio 2015 and have successfully compiled and executed programs with this library before. My apologies for the poorly formatted code. I recently switched from writing Java in Eclipse.
Any help would be greatly appreciated!
[Edit]
It's not a pretty answer, but I made what I was looking to do work. Instead of looking through the DOM by my (assumed) incorrect XPath expression, I moved through tag by tag to end up where I needed to be, and hard-coded in the correct entry in the nodeTab attribute of the nodeSet.
The code is as follows:
std::string StockIO::cleanHTMLDoc(std::string htmlInput) {
std::string ctxtID = "/html/body/div/div/div/div/div/div/div/div/span/span";
xmlChar* xpath = (xmlChar*) ctxtID.c_str();
htmlDocPtr doc = htmlParseDoc((xmlChar*) htmlInput.c_str(), NULL);
xmlXPathContextPtr context = xmlXPathNewContext(doc);
xmlXPathObjectPtr result = xmlXPathEvalExpression(xpath, context);
if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
xmlXPathFreeObject(result);
xmlXPathFreeContext(context);
xmlFreeDoc(doc);
printf("[ERR] Invalid XPath\n");
return "";
}
else {
xmlNodeSetPtr nodeSet = result->nodesetval;
xmlNodePtr nodePtr = nodeSet->nodeTab[1];
return (char*) xmlNodeListGetString(doc, nodePtr->children, 1);
}
}
I will leave this question open in hopes that someone will help elaborate upon what I did wrong in setting up my XPath expression.
I am wondering if there is any keyword in R for jumping out of a function without executing the rest of it. In C, Java, or Matlab, there is the keyword 'return'. But the 'return' keyword in R works different than in those languages. Here is an example,
myfunc = function() {
if (TRUE) {
return # hopefully, jump out of the function
}
print('the rest of the function is still executed!')
}
In the example, languages like Java will not execute 'the rest' when 'return' is met, while in R 'return' is only in the scope of the if statement and the rest of the functions is still executed. In this particular example I could have added an 'else' block to achieve it but I would like to know if there is any keyword which would give similar behaviors as in Java etc. Thanks.
What you show is actually syntactically valid R code ... but you have the mistake of not supplying a value to return. So here is a corrected version:
R> myfunc <- function() {
if (TRUE) {
return(NULL) # hopefully, jump out of the function
}
print('the rest of the function is still executed!')
}
myfunc <- function() {
+ if (TRUE) {
+ return(NULL) # hopefully, jump out of the function
+ }
+ print('the rest of the function is still executed!')
+ }
R> myfunc()
NULL
R>
I think what you're looking for is:
stopifnot()