Call shared action from custom js file

Workarounds and usability notes.

Call shared action from custom js file

Postby John Robin Dove » Fri Sep 11, 2015 9:14 am

Hi Clifton,

As I have far too much code to stuff into Toolbook shared actions I am writing my own functions to be used via 'Execute Script', as you suggested. As you know, these are stored in b.js and are readily available. It's slow work but I guess it's the only solution for me as otherwise Toolbook says: 'Script too large to compile.' The problematical part is using variables. If my functions use global variables these must be sent as local variables to each function and to modify a variable I have to use pgTBObjSet() to send a user value to an object which then updates the global variable.

This all works fine but sometimes there are some pretty big string variables flying around. I would like to leave some of my functions as Toolbook Shared Actions. Is it possible to call a Toolbook Shared Action directly from the code in b.js? I've been looking at the axf file but it looks pretty complicated!

PS. Thanks for the latest Powerpac and the constant updates.
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: Call shared action from custom js file

Postby Clifton » Fri Sep 11, 2015 1:34 pm

You may want to consider using the browser storage via cookies. The PowerPac has builtin cookie functions which enable you to target the browser storage object (HTML 5 browsers only) instead of disk files which are usually used for cookies. This way you can use that as your global data pool and both the actions system and the extra functions you are writing can access the same pool via PowerPac cookie functions.

Remember: the browser storage object is persistent when you exit your application, so you will need to reinitialize it to prevent issues from a previous session. However, it can store just about any data types (e.g.: strings; arrays, objects, etc.). Its size limiatations are relatively high so you shouldn't run into any problems in the vast majority of cases, especially if you clean up after each session.

I've learned that it is just not practical to attempt accessing global variables between Actions and JavaScript functions. It is better to find other ways to exchange data. Using properties of objects with the PowerPac userProperty() function is a good non-persistent way (cleared on page navigation) to have shared storage of data. Cookies (as mentioned above) is another. Finally, another way is to create your own storage pool using the window object.
Example:
    window.myStorage = { };
    window.myStorage.audios = [ "help.mp3", "teacher.mp3", "student.mp3" ];
    (The above example initializes a window storage object and then creates an array called "audios" which defines a list of mp3's that may be accessed by your application at either the function or Action Editor system level.)

    To retrieve this data at the Actions level, you would use exeJavascriptDirect() to retrieve the data and store it in a temporary Actions variable that can be used for the duration of the action sequence. If the action sequence modifies the data, you will have to use the same function to update the global pool.

    Bottom line, I would recommend experimenting with the browser storage object and using PowerPac's cookie functions to pass the data around. It's probably a little less complicated and more reliable, especially with complex strings that contain carriage returns, etc. You may even find that no one single method is best but that a combination of methods is the best approach.
Final (but important) note: If students are pretty savvy, remember they can access your stored data using any browser debugging tools. Therefore, any sensitive data should be encrypted using pgString Encrypt() before storing it in a persistent or shared data pool. This is true whether you use any of these methods or not.
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: Call shared action from custom js file

Postby John Robin Dove » Sat Sep 12, 2015 5:06 am

Thank you for your detailed reply. I'm not sure that I understand all of it.

So I can use cookies to replace global variables? I imagine that the cookie data can be converted back to global variables for the Actions environment but how would I access them in the js file? Could they be accessed as global variables in the js file?

I have been thinking about using cookies for a while because I think I should divide my 2 page book into two separate books and in this case the shared global variables would have to be passed from one to the other. I think two separate books would probably load better. At the moment when the second page loads some objects display as white rectangles until the loading is over.

Another idea I had: instead of using cookies for all the global variables like userName, className, exerciseName etc. most of these could be stored in a file in the user's personal folder on the server. userName would have to be stored in a cookie but all the rest could be in the file and accessed via XMLHttpRequest? Would this work and would it be safer than using cookies only?

I'm a bit disappointed with my progress so far. Over a year and I still haven't finished the first module (creating and using a video exercise). Admittedly it is by far the most complicated bit and I think most of the rest of the program will be easier to convert. It's a bit frustrating because I know it can all be done. My DHTML program is identical to the the VB.NET version and it functions just as well if not better.

Could you take a look at this please? It's a js file version of a TB shared action. I can't get the js file version to work. I've simplified it for testing purposes.
Code: Select all
function tbfunction_getTextlines(objectInfo) {
var textLines = [];
textLines = tbfunction_pgSplitToArray(objectInfo, crlf, true);
//textLines = tbfunction_pgSplitToArray(objectInfo, "crlf", true);
//textLines = tbfunction_pgSplitToArray(objectInfo, "\r\l", true);
var total = textLines[0];
alert(total);
  for (i = 1; i < total + 1; i++) {
  alert(i + " " + textLines[i]);
  }

};
I just need to create an array containing textlines. This was easier in the Actions system because I could use textline x of test and textlines x to y of text.
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: Call shared action from custom js file

Postby Clifton » Sat Sep 12, 2015 8:38 am

For starters, the task this seems to be trying to perform is already provided by:
pgSort_Shuffle()
The function takes a wide variety of data types and converts them to output formats needed by the application. In the process it can optionally strip empty lines, and/or sort and shuffle the data. You can easily use it to convert textlines to an array.

Regarding your code. It seems to be failing at the input. You must input a string to convert. I'm not sure what [objectInfo] is but if it is an object name, then the function will just return a single index array which contains the name of the field object. In addition, to split by a carriage return, you should use one of the following when writing a separate js function:
Use this "\n" including the quotes.
Or use this "/\n|\r/" including the quotes.

Finally, your loop is failing because your array is either invalid or the function failed to convert the string.
To get the textlines from a named field in a separate js file use:
objectInfo = tbfunction_pgTBObjGet( "name of field", "text" )
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: Call shared action from custom js file

Postby John Robin Dove » Sat Sep 12, 2015 10:01 am

Thanks Clifton,

Obviously pgSort_Shuffle() does exactly what I need! Actually, despite its name, objectInfo is just a list of textlines separated by carriage returns. I had guessed that the problem was my formulation of the carriage return and of course both the formulations you suggest do the trick.

On the subject of cookies etc. Any thoughts about my previous remark?

Another idea I had: instead of using cookies for all the global variables like userName, className, exerciseName etc. most of these could be stored in a file in the user's personal folder on the server. userName would have to be stored in a cookie but all the rest could be in the file and accessed via XMLHttpRequest? Would this work and would it be safer than using cookies only?
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: Call shared action from custom js file

Postby Clifton » Sat Sep 12, 2015 2:55 pm

Using an XML file to store information is not very secure unless the values are encrypted. However, it is a good way to quickly retrieve large amounts of data from a server and parse it into variables, etc.

Whether using and XML or cookies, you should still consider how sensitive data is being protected from prying eyes ... not necessarily hackers, but the user himself if he wants to try and improve his performance on some part of the course.

Using pgStringEncrypt() is a nice way to keep things protected if this is a concern. We recently had to use this function extensively to encrypt test question results that were stored in global variables and then emailed to an administrator when the student finished the lesson. When the email was compiled at the end of the course, the variables used to store the data was decrypted and then sent to the appropriate address by the server.
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: Call shared action from custom js file

Postby John Robin Dove » Mon Sep 14, 2015 4:02 am

Hi Clifton,

Yes I realize that all users are potential hackers. This is why all results in my previous version are protected by encryption. However I am amazed at the apparent lack of protection on a web server (and worried by it).

Are you saying that despite obfuscation someone can:

1) identify the type and path of the file containing results.
2) download it
3) modify and upload it

???
What about .htaccess? Would it make any difference? I suppose HTTPS is out of the question?
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: Call shared action from custom js file

Postby Clifton » Mon Sep 14, 2015 6:26 am

I'm only saying that once you read a file into global variables, then all the information is easily examined in a browser debugger tool. All the major browers have these tools and Firefox makes it especially easy to view web page variables and object properties. Its at that level that some discreet encryption would need to be maintained so students would not be able to cheat rather than learn from your courses.

ToolBook does a pretty good job of making some of this challenging, but the PowerPac's encryption function can potentially up the security of student data.
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: Call shared action from custom js file

Postby John Robin Dove » Mon Sep 14, 2015 1:56 pm

Thanks for your reply. So I must make sure to use encryption after accessing data from files and decryption when writing files which include data from global variables or something like that.

So I am correct in thinking that to download and upload files to my server the user would have to be a well above-average hacker? I sincerely hope so!
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 4 guests

cron