How to introduce a variable in a Markup function in Flask - python-3.x

I am writing a python flask function that uses a flash() to give a user an opportunity to undo an action. I am trying to present a variable "task_id" within a Markup(). This variable is defined earlier in the function before the flash is called. I am trying to assign a data-* attribute the value of this variable, but it is not working.
flash(task_name + " was marked complete " + Markup('<a href="#" class="toggle_task" data-task_id=task_id>UNDO</a>'))
I also tried using jinja syntax, like {{task_id}} but this does not work either. How can I pass a variable into the Markup()?

Try this:
flash(task_name + " was marked complete " + Markup('<a href="#" class="toggle_task" data-task_id={}>UNDO</a>'.format(task_id)))

Related

After you've found an a WebDriver element, how can you apply an xpath on that element to narrow it down further?

Here's the situation:
My HTML code's structure looks something like this:
XPATH1
XPATH1 + XPATH2
XPATH1 + XPATH3
XPATH1
XPATH1 + XPATH2
XPATH1 + XPATH3
I need to access those sub-paths. So I"m trying to get all XPATH1s into a list first and then trying to iterate over it.
Unfortunately, this is yielding duplicates for me.
I've got the following code in Python:
elements_list = driver.find_elements_by_xpath(XPATH1)
for element in element_list:
var1 = element.find_element_by_xpath(XPATH2) #We need XPATH1/XPATH2
var2 = element.find_element_by_xpath(XPATH3)
#lots more sub-paths
I suspect that what is happening is, element.find_element_by_xpath(XPATH2) does NOT apply to the element's XPATH. Instead it applies it universally on the page and fetches the whole list of XPATH2s.
I can't use XPATH1 + XPATH2 either because then it's still going to path to each element.
How can I access each element on this page using a for loop?
Also, is there any use of element.find_element_by_xpath function? It seems practically useless because the xpath gets applied to the entire page.
This is because you didn't specify CONTEXT NODE.
Note you should start your XPATH2 and XPATH3 with the dot that stands for "current context" (XPATH1):
elements_list = driver.find_elements_by_xpath('//div')
for element in element_list:
var1 = element.find_element_by_xpath('./a')
var2 = element.find_element_by_xpath('.//p')
This Selenium behavior inherent for search by XPath only. With other methods as find_element_by_css_selector, find_element_by_name, etc... context node should not be specified, so element.find_element_by_css_selector('a') will work fine
Another way of solving this, besides the way Andersson pointed out, is the following:
total_count = len(driver.find_elements_by_xpath(XPATH1))
for i in range(1,total_count+1):
var1 = element.find_element_by_xpath("("+ XPATH1 + ")[{0}]".format(i) + XPATH2)
var2 = element.find_element_by_xpath("("+ XPATH1 + ")[{0}]".format(i) + XPATH3)
Basically, we type in the absolute path by putting XPATH1 in brackets and iterating over it with an index.

The new line code "\n" and/or #NewLine does not add new line to field

I'm getting document history, adding "\n" and existing document history. Code executes without any error. But when I see it in web everything on one line. In notes client, document history is shown as one line of activity.
Tried with #Newline and same issue.
What I'm doing wrong?
Thanks in advance.
Here is sample code:
var myvar="\n"
var h=getComponent("docHistory1").getValue();
var msg="Stage 2 - LAB Manager approved and completed check. Send to Chemist: " + unm + " + dt1;
document1.setValue("DocHistory", h + myvar + msg);
document1.save();
Use a Multiline Edit Box xp:inputTextarea instead of a Computed field xp:text and set it to Read only readonly="true".
As an alternative you could still use a Computed field replacing all '\n' with '<br />' and setting escape="false".
Just to give an alternative solution, you could use a style on the computed text component with "white-space:pre" (or pre-line or pre-wrap, see this for the differences) and that would preserve the newlines in the content.

Angular JS ng-click action function as string

I am creating an application where the site menu would be dynamically loaded from JSON file. Each menu may correspond to an action that would be defined inside the ng-click directive. This would look something like this
<li ng-repeat="menuItem in menuContainer.menus" class="{{menuItem.cssClass}}">
<a href="{{menuItem.url}}" ng-click="{{menuItem.clickAction}}">
<i class="{{menuItem.iconClass}}"></i>{{menuItem.name}}
<span class="badge">{{menuItem.subMenus.length}}</span>
</a>`enter code here`
<li>
Now the problem is ng-click does not recognize the clickAction as a function, I believe this is due to linking process. I want to know is there any way to evaluate a string to method. I tried do $eval but it executes the function on load.
How do I do this?
Define methods not as strings, but as functions and replace ng-click="{{menuItem.clickAction}}" to ng-click="menuItem.clickAction()". Another way to define function on $scope, like:
$scope.executeString = function(body){
eval(body);
};
and replace your ng-click to ng-click="executeString(menuItem.clickAction)". Anyway, use eval is antipattern;)
Remember, that ng-click and other directives, like that, takes angular expression as parameter. And if body of you expression is a = b + c than angular convert it in javascript like $scope.a = $scope.b + $scope.c

computed field value in xpages

I am trying to update a computed fields value on click of a button with a value of a edit box + its own value.
Code written on button: here i put value of edit box in scope variable and make edit box blank. comment_te is the name of edit box
requestScope.put("commentValue", getComponent("comments_te").getValue);
getComponent("comments_te").setValue("");
Code written for value of computed field: comments is the name of computed field
getComponent("comments").getValue + "\n" + requestScope.get("commentValue")
But I get the output is:
0 com.ibm.xsp.component.xp.XspInputText#65426542
Please help me with this.
You're missing the parentheses in your calls to getValue(). By omitting these, you're returning a pointer to the getValue method of the component, not the result of invoking that method. Change each reference to getValue to getValue(), and you'll get a different result.
Your code returning the Object.
Try the following.
This following code get the the editbox value and set to a scope variable.
requestScope.commentValue = getComponent("comments_te").value;
getComponent("comments_te").value = "";
This following code sets the value to the computed field.
getComponent("comments").value = getComponent("comments").value + "\n" + requestScope.commentValue;
When you are appending the value to the computed field, as default it will add 0 to its value. Do the validation if you want.
I hope this helps you...!!!

Jade variable rendering inside tag specifications

I have a Jade page like so:
table
th Site Name
th Deadline
th Delete Transaction
- if (transactions != null)
each item in transactions
tr
td= item.item_name
td
span(id='countdown' + item.timeout + ')= item.timeout
td
span(style='cursor: pointer;', onclick='deleteTransaction("=item.uniqueId")')= "X"
button(id='confirmButton', onclick='confirm();')Confirm
As you can see in both the span attribute I try to put a local variable in two different ways and it doesn't work. Concerning the first way, I receive a token ILLEGAL error, while the second simply writes in my JavaScript something like deleteTransaction("=item.uniqueId");. I know the answer is something really stupid, but again and again Jade doc (even if it has improved) doesn't help me.
Thanks
To quote the docs:
Suppose we have the user local { id: 12, name: 'tobi' } and we wish to create an anchor tag with href pointing to "/user/12" we could use regular javascript concatenation:
a(href='/user/' + user.id)= user.name
Ergo:
span(id='countdown' + item.timeout)= item.timeout
// ...
span(style='cursor: pointer;', onclick='deleteTransaction("' + item.uniqueId + '")')= "X"
Quoting again:
or we could use jade's interpolation, which I added because everyone using Ruby or CoffeeScript seems to think this is legal js..:
a(href='/user/#{user.id}')= user.name
And so:
span(style='cursor: pointer;', onclick='deleteTransaction("#{item.uniqueId}")')= "X"
As a general tip that you'll use every day of your programming life: balance your quotes. Just like brackets and parentheses, every quotation mark must either open a new quotation or close an already-open quotation (of the same kind, i.e. double-quotes close double-quotes, single-quotes close single-quotes). To borrow your code:
span(id='countdown' + item.timeout + ')= item.timeout
// ^
// |
// What's this guy doing? ---------+
Even though Jade is a templating language and perhaps not a "real" programming language this rule, just as in HTML (also not a programming language), will serve you well.

Resources