In this tutorial we will be showing you how to create a simple Moai Cloud application that will change its content with input from the user, and also create a client program that will edit the application and print out the new content. This will require two separate lua files; first, the cloud application, and second, the client. We will break this tutorial up into those two sections.

The steps that our client and application will go through once it they finished are: the user will launch the script, the script will ask the user to input their name, after the user inputs their name the program will then send that data to the cloud application, the application will overwrite whatever information was there before with the new input, then the application will send a string back to the script which will then take that information and open a text box with the string contents and print that to a window. That being said, the first piece of this puzzle that will be constructed is the Cloud Application. Talk about the tutorial here!

Cloud Application

Before we get started, make sure that you have at least skimmed over our Moai Cloud documents (Getting Started, MongoDB, Lua Environment) to get familiar with Moai Cloud and MongoDB. Now to get started, we’ll need to make another web service (as we did in our previous Moai Cloud tutorial.) We can just use the Hello World Template, and once that’s been created, we’ll go into the resources and edit them. Go ahead and delete all the pre-placed Hello World code and replace it with the following. Don’t worry, we’ll go through it piece by piece.

function main(web, req)

   local params = web:params()
   local return_value = ""

   if( params.name ) then
        mongodb:update('names', {}, {name=params.name}, true, false)
        return_value = "Your name has been updated to:  " .. params.name
   else

   local cursor = mongodb:query('names', {})

        if( cursor:has_more() ) then
           local name_record = cursor:next()
           return_value = "You told us that your name is:  " .. name_record.name
        else
           return_value = "You haven't told us your name yet!"
        end
   end

   web:page(return_value, 200, 'OK')
end

First off, as was stated in the the "Getting started with Moai Cloud” documentation, our application must feature a function defined with “main()”.

main ( web, req ) 

Web is a Lua object containing various methods for managing replies to service requests, and req is a Lua table containing raw HTTP request headers.

local params = web:params()
local return_value = ""

Next, we will create two local variables; a table of “web:params()” called “params”, and a “return_value”, which we will use as a string when we return our messages. After that is where the main portion of our script comes into play.

if ( params.name ) then 

will check if we have received any input from the user; then,

mongodb:update('names', {}, {name=params.name}, true, false)
return_value = "Your name has been updated to:  " .. params.name

If there has been input, then mongodb will search for a table called “names”, and it will replace the first entry in this table with the params.name (our input from before). Now, if there isn’t a table already created, one will be automatically created on the fly for you. After this, the application will then print the string followed by the name you have just inserted into the table. Now, if we didn’t just pass through an argument, then the next bit will work instead.

local cursor = mongodb:query('names', {}) 

First we create a local cursor as a mongodb query (read about queries and cursors in the MongoDB Moai Cloud documentation)

if( cursor:has_more() ) then
     local name_record = cursor:next()
     return_value = "You told us that your name is:  " .. name_record.name

With that cursor we check to see if there is an entry in the table. If there is an entry, we create name_record to be that string, and then like before, we will return a string with the record. And finally, if there hasn’t ever been an entry in the table, we will return

return_value = You havent told us your name yet!

After all that has been determined, we will make our page display the return_value when a user accesses it. And that’s our cloud application! After deploying the application, we can click on the URL given to us on the Moai Cloud Dashboard and we will be taken to your application’s page:

Of course we haven’t given it a name yet, and it says as much. If you remember from the “Getting Started with Moai Cloud” documentation, you can manually submit request parameters by simply typing in the URL followed by a question mark, the argument type, an equals sign, then the value of the argument. So you can input the following: http://YOUR_URL?name=Beta User Entering that URL will then take you to our new, freshly updated application. And now, if you reload just the URL (without the “?name=Beta User”) you’ll get because we have already submitted a name to the table. Now that we have a working cloud application, it is time to create our client to take advantage of this application. This will be similar to our previous example from the Moai Cloud Basics tutorial, with the addition of user input.

Client

For our client, we will need it to do the following things; Open up a window, accept user input, send that input to the cloud, then receive input from the cloud and open a textbox with that information. We’ve already covered several times in our previous tutorials about how to open up a window and how to create a textbox, so I will just skip over those. One of the things we will need to create is a function that will encode input to the end of the URL, and then we will use that function with an httpGet (remember httpGet from our previous Cloud tutorial?) For our url encoding, we will use the encode function that is given on the Lua website (here); there's no reason to reinvent the wheel.

function urlEncode ( t )
     local s = ""
          for k,v in pairs ( t ) do
          s = s .. "&" .. urlEscape ( k ) .. "=" .. urlEscape ( v )
     end
          return string.sub ( s, 2 ) -- remove first '&'
end </pre>

<p>After we have that, it’s time to get down to business. After our constants and setup, this is the next bit of code that we will add.</p>
<pre class="brush:lua">io.write ("What is your name? ")
name = io.read ()
print ("Your name is " .. name )

function taskCallback ( task )
	print ( task:getString () )
	text = ( task:getString ())
	textbox:setString ( text )
	layer:insertProp ( textbox )
end
task = MOAIHttpTask.new ()
task:setCallback ( taskCallback )
task:httpGet ( MOAI_CLOUD_URL … “?" .. urlEncode ( { name = name } ))
The first chunk will take an input from our user and set that input to a variable called “name.” After that, we will print the name onto the debug screen. Now it should again look very familiar from our other cloud tutorial, with one major change. On the httpGet function call, instead of only putting the MOAI_CLOUD_URL in there, we are also adding a question mark after the URL, and then using our urlEncode function to add our user input and sent it up to our service. When all this is added in, this is what you should get when you run the program. and if we go to our URL, we will get With that, you have not only successfully created a cloud application that will take in variables given to it by a user, but will display those arguments, and on top of that create a client that will take advantage of this application. Listed below is the complete code for the client.
MOAI_CLOUD_URL = "YOUR_URL" MOAISim.openWindow ( "Textboxes", 320, 480 ) viewport = MOAIViewport.new () viewport:setScale ( 320, 480 ) viewport:setSize ( 320, 480 ) layer = MOAILayer2D.new () layer:setViewport ( viewport ) MOAISim.pushRenderPass ( layer ) --------------------------------------------------------------- function urlEncode ( t ) local s = "" for k,v in pairs ( t ) do s = s .. "&" .. urlEscape ( k ) .. "=" .. urlEscape ( v ) end return string.sub ( s, 2 ) -- remove first '&' end charcodes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .,:;!?()&/-' font = MOAIFont.new () font:loadFromTTF ( 'arialbd.ttf', charcodes, 16, 163 ) textbox = MOAITextBox.new () textbox:setFont ( font ) textbox:setTextSize ( font:getScale ()) textbox:setRect ( -160, -80, 160, 80 ) textbox:setYFlip ( true ) io.write ("What is your name? ") name = io.read () print ("Your name is " .. name ) function taskCallback ( task ) print ( task:getString () ) text = ( task:getString ()) textbox:setString ( text ) layer:insertProp ( textbox ) end task = MOAIHttpTask.new () task:setCallback ( taskCallback ) task:httpGet ( MOAI_CLOUD_URL .. "?" .. urlEncode ( { name = name } ))