PDA

View Full Version : Passing Values



Valor Studios
06-18-2010, 07:18 PM
Hi everyone. I'm currently working on a web-based application and Javascript has never been one of my strong points. I'm currently using this (http://code.google.com/p/lwrte/) as my rich-text editor of choice and have a question which may be easy for JS pros but have been the cause of my misery for a day now.

I know very basic Javascript so I'll explain my problem. So when the user clicks the insert image icon, Thickbox overlay opens up. This is iframe by the way. Here the user enters all there image info blah blah blah. Now when everything is good, the user clicks insert image. I need to pass the information from iframe to the textarea located on the parent document and was wondering how I would go about it.

I've been looking into it and my guess is something like execCommand('insertHTML', 0, 'HTML here'). However how do I link it to the textarea and pass the values. Additionally the text editor overlays an iframe on top of the textarea tag so I'm not sure about how I can solve this problem.

Please help. Thanks!

jscheuer1
06-19-2010, 05:20 PM
You should use the editor's built in functions. Say you didn't have an iframe, how would the editor do it? It may use execCommand for those browsers that support it, but it probably has a function for that which simplifies things cross browser. You should use that. This looks promising (from http://code.google.com/p/lwrte/wiki/API?tm=6):


selection_replace_with(html)

So I'm guessing that, say you initialized the editor like so:


window.arr = $('.rte1').rte({
css: ['default.css'],
controls_rte: rte_toolbar,
controls_html: html_toolbar
});

then from the page in the iframe, you could do a:


parent.arr[0].selection_replace_with(html);

where html is a string of HTML code you want inserted. The use of parent is a common javascript method to access things on a parent page from its child page.

I'm just guessing though it looks like a very good possibility.

Valor Studios
06-19-2010, 10:41 PM
I get an error in Firebug saying the the variable, in our case arr is undefined.

Do I somehow need to say that this variable is child of the function and if so how do I go about doing it.

I'm sorry about this John but I don't have even the rudimentary know-how of Javascript. Sorry!

jscheuer1
06-19-2010, 11:35 PM
Did you do:



window.arr = $('.rte1').rte({
css: ['default.css'],
controls_rte: rte_toolbar,
controls_html: html_toolbar
});

That window. is required to make the variable available to the global scope - the only scope from which code on a child page could access it.

And did you do it inside of the $(document).ready function? Does the editor show up at all?

If you want more help:

Please post a link to a page on your site that contains the problematic code so we can check it out.

Valor Studios
06-19-2010, 11:57 PM
Please take a look. Click the insert image button in the toolbar and an overlay will appear.

http://viwera.com/js-problem/

This is what opens up inside an iframe.
http://viwera.com/js-problem/insert.image.php

I really appreciate your help John.

jscheuer1
06-20-2010, 01:20 AM
You're welcome for the help. The documentation on this one is fairly poor. With a bit of snooping and some trial and error I discovered that:


You have the correct syntax on the top/parent page (the one with the editor on it). In other words this:


<script type="text/javascript">
$(document).ready(function() {

window.arr = $('#editor_content_editor_rte').rte({
width: 700,
height: 270,
controls_rte: rte_toolbar,
controls_html: html_toolbar
});

});

</script>

is good.


The syntax for evoking its functions is not exactly as described on the api page (http://code.google.com/p/lwrte/wiki/API?tm=6). In a way it is, but the numerical access (arr[0]) clearly doesn't work. The arr['txt1'] method does work, but the explanation of what 'txt1' refers to is extremely sketchy.


To make a long story short, instead of using:


parent.arr[0].selection_replace_with(html);

use:


parent.arr.editor_content_editor_rte.selection_replace_with(html)

As before, html refers to the string you want inserted. It can be an img or other HTML tag or just plain text. It will be inserted at the point the cursor currently occupies in the editor, or if there is an actual current selection in the editor, it will replace the selected content.

I did:


parent.arr.editor_content_editor_rte.selection_replace_with('<img src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" alt="original image" title="">')

and it put the familiar Google logo at the insertion point.

Boring Details -


editor_content_editor_rte

as used here is clearly a reference to the id of the element used to initialize that instance of the editor. It is stored in an associative array (a javascript object) but not as suggested by the documentation, also in a numerically indexed array (a true javascript array). This is often the case with jQuery created objects. In fact it is the standard for jQuery created objects. But clearly it is not the case here.

Valor Studios
06-20-2010, 01:38 AM
I love you John. That worked perfectly! Thanks a bunch!

This is off-topic but can you please explain to me a bit about accessing associate/integer arrays in javascript. My understanding was that $(document).ready(function() {
}); creates a jQuery function and all variables inside this are part of jQuery. I'm guessing this serves more of an onload type of function. But i'm surprised to see that selection_replace_with() was accessed directly without referencing jQuery or rtw/lwrte. My understanding is the .protoype extends a function/class.

Also one more thing, how come I didn't have to use the function getElementById() to refer to the textarea as opposed to referencing it (editor_content_editor_rte) directly.

jscheuer1
06-20-2010, 02:58 AM
The first question, about associative/integer arrays really applies to almost any programming language where arrays are used. The terminology and syntax do differ but the structure of the two types of arrays are basically identical regardless of the language -

Structure of Associative Array (called an object in javascript):


[
something = athing,
anotherthing = someotherthing
]

javascript syntax:


var myObject = {something: athing, anotherthing: someotherthing};

or:


var myObject = {};
myObject.something = athing;
myObject.anotherthing = someotherthing;

There are other ways.

In this type of construct something and anotherthing are often referred to as keys, and athing and someotherthing as items. There is an order to the items, but it is generally unimportant. However, it will always be the order in which they were declared. This can be useful to the clever coder.


Structure of Numerically Indexed Array (called an array in javascript):


[
athing,
someotherthing
]

javascript syntax:


var myArray = [athing, someotherthing];

or:


var myArray = [];
myArray[0] = athing;
myArray[1] = someotherthing;

There are other ways.

There are no keys here other than the numerical references which arise simply by the order in which the items are listed or as they are assigned. 0 will always be first and the highest numbered one will always be last regardless of the order in which they were declared.


In javascript you can access the content of the associative array (object) like so:


alert(myObject.something);

or:


alert(myObject['something']);

Either of which will alert:

athing


In javascript you can access the content of the numerically indexed array (array) like so:


alert(myArray[0]);

Which will alert:

athing

In both types, if athing is a string, it will alert that string. If it is not a string, it will type convert it to a string in various ways, depending upon what it is. Alert does this because it can only alert a string. If you use it in a different way - say athing is a function, and you do for associative:


myObject.something();

or for numerically indexed:


myArray[0]();

it will execute the athing function.


Now in jQuery the:


$(document).ready(function() {
// do stuff here
});

Which can also be written other ways, executes not onload, unless the browser has no way jQuery knows about to determine document ready other than onload. In most cases though, jQuery can determine when the page has been parsed by the browser. This is true document ready for the purpose of manipulating the DOM. Images scripts and styles may or may not be loaded yet. If it were onload, all of these should be loaded. This can be crucial in certain cases and you might want to wait until onload for some things. In jQuery onload is:


$(window).load(function(){
// do stuff here
});

But whichever you use, whatever you do in the:

// do stuff here

section is in a function. Unless it is made accessible to the global scope and/or assigned to/associated with an element on the page, it cannot be accessed outside of that function.

The reason why we can access the selection_replace_with function of:


arr.editor_content_editor_rte

Is that:


$('#editor_content_editor_rte').rte({
width: 700,
height: 270,
controls_rte: rte_toolbar,
controls_html: html_toolbar
});

returns an associative array (a javascript object) with the id of the element (editor_content_editor_rte) as the key for this instance. This instance in this case is the full publicly available functionality of this particular editor. When it returned that we assigned it to the global variable:


window.arr

Anything owned by window is global. So now:


arr.editor_content_editor_rte.selection_replace_with

is a function on the page and:


parent.arr.editor_content_editor_rte.selection_replace_with

is a function on the page as accessed from a child of that page.

Valor Studios
06-20-2010, 02:34 PM
That explains alot. Instead of writing it the conventional way (i.e. in php $arr['editor_content_editor_rte']['selection_replace_with']['.....']), in Javascript we can write an array using the dot operator. I guess many language like C# or Actionscript use this method but I've never spent much time with them.

One more question if you don't mind. Can you explain why we didn't use var to create the variable. My understanding was that the var creates a global scope so variable becomes global and can be accessed by different functions. In this case we used window.arr. I'm guess that all the variables in Javascript are assigned in an array to the window object, correct?

jscheuer1
06-20-2010, 04:16 PM
A variable declared with the var keyword is in the scope it is declared in. On an HTML page, window is the owner of the global scope. This:


<script type="text/javascript">
$(document).ready(function() {

window.arr = $('#editor_content_editor_rte').rte({
width: 700,
height: 270,
controls_rte: rte_toolbar,
controls_html: html_toolbar
});

});

</script>

is equivalent to:


<script type="text/javascript">
var arr;
$(document).ready(function() {

arr = $('#editor_content_editor_rte').rte({
width: 700,
height: 270,
controls_rte: rte_toolbar,
controls_html: html_toolbar
});

});

</script>

But this is not equivalent:


<script type="text/javascript">
$(document).ready(function() {

var arr = $('#editor_content_editor_rte').rte({
width: 700,
height: 270,
controls_rte: rte_toolbar,
controls_html: html_toolbar
});

});

</script>

Here we've declared the variable in the scope of a function. It's only available in that function.

Valor Studios
06-20-2010, 04:25 PM
Thank you John. That helps alot. :)