7 Replies - 13256 Views - Last Post: 01 March 2011 - 08:13 PM

#1 jdiwnab   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 28-February 11

Wait for Javascript Event

Posted 28 February 2011 - 11:41 AM

After lots of searching for a solution, a friend persuaded me to post my question here.

I'm working on a personal project that involves a command-line like console. Currently, output is being printed nicely into the console window, and I'm getting text based input from the user in the form of dialog boxes. While not elegant, these get the job done in that they are blocking calls for input. I wanted to make it less annoying by providing a input line. As the user enters information, various events fire, and I can catch them.

The problem I have is the event based input field isn't directly compatible with the blocking dialog box. The usual recommendations I've found involve breaking the logic up with callbacks, where I would attach a new event to the input box, then add my new logic inside that. Unfortunately, that method wouldn't work in this situation, as it breaks up the control flow. For example, if I wanted to get input from inside a loop, event callbacks would force me out of the loop, or require global variables and crazy flags and more callbacks.

The other option that was recommended was using setTimeout and polling. But that is also non-blocking, and I can't figure out how to have it not wait in a very tight loop. Something like a tight loop that sleeps for a few milliseconds would probably work, but Javascript doesn't have a sleep function.

Below is a very minimal bit of code that tests what I need it to do. The button represents attempting to read input before there has been any input. I also tried calling read() recursively with a delay, but decided to try a dummy function because you can't seem to return a value if you use .delay or setTimeout().

<script type="text/javascript">
function print(value) {
	var lines = value.split("\n");
	for(var i=0; i<lines.length; i++) {
		if(i>0) document.getElementById("consoleWindow").appendChild(document.createElement("br"));
		document.getElementById("consoleWindow").appendChild(document.createTextNode(lines[i]));
	}
}

function wait() {
	//do nothing
}

function read() {
	var value = document.getElementById("consoleInputField").value;
	while (value=="") wait.delay(2000);
	document.getElementById("consoleInputField").value = "";
    return value;
}</script>
<!-- SNIP -->
<div class="consoleWindow" id="consoleWindow"></div>
<div class="consoleInput" id="consoleInput"><input type="text" id="consoleInputField" style="width: 100%;" onchange="var temp = read(); print(temp+'\n');"></input></div>
<input type="button" name="read" value="read" onclick="var temp = read(); print(temp+'\n');" />


Is This A Good Question/Topic? 0
  • +

Replies To: Wait for Javascript Event

#2 BetaWar   User is offline

  • #include "soul.h"
  • member icon

Reputation: 1533
  • View blog
  • Posts: 8,326
  • Joined: 07-September 06

Re: Wait for Javascript Event

Posted 28 February 2011 - 12:17 PM

Why not just add an event listener to the console input box which looks for the enter character (key code 13) and when it finds one then calls the approperiate function?

That way you don't have to worry about all the intermediate steps and you don't have to poll the input multiple times, you just wait for the browser to notice that a key has been pressed and then check that key code against enter (normally a sign of the end of a command) and go from there.

Hopefully that makes sense.
Was This Post Helpful? 0
  • +
  • -

#3 jdiwnab   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 28-February 11

Re: Wait for Javascript Event

Posted 28 February 2011 - 12:55 PM

Thanks for the reply.

The problem with just listening for the event is resuming where it left off. In this project, I'm executing code that wasn't originally javascript, and I would like to execute it as close to the original as possible, particularly so that it can be a general as possible.

As a silly psudocode example, I have something like:
for(var i=0; i<10; i++) {
  var temp = prompt("Enter a value");
  alert("you entered" + temp);
}


which I would like to rewrite as:
for(var i=0; i<10; i++) {
  print("Enter a value\n");
  var temp = read();
  print("you entered" + temp);
}


If I just setup an event listener, how would I re-enter my loop? I could have the read() function add an event listener and save off as a global variable what line I was on. On the event, I could re-call my running function, and goto where I left off, but many variables would still be un-set. If I broke out the stuff after a 'read()' into a new function, I would also loose variables and state.

Any other recommendations?

Thank you

jdiwnab
Was This Post Helpful? 0
  • +
  • -

#4 BetaWar   User is offline

  • #include "soul.h"
  • member icon

Reputation: 1533
  • View blog
  • Posts: 8,326
  • Joined: 07-September 06

Re: Wait for Javascript Event

Posted 28 February 2011 - 04:09 PM

Let me see if I have this correct: You are wanting to write a language on top of Javascript?

In that case, yes you have to worry about your state and you will have to worry about different scopes. Given that the language would be written in Javascript you would need to write any "built in" functionality in Javascript or it wouldn't know what to do with the given function call.

That said, you could want to have an object/ array which would be responsible for the current scope (and any larger scopes), then when you do a function call you would need to open a new scope and start writing variables into it (instead of other scopes, unless they were global variables).

For instance, if you have a setup like so:
Global
  Class X
    Function Y



If you were to call function Y of class X there would be 3 levels of scope (Global, Class, and Function). If in function Y you ask for variable z then you should first check the smallest scope and work your way outwards (start with Function, then go to Class, and then to Global) as the variable isn't found. Another thing you have to think about is that loops normally have their own scope as well, however if you declare a variable in a lower scope that has the same name as one in a higher scope you won't be able to access the variable in the higher scope until you have exited the current scope (as it will be shadowed).

There is an easier solution to what you are attempting (assuming you are in fact attempting to write a programming language on top of JS), and that is to create a "compiler" which takes the code form your language and spits out Javascript code which will do the same thing. This takes a lot of the work off your hands and puts it on Javascript instead (for instance you don't have to worry about anything more on scoping than getting the variables declared in the appropriate way). If this sounds more appealing to you then I am going to suggest you take a look at other things out there such as coffeescript, which is a "compiled" language built on Javascript.

Hopefully that makes some sense.
Was This Post Helpful? 1
  • +
  • -

#5 jdiwnab   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 28-February 11

Re: Wait for Javascript Event

Posted 28 February 2011 - 04:46 PM

View PostBetaWar, on 28 February 2011 - 04:09 PM, said:

There is an easier solution to what you are attempting (assuming you are in fact attempting to write a programming language on top of JS), and that is to create a "compiler" which takes the code form your language and spits out Javascript code which will do the same thing. This takes a lot of the work off your hands and puts it on Javascript instead (for instance you don't have to worry about anything more on scoping than getting the variables declared in the appropriate way). If this sounds more appealing to you then I am going to suggest you take a look at other things out there such as coffeescript, which is a "compiled" language built on Javascript.

Hopefully that makes some sense.


I am working on making a compiler that output javascript (in particular, one also written in javascript). The particular problem is finding equivalent code for things like reading in from the command line. Currently, using javascript 'prompt' dialog boxes, it works out, as I can just do a drop in replacement. I was thinking that I could do the same, only with a function that would handle the reading from the input line.

I looked into coffeescript, and it is interesting. I am not fond of the language itself, but it is similar in what I am hoping to accomplish in many respects. Looking through their references, I don't see anything about reading input (not surprised), but I did see a helper function 'print()' in some of the produced JS code, and I couldn't find any notes on that, even in their grammar definitions.

Most things I am working on implementing for the language have a one-to-one correspondence with something in JS, which is not surprising. Just that this one bit, reading in of input, is throwing me way off.

The input code equlivant of what is above:
for i = 0 to 10
  print "Enter a value\n"
  read temp
  print "You entered" + temp
next


I have my compiler get turn that into a JS for loop with alert()'s and prompt()'s, but I would like to make it more user (and browser) friendly than alerts and prompts. I can handle the prints easy enough, but the read is being difficult.

Thank you for all your suggestions!

jdiwnab
Was This Post Helpful? 0
  • +
  • -

#6 BetaWar   User is offline

  • #include "soul.h"
  • member icon

Reputation: 1533
  • View blog
  • Posts: 8,326
  • Joined: 07-September 06

Re: Wait for Javascript Event

Posted 01 March 2011 - 10:08 AM

For the reads you could just start listening to keyboard input, see if the key pressed is a readable character, if so add it to a string, otherwise don't. Also check if it is an enter (end of input in most cases) or a backspace (at which point you need to remove the last character from the input).

Here is some example code of how to do this:
<body></body>
<script>
var inputString = "";
window.onkeypress = function(e){
  e = e || window.event;
  e.returnValue = false;
  e.preventDefault();
  var char = e.keyCode;
  if(char == 13){ // enter
    // do something
    return;
  }
  if(char >= 32 && char <= 126){ // is a readable character
    inputString += String.fromCharCode(char);
  }
  else if(char == 8){ // backspace
    // remove a character from the input
  }
  document.body.innerHTML = inputString;
}

</script>


NOTE - I haven't filled in everything.
Was This Post Helpful? 0
  • +
  • -

#7 jdiwnab   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 28-February 11

Re: Wait for Javascript Event

Posted 01 March 2011 - 11:37 AM

Maybe I'm missing something, or maybe I'm not explaining things well.

I can figure out how to respond to events enough to put the entered string somewhere, such as in input buffer to be read. The problem is that a normal READ, or, as in C++ a cin >>, or C's scanf, the function is blocking until get gets a line of input.

So, I could setup events to grab the input from a field, and put them into an input buffer to be read later, but if the READ function comes and the buffer is empty, it should wait until I put something in there. And this waiting is what has been giving me difficulties. Trying to implement some equivalent bit of JS code that would block until there is something to read.

In the original demo code I pasted in my first post, I somewhat demonstrate this problem. I can setup events that, if there is data, it will do something with it, I.E. print it out, while if I try and read, and there is nothing there yet, it will lock up in a tight loop, or else run past it, not waiting for input.

So, I can't figure out what kind of JS code I could generate from my compiler that would be able to mimic the 'READ' command. Everything I can think of would either break the control flow by splitting the function into pre-read, reading events, and post-read functions, or get caught in a tight loop that would prevent the user from entering anything.

I hope this is clearer.

Thank you

jdiwnab
Was This Post Helpful? 0
  • +
  • -

#8 BetaWar   User is offline

  • #include "soul.h"
  • member icon

Reputation: 1533
  • View blog
  • Posts: 8,326
  • Joined: 07-September 06

Re: Wait for Javascript Event

Posted 01 March 2011 - 08:13 PM

Ah, okay. Now I understand.

Sadly, there is no way (at this point) to block, sleep, or wait in Javascript.

The only way to accomplish what you are attempting to do is to split up the function and do something like so:

<body></body>

<script>
function read(callback){
  var inputString = "";
  var cb = callback;
  var args = arguments;
  window.onkeypress = function(e){
    e = e || window.event;
    e.returnValue = false;
    e.preventDefault();
    var char = e.keyCode;
    if(char == 13){ // enter
      window.onkeypress = null;
      args[0] = inputString;
      cb.apply(window, args);
      return;
    }
    if(char >= 32 && char <= 126){ // is a readable character
      inputString += String.fromCharCode(char);
    }
    else if(char == 8){ // backspace
      // remove a character from the input
    }
    document.body.innerHTML = inputString;
  };
}


function start(){
  var x = 42;
  alert(x);
  read(end, x); // could take any number of parameters you want to pass between function sections
}
function end(input, x){
  alert(input);
  alert(x);
}
start();
</script>


Hopefully that helps.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1