I want to display a long sentence (in some component) and detect which word was clicked.
Even better if I could also highlight each word as hovered.
Hi @paul.k.pallaghy and welcome to the forum,
This will touch on a lot of anvil concepts.
Here’s one way you could do it.
For a component with a click handler it would make sense to use a Link component for each word.
To display the sentence as a sentence you’ll probably want a flow panel.
class Form1(Form1Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eleifend feugiat blandit. Aenean ornare lacus nec imperdiet consequat. Vivamus vitae sem convallis, volutpat nisl vitae, posuere massa. Quisque vel orci.'
# Any code you write here will run when the form opens.
for t in text.split():
l = Link(text=t, foreground='black', role='word')
self.flow_panel_1.add_component(l)
l.set_event_handler('click', self.text_click)
def text_click(self, **event_args):
print(event_args['sender'].text)
For the hover I used the role above and added the following to theme.css
.anvil-role-word:hover {
font-weight:bold;
}
Here’s the clone
https://anvil.works/build#clone:UANGCJ7SCTVK4CB5=FUDLFHU447FWAHXJDUY3S6RZ
How can I detect control or command key during word click (I want to select multiple words sometimes)?
Off the top of my head I can’t think that there is a native way to detect the command key. You can use anvil.js
to use native javascript events and detect the cmd key.
editing the solution above
import anvil.js
for t in text.split():
l = Link(text=t, foreground='black', role='word')
dom_node = anvil.js.get_dom_node(l)
dom_node.addEventListener('click', get_click_handler(l))
self.flow_panel_1.add_component(l)
def get_click_handler(link):
def js_handler(e):
print('cmd key:', e.metaKey, link.text)
return js_handler
I’ve adjusted the clone link above so you can see it in action.
@stucork
How do I get the command key state BACK INTO the Form1 class text handlers I’m using?
I’ve tried but failed . .
I want to return the command key state to the Form1 class.
As a global or anyway I can SOMEHOW access it from within the Form1 class where I am tracking the current list of sentences.
Really nice solution BTW.
Instead of defining get_click_handler as a function in the namespace, you could define it as a method in the class definition for the form - then the first argument is self.
That way you have a reference to self in the js_handler function.
Thnx, I’d just assumed it wouldn’t work there . .
@stucork
I’ve made some mods but I don’t get the print in def js_handler(e) occuring.
Only my text_click handler.
import anvil.js
class Form1(Form1Template):
# Globals
sentences = []
parent = ''
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
def get_click_handler(self, link):
def js_handler(e):
key = e.metaKey
print('cmd key:', e.metaKey, link.text)
return
def display_parent(self):
if self.parent in self.sentences:
self.sentences.remove(self.parent)
if len(self.sentences) > 0:
self.parent = self.sentences[0]
self.flow_panel_1.clear()
for t in self.parent.split():
l = Link(text=t, foreground='black', role='word')
self.flow_panel_1.add_component(l)
dom_node = anvil.js.get_dom_node(l)
dom_node.addEventListener('click', self.get_click_handler(l))
l.set_event_handler('click', self.text_click)
else:
self.flow_panel_1.clear()
def text_click(self, **event_args):
You’re not returning the js_handler
This mix of Anvil and js is like black magic to me . .
Thnx. Works now of course!
@paul.k.pallaghy an update on this post - we’ve added support for keys in anvil click event
def link_click(self, **event_args):
print(event_args['keys']['meta'])
That should work for Link
and Button
components and should make the implementation above slightly easier.