0

I'm trying to access a global variable in two Javascript methods. The first one is supposed to write to the variable and the second one is supposed to read it.

I have the following code:

var selectedObj;
function first(){
    selectedObj = window.getSelection();
    alert(selectedObj);
}

function second(){
    alert(selectedObj);
}

So the user selects some text in an contenteditable textbox. When function first() runs, it does in fact display what was selected. So I know its value is going into the global variable selectedObj.

But before running function second(), the selected text becomes unselected. However, nothing happens that explicitly sets the value of selectedObj. Ergo, I would expect it to still retain the value of what was previously selected by the user.

But it doesn't. When the function second() runs, the alert is empty.

The alert won't be empty if the user doesn't deselect the text, so I know the global variable can work. But I need it to retain its value even if the user deselects the text.

How can I make this happen?

user3402743
  • 553
  • 2
  • 8
  • 12
  • 2
    How/when is `first` being called? – larz May 10 '17 at 14:45
  • My suspicion is that first is being invoked in such a way that it is overwriting with an empty string on a subsequent call to get the selection. what happens if you store the selection to a temp variable first and then only make the assignment to selectedObj if it is not empty? – dgeare May 10 '17 at 14:49
  • The user highlights some text in the contenteditable area, which pops up a modal. If the user clicks a particular link in the modal, first() is called. First runs the code above, then hides that modal and displays a second modal. When the user clicks a button on that second modal, second() is called. If the user clicks inside a textbox in the second modal, the global variable seems to reset (since the highlighted text lost focus). If the user doesn't click inside that textbox, the global variable doesn't seem to reset. – user3402743 May 10 '17 at 14:50
  • @dgeare, I added the following to first(): var temp = window.getSelection(); if (temp != "" && temp != null && temp != undefined) { selectedObj = temp; } But got the same result. – user3402743 May 10 '17 at 15:00

3 Answers3

2

Like someone else suggested, setting it to a local variable (by value instead of reference) seems to work.

var selectedObj;

function first() {
  let newSelection = window.getSelection().toString();
  selectedObj = newSelection;
  alert(selectedObj);
}

function second() {
  alert(selectedObj);
}
Lorem ipsum yada yada
<button onclick="first()">First</button>
<button onclick="second()">Second</button>
larz
  • 5,724
  • 2
  • 11
  • 20
  • That does seem to work! Thanks! Is there a way, though, to make it reselect the text after the user deselected it? – user3402743 May 10 '17 at 15:10
  • Of course there's a way! http://stackoverflow.com/questions/985272/selecting-text-in-an-element-akin-to-highlighting-with-your-mouse may be of use to you. – larz May 10 '17 at 20:55
1

From the docs (man I love docs): Window.getSelection()

Returns a Selection object representing the range of text selected by the user or the current position of the caret.

You answered your own question really:

The alert won't be empty if the user doesn't deselect the text

You're assigning the result of window.getSelection() to your global.

selectedObj = window.getSelection();

When the result is empty, your global is empty. Like @larz said in his comment it's most likely in how/when funciton first is called.

gforce301
  • 2,944
  • 1
  • 19
  • 24
  • Yeah, but I wouldn't expect the value of the global to change from when I first set it to window.getSelection(). The result wasn't empty originally. If I had two variables, X and Y, and I write the line "X = Y;", then I wouldn't expect X to change if I change Y later. – user3402743 May 10 '17 at 14:53
  • That's the thing with objects. They are always **referenced**. When changing an object's contents through one reference, all references will still point to that same (changed) object. – JJWesterkamp May 10 '17 at 14:56
  • @JeffreyWesterkamp, how can I store it by value instead of by reference so it doesn't change? I need to retain what was selected at a particular point, not what is selected currently. – user3402743 May 10 '17 at 14:59
  • If you want to "retain" the value stop using a common global. – gforce301 May 10 '17 at 15:01
  • @gforce301, Function first() never calls function second(), so how do you propose getting the data between? – user3402743 May 10 '17 at 15:02
  • getSelection() returns a **live** Selection object. That means that it's always up-to-date with what's selected anytime. You'll have to copy the data you need to a regular object. – JJWesterkamp May 10 '17 at 15:04
  • Not trying to be offensive here. An entire discourse on programming structure, best practices, design patterns and the like is way way beyond the scope of an answer to this question. Might I suggest a basic javascript tutorial? [JavaScript basics](https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics) – gforce301 May 10 '17 at 15:05
0

as mentioned in question, before second() runs text becomes unselected causing selectedObj to set to empty value.

You should set the value of selectedObj if window.getSelection() !== ""

Meharaj M
  • 69
  • 1
  • 5