PricingBlog

Is it possible to highlight text and get the selection?

  • tomthebigtree-1173655700908544101

    Tom Ireland

    2 years ago

    I'm looking at how I might highlight text on the page and have something whereby I can get the selected text and then use that with subsequent actions e.g. copy, trigger custom event, etc. I can see on MDN that there is the Web API getSelection method.

    Is that possible in toddle somehow?
  • andreasmoller-1173657037851332649

    Andreas Møller

    2 years ago

    Not without a custom action/formula
  • tomthebigtree-1173657314365014166

    Tom Ireland

    2 years ago

    Righto. Thanks, @Andreas Møller - helps me narrow things down a wee bit. 👍
  • tomthebigtree-1173682596035710986

    Tom Ireland

    2 years ago

    @Andreas Møller - Okay, so progress has been made! 🙌 I'm able to get the selected text and log that to the console in my custom action but I can't tell from the docs how I get it to return the value so I can store that in a variable in my component. Any pointers if you have a moment?
  • tomthebigtree-1173682916245639209

    Tom Ireland

    2 years ago

    It was quite straightforward after watching a JS tutorial online. This is the code:

    function selectedText(event) {
    const selected_text = window.getSelection().toString().trim();
    console.log(selected_text);
    }
  • andreasmoller-1173683118989910046

    Andreas Møller

    2 years ago

    You can emit events from your custom actions, but the simplest solution is probably make a formula instead of an action.
  • tomthebigtree-1173685507776053338

    Tom Ireland

    2 years ago

    Okay, that's good to know. I assume it would be the exact same as above? I tested it and can see the log to console with the selected text but the variable value is Null when I come out of test mode. I'm using mouseup event on p element to set variable value with custom formula.
  • andreasmoller-1173687964610596974

    Andreas Møller

    2 years ago

    Can you show the code for the formula?
  • tomthebigtree-1173688638261952532

    Tom Ireland

    2 years ago

    Sure! I was just away to write back to you to say I managed to get the action to trigger the event and store the value but would be good for a sense-check. 😄 2 secs...and thank you for taking a look. 😊
  • tomthebigtree-1173689900567117835

    Tom Ireland

    2 years ago

    Here you go, sir! Some screenshots for your viewing pleasure. Code:

    function selectedText(event,ctx) {
    const selected_text = window.getSelection().toString().trim();
    console.log(selected_text);
    ctx.triggerActionEvent("text_selection",selected_text)
    }
    1173689898482532424-custom-action.png
    1173689899761815702-text-selection-event.png
    1173689900353191936-variable-result.png
    1173689899061362708-mouseup.png
  • tomthebigtree-1173735110487589009

    Tom Ireland

    2 years ago

    For those that are curious on this thread, I did a first pass on getting selected text from the page and then having an action component display to add items to a list (a temp array for testing just now, but will be database). Happy to share how I did this if interested.

    @Andreas Møller - Couple of things:

    1. I'm using x and y to set position of action component but it's hard to line things up due to the fact that I'm not currently getting the coordinates of the selected text. Would be nice to center the action above the selected text. Any pointers on that? I'm using window.getSelection, which I believe has all that stuff in an object, right? Not sure if it's easy enough to pass that in the same event? A bit beyond me at that point from a custom actions perspective. 😄

    2. Any plans to add selection to the list of events in order to do what I'm trying to do from a no-code perspective? I'd imagine that'd unlock a few doors for folk e.g. select text to Tweet, etc. 😉
  • andreasmoller-1173756603103727667

    Andreas Møller

    2 years ago

    1. I dont know exactly how I would do that. My best guess would be to put the selected text into a span, and then use that as an achor.
  • So you would essentially split the text into 3 parts, with the middle part being the selection.
  • tomthebigtree-1173875497290190868

    Tom Ireland

    2 years ago

    Interesting. 🤔 I'll ponder on that one. Thank you! 🙂
  • tomthebigtree-1173971115949948959

    Tom Ireland

    2 years ago

    Thanks for the insights on this one, Andreas. I did try splitting and that worked to a degree but I lost the selection in the browser (not the text selected though) after doing that, so the action button was kinda hanging in space and you could not see what you highlighted. Probably my approach and likely a better way but position seems to work a wee bit better if not the ideal solution. Have submitted a feature request for [select and range events](https://discord.com/channels/972416966683926538/1173970485118246922/1173970485118246922). Thanks for all your help on this one - appreciated! 🙌
  • tomthebigtree-1175434673967599748

    Tom Ireland

    2 years ago

    @Andreas Møller / @Jacob Kofoed / @Erik Beuschau - Following on from office hours, I'm still struggling with the span thing for placement of my action component when selecting text, so I dug a bit more into getRange and getClientBoundingRect.

    I managed to get it so that I log the custom action variables to the console with the results of those, so I can see that for my text selection range I have the x and y position of the whole text plus some other useful information. It's a DOMRect object that's returned but struggling to see the object values from the event - it just returns what appears to be an empty object even though it's stored in the custom action variable and I'm passing that back.

    I've done a short Loom demonstrating the problem. Any help and advice gratefully received and if there is a much easier way using the span, I'm all ears! 🙂

    https://www.loom.com/share/9a01da5be1ea4723bfc346a235e0e7f3?sid=605d09b6-6166-4d74-b9c7-b68ec898fdf2
  • tomthebigtree-1175506682156163103

    Tom Ireland

    2 years ago

    Found something interesting, if I copy the array in the variable, despite it showing as the first item in the array (the DOMRect object) being empty, there is data there. Is that a bug?

    // Result in variable from copying
    [{"x":97.6812515258789,"y":104.4000015258789,"width":234.84375,"height":16.800003051757812,"top":104.4000015258789,"right":332.5250015258789,"bottom":121.20000457763672,"left":97.6812515258789},"quickly and easily from the browser"]
  • tomthebigtree-1175511987225116892

    Tom Ireland

    2 years ago

    Actually, may have almost cracked it. The object key/value pairs are not visible but you can still see them if you copy them aaand you can still get them in the formula using get and the key as the path. 🙌 Not 100% there but consistently moving the component to the left and top coordinates brought back from the bounding rectangle now. Wahoo!
  • andreasmoller-1175525476916281394

    Andreas Møller

    2 years ago

    Yes the “DomRect” object that JavaScript uses cannot be logged to console. 🤦‍♂️
  • tomthebigtree-1175529181019394058

    Tom Ireland

    2 years ago

    @Andreas Møller - You sure? I managed to log it to the console in the custom action. Or is that how display in the variable is handled? It seems like it is not displayed in the variable but I can get the keys in a formula.

    I have now managed to consistently generate the selected range position info with the DOMRect object in my custom action and - with some hard math 😄 - I managed to get my formula to consistently apply position at the top of the range selection with a little gap. The last piece of the puzzle would be to have left position be in the center of the component but I think my brain has had enough. It is now working consistently! 🙌
    1175529180365066351-insight-position-example.png
    1175529180813852692-range-position-formula.png
  • andreasmoller-1175529921322438677

    Andreas Møller

    2 years ago

    No sorry I am confusing issues, I think the problem was serialising it, which is why you are not seeing it in the variable
  • tomthebigtree-1175531117063962654

    Tom Ireland

    2 years ago

    Ah, okay. Thanks for confirming, @Andreas Møller . Is that a bug then?
  • andreasmoller-1175533355027144746

    Andreas Møller

    2 years ago

    Kinda, but I don’t think it is one we can fix, since the value has to be serialised before it can be shown in the variable.

    We have a getBoundingClientRect formula in the toddle project that returns a new object with the same values as the DomRect
  • I think it has to be fixed in the Action/Formula
  • tomthebigtree-1175534096273899530

    Tom Ireland

    2 years ago

    Is that a toddle fix or me fix? 😄
  • andreasmoller-1175534250985005056

    Andreas Møller

    2 years ago

    You will have to fix it in your action, I can send you an example later
  • tomthebigtree-1175534321705156680

    Tom Ireland

    2 years ago

    Oh, cool! 🙌
  • 🤔 reminds me I need to remove console.log messages from custom action as well
  • andreasmoller-1175534545680998532

    Andreas Møller

    2 years ago

    🙂
  • tomthebigtree-1175535748523499733

    Tom Ireland

    2 years ago

    This should also mean the same logic could be applied to the JSON rte I was working on for formatting selected ranges. 😉
  • andreasmoller-1175536068012032041

    Andreas Møller

    2 years ago

    Yes. I actually didn’t know you could use getBoundingClientRect on a selection range. You learn something every day
  • tomthebigtree-1175537113874301008

    Tom Ireland

    2 years ago

    Every day is a school day. I didn't know any of that was possible until I started hunting and messing about. 😄
  • datomnz-1175538098516537384

    Tom Wrench

    2 years ago

    What you're doing here sounds super cool @Tom Ireland .

    Kinda wish I had time for another project that would have this use case so I could dig into it too 😅
  • tomthebigtree-1175539079157391460

    Tom Ireland

    2 years ago

    @Tom Wrench - Yeah, it's very cool and - for my app - going to make it nice and easy to select snippets of info from product feedback to add as insights to inform product improvements. It has been done before but I wanted to a) create my take on it and b) see if it was possible in toddle by a non-coder. Proving 100% possible. I definitely want to share build videos as well because sharing is caring. Empty hands as Raphael would say.
    🔥1
  • andreasmoller-1175549746149085237

    Andreas Møller

    2 years ago

    I use this formula in the swipey-card project
    1175549745901613154-CleanShot_2023-11-18_at_22.33.46.png
  • All it is doing is creating a new object that looks just like the DomRect, but since it is a normal JS object it can be serialized.
  • andreasmoller-1175550601178927205

    Andreas Møller

    2 years ago

    This looks solid. Just to be clear my idea with the span, was because I didnt know you could get the bounding rect from a selection. Your solution is MUCH better
  • You could make it a formula in stead of an Action. that might make it easier to use.
  • tomthebigtree-1175552664705171496

    Tom Ireland

    2 years ago

    @Andreas Møller - It certainly feels like an easier solution given that it gives you all the positioning, etc. At the moment, I am getting the text selection and the bounding rect within a single action with event trigger.

    Are you suggesting I split these up and turn one (or both?) into formulas instead? (see attached)

    Thanks for sharing that formula. 🤘

    I've also now centred the component. I checked the width in dev tools and hard set it as haven't worked out how to find the width of an element dynamically yet.
    1175552664222834709-custom-action.png
    1175552664503865444-insight-position.png
  • andreasmoller-1175562844524261467

    Andreas Møller

    2 years ago

    I mean if your current solution works I dont see any reason to change it.
    If you later find out that there are similar cases where you need the same data, but dont want to trigger and Action the consider refactoring then 🙂
    👍1
  • lululucaschae-1227188495647506504

    lululucaschae

    1 year ago

    Awesome thread! Thank you 🙂
    🙌1