PDA

View Full Version : BBCODE: insert into textarea at cursor (or end), little access to page configuration



djr33
12-20-2013, 01:39 AM
Goal: add a custom bbcode button to a forum. There's no default option for this (or mod, etc.). I must do it manually due to how I want the layout to work.

Function: click on image, add text to reply textarea based on where the cursor is (if it is there, if not just at the end).


I have completed everything except this function.

I have a button that appears on the page this this code:
<a href="#" onclick="special_bbcode('EXAMPLE');return false;">EXAMPLE</a>

There's a textarea called "mytextarea".

Currently I have the function (in a script within the head section) defined as:

function special_bbcode(t) {
document.getElementById('mytextarea').innerHTML = document.getElementById('mytextarea').innerHTML+t;
}

This works well. But, obviously, it just places the text at the end of the textarea.

What I would like:
1. Click on an image/link.
2. Text appears before cursor in textarea (if the cursor is there, otherwise at end).
3. The cursor remains active and in the same location (except now being after a new symbol), and the textarea remains focused.

Can this all be done just from within a single function ("special_bbcode()")? Or do I need to set events and do other things like that? The problem is that integrating it into the rest of the forum software is very complicated.



(Note: the goal for this is to create a popup keyboard for inserting special symbols. So it's just like emoticons, really, except it's for characters that aren't on the keyboard, eg, for math.)


In short: what JS function could be used to simulate (with clicking the mouse) a key on the keyboard and inserting that symbol into, for example, the quick reply textarea here?

jscheuer1
12-20-2013, 01:47 AM
It's a lot to wade through but we beat this to death (you might want to start on the last page) here:

http://www.dynamicdrive.com/forums/showthread.php?50020-textarea-using-ENTER

djr33
12-20-2013, 02:22 AM
That's helpful, thanks.

Important question: are there potential conflicts with that script? Could it somehow disable any important functionality that already exists on the forum? I'm trying to do this with as little interference with core functionality as possible, and that's really what makes it so difficult.

djr33
12-20-2013, 04:57 AM
In fact, that worked out very well. Luckily there were no conflicts. Thanks!

So is this impossible in just a function, without attaching events to the textarea and so forth? Just curious.

jscheuer1
12-20-2013, 08:01 AM
In order to have the insertion point, you need the current range. Since that's established each time something happens in the textarea (onchange), you will need to be listening (have previously added an event listener) for that. The rest could be done more piecemeal.

djr33
12-20-2013, 09:16 AM
Makes sense, thanks.


But now to my lack of understanding of Javascript:
Can a single element for a single action (eg, "onclick") have multiple events/functions associated with it?

Let's say I have a rollover image. Can I also, without disturbing/changing that original code in any way, display an alert when my mouse is over that image?

I thought the answer was no-- I thought events were unique (and would replace each other).

But as far as I can tell in the (very well working) script you provided, the same textarea has several events associated with changes in it. How is that possible?

Again, I probably am just missing something fundamental about JS.

jscheuer1
12-20-2013, 03:02 PM
If I understand the question, that's the difference between what I call version 4 and version 5 events. Version 4 events are where you go:


el.onclick = function(){alert('This a version 4 click event. This el can have only one of these at a time'); alert('It can do more than one thing though.'); return false;};

If you have (also version 4):


<a href="#" onclick="alert('here'); return false;">Whatever</a>

And that's el, and the code at the top comes last in the parsing of the page, it will overwrite the one hard coded to the tag. If even later you have:


el.onclick = function(){};

Then there will essentially be no version 4 click event for that element. It's empty and overwrites any v4 event that came before.

Version 5 events are where you do (or similar):


el.addEventListener('click', function(){alert('Hello World!');}, false);

That will only add to the click queue for that element, it will not overwrite any previous click event and will not be overwritten by any future click event.

For more see:

http://www.dynamicdrive.com/forums/entry.php?255-Version-5-Events


However, just looking at the code, I don't think this is what's happening. I think you mean:


saveCurRng: (function(){return document.selection?
function(el){this.el = el; el.focus(); this.curRng = document.selection.createRange();}:
function(el){this.el = el, this.curRng = typeof el.selectionStart === 'number'?
el.value.substring(el.selectionStart, el.selectionEnd) : null;}
})(),

This is a property being defined by a self executing anonymous function. It will be defined once as the page loads. It will be defined differently in different browsers. It will then be the onchange event for the textarea. This approach allows the script to execute more quickly because it doesn't have to branch each time it's used.

djr33
01-03-2014, 05:11 PM
Hi John,

This is working out, so it took me a while to get back to thinking about it more.

That information is very helpful, in the post and the blog. Thanks!!

But I don't understand how this isn't going on in the script you provided. It's working on the forum and those events are working flawlessly with existing events.

It's possible that these events (version 4) are set as the basic ones and that the forum's (default) events are then added on top (version 5), I guess. I could give you a link to (or demo account in) the forum if you want to check it out.

It's not too important, just puzzling based on what you said. The existing BBCODE and additional code you provided work well together. I didn't expect that. It's not a problem, obviously, though!

jscheuer1
01-03-2014, 05:51 PM
The code I provided assigns all events as version 5 events. So, if there were existing events on the page, regardless of whether those were version 4 or 5, they would be unaffected.

At the same time, the code has little or no global exposure. That means that it's variables are local to it's functions/objects and get exposed globally either through a single reference or not at all (I forget which at the moment - that's just how I write most of my code - zero or one global). That means there should be no script conflict with existing code.

Code can exist in that way because the objects (tags) that it needs to effect and/or listen to are always globally available. So no additional globals need to be created by the code itself.

djr33
01-03-2014, 06:01 PM
Oh. I must have misunderstood what you said. I was talking about version 4 conflicts then, which are irrelevant. Ok :)

Right, I don't think the variables or anything along those lines would be a conflict.

Great, makes sense now!