global var doesn't capture text on mouseup

L

lkrubner

I've got a function, you can see it below, that is being called
onmouseup in the textarea on my main form. The idea is to find a
selection if possible and store that text in a global variable. I can't
get this to work in any browser on a Mac, though it works alright on a
PC. What am I missing?





// 01-24-05 - most of the time, with most browsers, you
can't get a selection from a form
// input with a function triggered with a form control
like a button, because clicking the
// button shifts the focus to the button and destroys
the selection. So I'm thinking that
// perhaps we can have a global variable that is set
with setFieldSelectionValue() which
// can be called onMouseUp(). This sets the value and
insertAtCursor() can check to see
// if that value is there.
var fieldValue = "";

function setFieldSelectionValue(myField) {
// 01-24-05 - this next line is meant to ensure
that we don't
// carry an old value forward.
fieldValue = "";

if (document.selection) {
if (document.selection.createRange) {
var range =
document.selection.createRange();
var fieldText = range.text;
} else if (document.selection.getRangeAt) {
// 01-24-05 - this next bit may work in
Mozilla
var range =
document.selection.getRangeAt(0);
if (range) {
if (range.text) {
var fieldText = range.text;
} else if (range.value) {
var fieldText = range.value;
}
}
} else if (document.selection.toString) {
var fieldText =
document.selection.toString();
}
} else if ('number' == typeof
myField.selectionStart) {
// MOZILLA/NETSCAPE support
//
myField.value.substring(myField.selectionStart,myField.selectionEnd)
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
if (myField.value.substring) {
if (endPos != 0) {
var fieldText =
myField.value.substring(startPos, endPos);
}
}
}
if (fieldText != "") fieldValue = fieldText;
}

xt bit may work in Mozilla
var range =
document.selection.getRangeAt(0);
if (range) {
if (range.text) {
var fieldText = range.text;
} else if (range.value) {
var fieldText = range.value;
}
}
} else if (document.selection.toString) {
var fieldText =
document.selection.toString();
}
} else if ('number' == typeof
myField.selectionStart) {
// MOZILLA/NETSCAPE support
//
myField.value.substring(myField.selectionStart,myField.selectionEnd)
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
if (myField.value.substring) {
if (endPos != 0) {
var fieldText =
myField.value.substring(startPos, endPos);
}
}
}
if (fieldText != "") fieldValue = fieldText;
}
 
F

Fred Oz

I've got a function, you can see it below, that is being called
onmouseup in the textarea on my main form. The idea is to find a
selection if possible and store that text in a global variable. I can't
get this to work in any browser on a Mac, though it works alright on a
PC. What am I missing?


That document.selection and element.selectionStart don't work in
Safari or IE 5.2.

However, element.selectionStart does work in Firefox on Mac but if you
select from the start of the text, selectionStart returns undefined so
your test:

if ('number' == typeof myField.selectionStart) {

will fail.

Your method will also fail if the user selects all the text by clicking
in the field and uses Ctrl+A. It also stops double-clicking in the
field to select all the text.

The following play code works in Firefox 1.0 on Mac OS X (but not in
either Safari 1.0.3 or IE 5.2). It deals with selectionStart being
undefined if all the selection starts with the first character. Note
that if the user doesn't select anything, the start and end will have
the same value, and if the cursor is before the first character, both
selectionStart and selectionEnd will be undefined.

If the user selects some text, then clicks in the field, the function
will return the same value as if some text was still selected. I think
that qualifies as unreliable, but it's up to you.


<html><head><title>play</title>
<script type="text/javascript">

function setFieldSelectionValue(myField) {

(document.selection)?
alert('document.selection works') :
alert('document.selection doesn\'t work');

var start, end;
if(myField.selectionStart || myField.selectionEnd) {
if (myField.selectionStart) {
start = myField.selectionStart
} else {
start = 0;
}
end = myField.selectionEnd;
alert('Started at ' + start + '\nEnded at ' + end);
} else {
alert('selectionStart and selectionEnd not supported');
}
}
</script>
</head><body>
<form action="">
<textarea onmouseup="
setFieldSelectionValue(this);">Fred is a very fine fellow</textarea>
</form>
</body></html>
 
R

RobG

Fred Oz wrote:
[...]
Your method will also fail if the user selects all the text by clicking
in the field and uses Ctrl+A. It also stops double-clicking in the
field to select all the text. [...]
If the user selects some text, then clicks in the field, the function
will return the same value as if some text was still selected. I think
that qualifies as unreliable, but it's up to you.

This can be avoided by adding setFieldSelectionValue as an
onclick to the submit button, or to any other button. As long
as the user clicks on the button immediately after making the
selection, it works.

The following code will report the selected range when either
"Show selection" or submit are clicked.

<html><head><title>play</title>
<script type="text/javascript">

function setFieldSelectionValue(myField) {
var start, end;
if(myField.selectionStart || myField.selectionEnd) {
if (myField.selectionStart) {
start = myField.selectionStart
} else {
start = 0;
}
end = myField.selectionEnd;
alert('Started at ' + start + '\nEnded at ' + end);
} else {
alert('selectionStart and selectionEnd not supported');
}
}
</script>
</head><body>
<form action="" onsubmit="
setFieldSelectionValue(this.form.tx1);">
<textarea name="tx1">Fred is a very fine fellow</textarea>
<br>
<button onclick="
setFieldSelectionValue(this.form.tx1);
">Show selection</button><br>
<input type="submit" onclick="
setFieldSelectionValue(this.form.tx1);">
</form>
</body></html>
 
J

John Doe

Does it occur to anyone else that the way to do this is to work with the
mouseup event in the textarea itself always updating a hidden field to
the current selection. Then no issues if user deselects before clicking
a button (cause the mouseup fires and resets selection to nothing) and
no issues with loss of focus (because mouseup isn't fired when the focus
is lost).???? I'm not gonna build a full-fledged example but it only
seems reasonable.
Fred Oz wrote:
[...]
Your method will also fail if the user selects all the text by clicking
in the field and uses Ctrl+A. It also stops double-clicking in the
field to select all the text. [...]
If the user selects some text, then clicks in the field, the function
will return the same value as if some text was still selected. I think
that qualifies as unreliable, but it's up to you.

This can be avoided by adding setFieldSelectionValue as an
onclick to the submit button, or to any other button. As long
as the user clicks on the button immediately after making the
selection, it works.

The following code will report the selected range when either
"Show selection" or submit are clicked.

<html><head><title>play</title>
<script type="text/javascript">

function setFieldSelectionValue(myField) {
var start, end;
if(myField.selectionStart || myField.selectionEnd) {
if (myField.selectionStart) {
start = myField.selectionStart
} else {
start = 0;
}
end = myField.selectionEnd;
alert('Started at ' + start + '\nEnded at ' + end);
} else {
alert('selectionStart and selectionEnd not supported');
}
}
</script>
</head><body>
<form action="" onsubmit="
setFieldSelectionValue(this.form.tx1);">
<textarea name="tx1">Fred is a very fine fellow</textarea>
<br>
<button onclick="
setFieldSelectionValue(this.form.tx1);
">Show selection</button><br>
<input type="submit" onclick="
setFieldSelectionValue(this.form.tx1);">
</form>
</body></html>
 
L

lkrubner

--------------------
Does it occur to anyone else that the way to do this is to work with
the
mouseup event in the textarea itself always updating a hidden field to
the current selection.
-------------------

Interesting that you put it like that since that is what I thought I
was doing. Except that I was using a global var instead of a hidden
field. But the idea was the same, to store the info somewhere
onmouseup(), so as to avoid problems with loss of focus. That is how
the script works. The problem is that my function doesn't seem to be
capturing the info. Just to go over it again, my textarea gets declared
like this:

<div class="formInput"><textarea id="inputId5"
name="formInputs[cbMainContent]" style="height:200px; width:100%;"
class="textareaInput"
onmouseup="setFieldSelectionValue(this)"></textarea>
<p><a href="#inputId5" onclick="makeBigger(inputId5);">Make box
larger?</a></p></div>


and then setFieldSelectionValue was trying to capture that value like
this:



// 01-24-05 - most of the time, with most browsers, you can't get a
selection from a form
// input with a function triggered with a form control like a
button, because clicking the
// button shifts the focus to the button and destroys the selection.
So I'm thinking that
// perhaps we can have a global variable that is set with
setFieldSelectionValue() which
// can be called onMouseUp(). This sets the value and
insertAtCursor() can check to see
// if that value is there.
var fieldValue = "";

function setFieldSelectionValue(myField) {
// 01-24-05 - this next line is meant to ensure that we don't
// carry an old value forward.
fieldValue = "";

if (document.selection) {
if (document.selection.createRange) {
var range = document.selection.createRange();
var fieldText = range.text;
} else if (document.selection.getRangeAt) {
// 01-24-05 - this next bit may work in Mozilla
var range = document.selection.getRangeAt(0);
if (range) {
if (range.text) {
var fieldText = range.text;
} else if (range.value) {
var fieldText = range.value;
}
}
} else if (document.selection.toString) {
var fieldText = document.selection.toString();
}
} else if ('number' == typeof myField.selectionStart) {
// MOZILLA/NETSCAPE support
//
myField.value.substring(myField.selectionStart,myField.selectionEnd)
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
if (myField.value.substring) {
if (endPos != 0) {
var fieldText = myField.value.substring(startPos, endPos);
}
}
}
if (fieldText != "") fieldValue = fieldText;
}
 
F

Fred Oz

John said:
Does it occur to anyone else that the way to do this is to work with the
mouseup event in the textarea itself always updating a hidden field to
the current selection.

The original post was that it works OK on PC (presume Windows),
but not Mac. My (paraphrased) answer was that
document.selection and element.selectionStart do not work on Mac
for Safari and IE, and that Firefox has usability issues with
selections.
Then no issues if user deselects before clicking
a button (cause the mouseup fires and resets selection to nothing) and
no issues with loss of focus (because mouseup isn't fired when the focus
is lost).????

But other issues with using mouseup continue -

1. what if the selection is made using Ctrl+A?

2. using mouseup blocks double-clicking, a typical method of
selecting everything in the field.
I'm not gonna build a full-fledged example but it only
seems reasonable.

You should, then you'd know whether your suggestion works or
not.
 
L

lkrubner

This is for a software control panel, so I only need to get it working
in one Mac browser. I can tell users which browser to use. I'm dealing
with client in particular who is Mac based, and I'd like to get
something working for him this week. He's perfectly willing to use
whatever browser I suggest to him.
 
L

lkrubner

Much thanks to all your help. This is a good response and gives me
something to think about. I'm not sure I understand your concern here:

--------------------------
If the user selects some text, then clicks in the field, the function
will return the same value as if some text was still selected. I
think
that qualifies as unreliable, but it's up to you.
--------------------------

That is sort of the idea. Reading through Danny Goodman's book on
Javascript, I noticed that one can grab selections using Javascript,
but one usually can't manipulate those selections by clicking on form
inputs, because clicking a button shifts the focus and therefore
deselects the text (the exceptions are FireFox and IE on PC). I was
trying to think of ways around this, and I think someone here suggested
capturing selected text onmouseup(). It occured to me I could store the
selection in a global var, and then use that when someone clicks a
button. The idea is to wrap the text in an HTML tag, for instance, a
bold tag. The global fieldValue can be used as a last ditch resort if
the current browser is not FireFox or IE on a PC. In the following
function, we hope to be dealing with FireFox of IE on a PC, but if not,
at the end, we use whatever value has been stored to fieldValue. You
mention that this method of doing things is unreliable, if so, I'm
thinking that maybe another way to do this would be to use a prompt as
the last ditch effort, and ask the user to input whatever text they
want wrapped by the HTML tag they clicked on.



function insertAtCursor(myField, tag) {
// 01-24-05 - this first if() block is for Microsoft IE on PC
if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
if (range.text == '') {
alert("You haven't selected any text to change.");
} else {
range.text = '<' + tag + '>' + range.text + '<\/' + tag + '>';
}
} else if ('number' == typeof myField.selectionStart) {
// this next bit is for Netscape/Mozilla
//
myField.value.substring(myField.selectionStart,myField.selectionEnd)
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
if (endPos != 0) {
var mySelection = myField.value.substring(myField.selectionStart,
myField.selectionEnd);
mySelection = '<' + tag + '>' + mySelection + '<\/' + tag + '>';
myField.value = myField.value.substring(0, startPos) +
mySelection + myField.value.substring(endPos, myField.value.length);
} else {
alert("You haven't selected any text to change.");
}
} else {
// 01-24-05 - the above methods work in IE and Firefox on the PC.
For other
// browsers we try to use the fieldValue variable and append to
the end of the
// textarea. fieldValue is global and set onmouseup by
setSelectionFieldValue().
myField.value += '<' + tag + ' >' + fieldValue + '<\/' + tag +
'>';
}
}
 
L

lkrubner

We've set up a site as a demo site and a debugging site. You can see
what I'm trying to do here:

http://www.publicpen.com/designer/mcControlPanel.php

You'll need a username and password to get in. Use these:

username: designer
password: designer123

In invite everyone to go kick it around.

When you log in, you'll see a text area on the lower right side of the
screen. There are some formatting buttons there. The way it works in IE
and FireFox on a PC is you can select text and then it a formatting
button (like bold) and the javascript will wrap the text in some HTML
tags. I'm trying to get this to work in at least one browser on the
Mac.
 
F

Fred Oz

We've set up a site as a demo site and a debugging site. You can see
what I'm trying to do here:

http://www.publicpen.com/designer/mcControlPanel.php

You'll need a username and password to get in. Use these:

username: designer
password: designer123

In invite everyone to go kick it around.

Once logged in with Firefox, clicking on a top menu items gives:

"Error: document.getElementById("mainPanel") has no properties
Source File:
http://www.publicpen.com/designer/mcControlPanel.php?arrangement=
Line: 983"


You have a div with class="mainPanel", but none with that id.

The navigation seems hopeless, probably because of the failure of
the above. Anyway, eventually I got to a page with a text area
and buttons to format entered text.

It seems to work OK in Firefox for Mac OS X. Personally, I think
attempting an HTML editor this way is pointless. It is easy to
ceate crap, like <h5>blah<h5></h5></<h5>h5></<h5></h5>h5>.

Unless you are goning to parse and validate the HTML, why bother?

The markup you are adding is trivial to learn, but hey, it's your
page.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top