Jump to content

Some MOAP Tricks I'm learning..


Love Zhaoying
 Share

You are about to reply to a thread that has been inactive for 372 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

One of the things I needed to doin my MOAP implementation, was "send back a response" to the MOAP page from a "POST" call, and do something with the response.

Adding the highlighted part below to the function allowed me to get and process the "POST" response body.  (Function "addtxt()" just writes the response to a textarea).

This javascript function is included when the page is initially built by LSL.

function SendToLSL() {
  if (input.value.trim().length!=0) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {            // Setup a callback
        if (this.readyState==4 && this.status==200)  // Only if ready and OK
            addtxt(this.responseText);                           // Add the response to my textarea
    };    

    xhttp.open(\"POST\",\"GetSomeData\", true);
    xhttp.send(input.value.trim());
    input.value = '';
  }

I did not put the code in a "code block" so I could highlight it, sorry.

I am a programmer, but a "true n00b" at "Web Programming" - so believe it or not, escaping the "&&" to "&&" was the hardest part!

 

 

Link to comment
Share on other sites

6 minutes ago, Quistess Alpha said:

Interesting, do you need to do that even if the javascript is within CDATA metatags?

I'm not using those tags, here is the LSL that generates the "main HTML Body" (taken from your example? I did not find it in the thread just now):

generateMainBody(){

    gsMainBody  = "
<html xmlns=\"http://www.w3.org/1999/xhtml\">
<style> 
div.log {width:auto;border:2px solid black;height:calc(100vh - 75px);}
div.fixed {position:fixed;bottom:10px;} </style>
<body>
<div class='log'><textarea id='txtlog' style='font-size:28px;width:100%;max-width:100%;height:calc(100vh - 75px);'/></div>
<div class='fixed'><button onclick=\"SendToLSL()\" style='font-size:28px;'>Send</button><input id='cmdLine' style='font-size:28px;height:35px;' size='50'></input><button onclick=\"cleartxt()\" style='font-size:28px;'>Clear</button></div>
</body>
<script>
var input = document.getElementById('cmdLine');
var txtArea = document.getElementById('txtlog');
function addtxt(newvalue){
  txtArea.scrollTop = txtArea.scrollHeight;
  txtArea.value += newvalue + '\\r\\n'; 
}
input.addEventListener('keypress', function(event) {
  if (event.key === 'Enter') {
    event.preventDefault();
    SendToLSL();
  }
});
function focus(){input.focus(); input.select();}
function cleartxt(){txtArea.value = '';focus();}
function SendToLSL() {
  if (input.value.trim().length!=0) {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState==4 &#038;&#038; this.status==200)
            addtxt(this.responseText);
    };    
    xhttp.open(\"POST\",\"GetSomeData\", true);
    xhttp.send(input.value.trim());
    input.value = '';
  }
} 
focus();
</script>
</html>";

}

..but don't get me wrong, I had to use my Google skills to find the XMLHttpRequest response handling for "POST"! 

Just getting it to WORK was a challenge until I realized the error really did mean it was the "&"!

 

 

Edited by Love Zhaoying
Link to comment
Share on other sites

2 minutes ago, Love Zhaoying said:

I'm not using those tags,

Also not a web programmer, but those tags seem to fix a lot of 'funny character' problems without having to escape them, or at least, I know it works for '>' and '<'.

so a script segment would look like:

<script>
//<![CDATA[
  /*Some javascript stuff here*/
//]]>
</script>

I've made it a habit to add those even when it's not "required" but maybe I hadn't picked up that trick when I posted the example you worked off of?

Also, I always copy them from other script snippets, they are not easy to remember.

  • Thanks 1
Link to comment
Share on other sites

@Quistess Alpha - while I've got your attention.. this morning while I was testing the script - the media page (I will tire or writing MOAP, it feels silly) worked for "clicks" but would not let me type any input!  Even with previous versions of the script.

I finally had to reboot my PC - then it worked fine. (Maybe just exiting / re-running the SL viewer would have been enough..)

Have you seen anything like this - where the pages just "don't work" for unexplained reasons, then they "do work"?

 

Link to comment
Share on other sites

6 minutes ago, Love Zhaoying said:

Have you seen anything like this - where the pages just "don't work" for unexplained reasons, then they "do work"?

That's getting into the weeds, but I have noticed my backspace key doesn't work in SL's web-browser-on-a-prim. Media stuff opens you up to a lot more 'platform dependent behavior' than usual: the user's OS and current state of libraries etc. . . so, not exactly, but I'm not surprised.

Edited by Quistess Alpha
  • Thanks 1
Link to comment
Share on other sites

Looks like I'll have to implement a timed poll for GET to get updates (this is basically a console). I've come to terms with that since it will follow the same basic pattern as POST.  I'll post the approach tomorrow when I'm "done".

The goal is to NOT reload the page, but: 

1) Send a POST to the script when user enters data, and 

2) Use a "long polling GET" to get updates from the script for a "log" in a scrolling textarea. Easy peasy, the examples I started with for this part were just unnecessarily complicated.

 

Link to comment
Share on other sites

Ok, I ended up using two XMLHTTPRequest Objects: 1 for "POST", and 1 for "Polling".

The relevant code is below. 

I made the "GET" XMLHTTPRequest instance "global" since it is always polling, and the "POST" XMLHTTPRequest instance local to the "SendToLSL()" function.

I left out any code not relevant to the GET / POST.

The "POST" waits for a response (in this use-case, it will be an echo of the command entered).

The "GET" is always looking for any data.

So far, this works pretty well..

Original inspirations were:

1) In Innula's and Quistess's thread (see OP for link), and 

2) In the Wiki here: https://wiki.secondlife.com/wiki/User:Becky_Pippen/Shared_Media_LSL_Recipes#Reverse_Ajax_-_Long-polling_the_HTTP-in_server.2C_chat_logger_example.  That example was overly complex for what I needed, and appears to pre-date some of the newer restrictions and conventions.

// Javascript

const debug = false;
var phttp = new XMLHttpRequest();	// Global XMLHttpRequest - For polling changes from LSL script - GET
phttp.timeout = 20000; 				// 20 second timeout
phttp.ontimeout = function () { 	// On timeout, starts polling again
    if(debug)addtxt('timeout');		// Add debugging info to textarea
    startpoll(); 					// Open a new GET - start polling LSL script
}

phttp.onreadystatechange = function() {	// Handle changes in GET request state
    if (this.readyState==4 &#038;&#038; this.status==200) {	// If success
        addtxt(this.responseText);		// Add response to textarea
        setTimeout('startpoll()',500);	// Start a new poll after 0.5 seconds
        if (debug) addtxt('Added timed poll for 500');
    }
};    

function SendToLSL() {				// Called when users clicks "SEND" button or ENTER key from field to send
  if (input.value.trim().length!=0) {	// Only send if something was entered
    var xhttp = new XMLHttpRequest();	// XMLHttpRequest - For sending changes to LSL script - POST
    xhttp.onreadystatechange = function() {	// Wait for a change 
        if (this.readyState==4 &#038;&#038; this.status==200) {	// Add the POST response to textarea
            addtxt(this.responseText);
        }
    };    
    xhttp.open(\"POST\",\"GetSomeData\", true);	// POST command
    xhttp.send(input.value.trim());		// Send POST to LSL script
    input.value = '';					// Clear input field
  }
} 
function startpoll() {				// Called to initiate a new GET poll
    if (debug) addtxt('polling');	// Add debug info to textarea
    phttp.open(\"GET\",\"GetSomeData\", true);	// GET command
    phttp.send();					// Send GET to LSL script
}    

// Startup code
addtxt('Initialized.');    	// Add to textarea
focus();					// Set focus to input field
setTimeout('startpoll()',500);	// Start polling after 0.5 seconds

 

Link to comment
Share on other sites

Today I Learned:  

From a certain point of view, for my use-case there's not really a reason to use MOAP.  

If I just say the URL in chat instead of setting my HUD to MOAP, clicking the URL opens a nice window that works perfectly (so far.. I probably just jinxed it).

Anyway, now that I know the option is there, I can more easily design the whole thing for non-MOAP. 

The "in-viewer browser" version looks a lot better, is more readable, etc. than the MOAP version.

So the project becomes: not using "media-on-a-prim" or "shared media" but, "create a simple website/form from LSL that has NO external dependencies".

Seems legit on the surface.  Perhaps I'll keep going on this thread if I find "browser vs. MOAP" differences and issues, or make a separate one.

Speaking of "differences between MOAP and in-viewer browser":

    I was starting to try "cookies" from the MOAP version and it did not work. 

    It will be interesting to find out if cookies work from the "in-viewer browser", or if I need to open the website in Chrome.  Any thoughts?

 

Link to comment
Share on other sites

1 hour ago, Love Zhaoying said:

Any thoughts?

Goes beyond what I have specific knowledge in, but AFAIK, the 'in-viewer browser' and MOAP should be essentially the same save for one looking like it's in-world and the other being a pop-up. just posting a link in chat lets the user decide whether to open in the 'linden browser' or their preffered OS browser (right-click -> open in internal/external browser) (external browser is also great for people with dual monitors...).

For links posted in chat, if you surround the link in '[]'s you can add nicer-looking text:

"[http://www.duckduckgo.com Do the duck!]" when said in local becomes: Do the duck!

Edited by Quistess Alpha
'dial'-> dual. why would I ever use my old CRT for SL?. . .
  • Thanks 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 372 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...