django-tables2: linkify, how to make target new window - django-tables2

Using the linkfy argument as so:
def linkify_sale(**kwargs):
record = kwargs.get("record")
if record:
return f"https://...url...#{record.get('order_sale_id')}"
class ASA_Journal_ViewTable(tables.Table):
...
order_sale_nbr = tables.Column(verbose_name="Sales Order Number", linkify=linkify_sale)
works. But how to I specify a target on the link, to open in a new window?

ok, like this
order_sale_nbr = tables.Column(verbose_name="Sales Order Number", linkify=linkify_sale, attrs={"a":{
"target":"_blank"}})

Related

How to build a simple widget or app in jupyter notebook/lab to interactively extract a substring from text?

I want iterate over a list of string, output the string as plain text in jupyter lab then interactively highlight a substring to get easily the start index of the substring and the length. The goal is to do a quick annotation of text and get the coordinates of the substring.
Is it easy or even possible to do something like this with jupyter notebook (lab)? If then How?
I had a look at ipywidgets but couldn't find something for this use case.
Here's an example with the RangeSlider:
import ipywidgets
input_string = 'averylongstring'
widg = ipywidgets.IntRangeSlider(
value = [0, len(input_string)],
min=0, max=len(input_string)
)
output_widg = ipywidgets.Text()
display(widg)
display(output_widg)
def chomp_string(widg):
start,end = tuple(widg['new'])
output_widg.value = input_string[start: end]
widg.observe(chomp_string, names='value')
You can implement this using jp_proxy_widgets. See the following screenshot:
Note that there are warnings about compatibility for selection protocols -- I only tested this on Chrome on a Mac. Also I don't know why the indices are off by one
(select_callback(startOffset+1, endOffset+1);)
Please see https://github.com/AaronWatters/jp_proxy_widget for more information
Edit: Here is the pastable text as requested:
import jp_proxy_widget
select_widget = jp_proxy_widget.JSProxyWidget()
txt = """
Never gonna give you up.
Never gonna let you down.
Never gonna run around and
desert you.
"""
selected_text = None
def select_callback(startOffset, endOffset):
global selected_text
selected_text = txt[startOffset: endOffset]
print ("Selected", startOffset, endOffset, repr(selected_text))
select_widget.js_init("""
// (Javascript) Add a text area.
element.empty()
$("<h3>please select text:</h3>").appendTo(element);
var textarea = $('<textarea cols="50" rows="5">' + txt + "</textarea>").appendTo(element);
// Attach a select handler that calls back to select_callback.
var select_handler = function(event) {;
var target = event.target;
var startOffset = target.selectionStart;
var endOffset = target.selectionEnd;
select_callback(startOffset+1, endOffset+1);
};
textarea[0].addEventListener('select', select_handler);
""", txt=txt, select_callback=select_callback)
# display the widget
select_widget.debugging_display()

Python webdriver switch from main window to popup screen (not Java alert) and login

Here is the window I need to enter new password and repeat it again and click 'create'.
My code so far:
createLogin = wait.until(EC.presence_of_element_located((By.XPATH, '//*[#id="Item.MessageUniqueBody"]/div/div/div/div/div[2]/div[2]/a')))
createLogin.click()
time.sleep(10)
try:
newPassword = self.driver.find_elements_by_xpath('//*[#id="editNewUser_newPassword"]')
newPassword1 = self.driver.find_elements_by_xpath('//*[#id="editNewUser_newPasswordRepeat"]')
newPasswordForm = self.driver.find_elements_by_xpath('//*[#id="editNewUserPasswordForm"]/table/tbody/tr[1]/td[1]')
self.driver.switch_to.active_element(newPasswordForm)
time.sleep(3)
newPassword.send_keys('123')
newPassword1.send_keys('123')
time.sleep(2)
# createLog = wait.until(
# EC.presence_of_element_located((By.XPATH, '//*[#id="editNewUserPassword_save"]')))
# createLog.click()
# time.sleep(5)
except NoAlertPresentException as e:
time.sleep(2)
myAccount = wait.until(
EC.presence_of_element_located((By.XPATH, '//*[#id="easMyAccount1"]')))
myAccount.click()
time.sleep(5)
This is the problem.
You are using find_elements_by_xpath rather than find_element_by_xpath
plural vs singular.
find_elements_by_xpath: it gives you a list of web elements with matching identifier.
find_element_by_xpath: it gives you a first web element with matching identifier.
newPassword = self.driver.find_element_by_xpath('//*[#id="editNewUser_newPassword"]')
newPassword1 = self.driver.find_element_by_xpath('//*[#id="editNewUser_newPasswordRepeat"]')
newPasswordForm = self.driver.find_element_by_xpath('//*[#id="editNewUserPasswordForm"]/table/tbody/tr[1]/td[1]')
#gauurang Answer is right, But You have to used find_element_by_xpath, also as your xpath suggested you have id to locate the webelements so it is always better to use id over xpath
Also your xpath are correct
newPassword = self.driver.find_element_by_id('editNewUser_newPassword')
newPassword1 = self.driver.find_element_by_id('editNewUser_newPasswordRepeat')
newPasswordForm = self.driver.find_element_by_xpath('//*[#id="editNewUserPasswordForm"]/table/tbody/tr[1]/td[1]')

Conditional classname and text (Rails)

I'm pretty new to Rails and trying some basic stuff like conditional classes.
On the 'show' view I have an element that changes styling depending on the stock availability, but also the text changes accordingly.
People keep saying the controller should be as small as possible, but placing this conditional in the view also feels dirty. Is this really the best way?
Current controller:
def show
#tyre = Tyres::Tyre.find_by_id(params[:id])
if #tyre.in_stock
#availability = I18n.t("products.filter.other.in_stock")
#availability_class = 'i-check-circle color--success'
else
#availability = I18n.t("products.filter.other.not_in_stock")
#availability_class = 'i-cross-circle color--important'
end
end
Edit:
Controller:
def show
#tyre = Tyres::Tyre.find_by_id(params[:id])
if #tyre.in_stock
#availability_append = ".in_stock"
else
#availability_append = ".not_in_stock"
end
#availability = I18n.t("products.filter.other#{#availability_append}")
end
View:
.xs-12.description__status
%i{class: (#tyre.in_stock? ? 'i-check-circle color--success' : 'i-cross-circle color--important')}
= #availability
You can clean your controller tyres_controller.rb (i suppose) method,
def show
#tyre = Tyre.find(params[:id]) # I believe you have a model named 'tyre'
end
Then, there will be a file named tyres_helper.rb in your myproject/app/helpers/. Put the following code there,
def tyre_availability(tyre) # it'll return an array with two values, first one is class name, second one is localized value
if tyre.in_stock
return 'i-check-circle color--success', I18n.t("products.filter.other.in_stock")
else
return 'i-cross-circle color--important', I18n.t("products.filter.other.not_in_stock")
end
end
and, in the view you can use,
.xs-12.description__status
%i{:class => tyre_availability(#tyre)[0]}
= tyre_availability(#tyre)[1]

calling an event on a Button in datawindow

I have placed a search button on a datawindow, and i have already an event for searching such list...how is it possible to call an event once the button is clicked on runtime.
below is the code on my event named "ue_key"
string xcode, iseries, ycode, sql_statement, xname, i_cname, name, iseries_no, irequested_by, irequest_problem, irequesting_dept, idate_request, idate_needed
string iasset_no, idate_received, istatus
long i_row
//integer
i_cname = dw_work_order.getcolumnname()
i_row = this.getrow()
if i_row > 0 then
if key = keyF2! and i_cname = 'series_no' then
//open(w_csearch)
// Then, define select statement
sql_statement = "SELECT series_no as 'Series NO', requested_by as 'Requested By' FROM work_order_form where status = 'A' or status = 'ACTIVE';"
str_sellist args
args.trans = sqlca
args.sel_cmd = sql_statement
// Specify which column will be the return value
args.retcol = 1
// Define drop-down items. NOTE: This should correspond
// with the alias you use for the columns you retrieve
args.dropdown_items[1] = "Series NO"
args.dropdown_items[2] = "Requested By"
// Define Search Window Title
args.title = "Work Order"
// Define transaction object for the window
// This is REQUIRE for now... :)
// Open with parameter
OpenWithParm(w_sellist, args)
ycode=message.stringparm
xcode = ycode
// MessageBox('test', xcode)
if trim(xcode) <> '' then
select series_no, requested_by, request_problem, requesting_dept, date_request,date_needed, asset_no, status
into :iseries, :irequested_by, :irequest_problem, :irequesting_dept, :idate_request, :idate_needed, :iasset_no, :istatus
From work_order_form where series_no = :xcode using sqlca;
// Messagebox('test', iseries)
this.setitem(THIS.GETROW(),'series_no', iseries)
this.setitem(THIS.GETROW(),'requested_by', irequested_by)
this.setitem(THIS.GETROW(),'request_problem', irequest_problem)
this.setitem(THIS.GETROW(),'requesting_dept', irequesting_dept)
this.setitem(THIS.GETROW(),'date_request', idate_request)
this.setitem(THIS.GETROW(),'date_needed', idate_needed)
this.setitem(THIS.GETROW(),'asset_no', iasset_no)
this.setitem(THIS.GETROW(),'status', istatus)
//dw_work_order.retrieve(iseries)
end if
end if
end if
Thanks a lot!
The datawindow control has "ButtonClicking" and "ButtonClicked" events. You can use these event to identify which button was clicked (check the event arguments, specifically dwo.Name) and call the appropriate code.
You'll want to make sure that your datawindow button's action is set for "User Defined (0)".

How can I update the label of a Polygon Vector in OpenLayers after it has been drawn?

I am quite new to OpenLayers. Right now, I have a polygon vector with some styling applied and a label.
var style = $.extend(true, {}, OpenLayers.Feature.Vector.style['default']);
style.pointRadius = 15;
style.label = "My Polygon";
style.fillColor = #f00;
style.strokeColor = #000;
var styleMap = new OpenLayers.StyleMap({"default" : style});
var polygonLayer = new OpenLayers.Layer.Vector("Polygon Layer", {styleMap: styleMap});
At some point after doing some processing, I want to display the result as a label. How can I update the label? I figure it would be something like this, but this wasn't the way.
polygonLayer.options.styleMap.styles.label = "Updated label";
Thanks in advance.
You are on the right way. You can set new label for all features in a layer like that:
polygonLayer.styleMap.styles.default.defaultStyle.label = "new label";
polygonLayer.redraw();
As you see it's important to call redraw() method after you set new value.
That's how you change label for all features in a layer. Quite often though you'll need to set new labels per feature. To achieve that you should do following when you create pollygonLayer:
var style = $.extend(true, {}, OpenLayers.Feature.Vector.style['default']);
style.label = "${feature_name}";
Each feature has a collection of attributes. In this case value of attribute feature_name will be displayed as a label. To change label value per feature you simply change value of the attribute on that feature and then of course call redraw() on layer.

Resources