Moxie.Build Keeps it Simple
The full stack in one app, delivered by one company.
Coding with the MOX server side scripting language is concise, well structured, and keeps your focus on the data. Use Moxie.Build in your company to pull together resources, centralize data, customize business workflows, and act as a highly accessible web portal for staff and customers alike.
Just a simple form with one Ajax calculated field.
Although the MOX syntax pays heritage to BASIC, it includes modern features such as Try/Catch and Multiple Return Values from Functions. MOX encourages easy to understand step-by-step processing, and comes without language features that are typically abused and make code harder to maintain. Security is built right in; all user data is sanitized before the developer ever sees it.
Rem 'Flow Control: Pulls data from incoming web browser request and decides where to go [Pull] Req.IsGet ajCalc If ajCalc : AjaxReply : Form.Ajax.Calc ElseIf Req.IsGet : Form.Build Else : Form.Proc End If EndRem Method Form.Build() Rem 'Fetch or create our Person fields depending on if we have a valid user logged in If ($SessionIsBad) NewFields "MemTab.Person.", "FirstName LastName" Else Try LoadRecord "MemTab.Person", ($SessionUser) KeepFields "MemTab.Person.", "FirstName LastName" Catch HtmlErr "Oh my! it looks like we lost you somehow." Error "Could not load logged in user" 'Sends admin notifications and exits proc End Try End If EndRem Rem 'Create some extra fields for the demo and customize the form NewFields "Demo.", "Apples Oranges Fruit" GetFieldDefs 'Fetch db defenitions for db fields, creates blank defs for non-db fields WorkWith "Demo.Apples#" Set "Label", "`Apples?" Set "Attr", ("`[!] 0, 1, 2, 3, 4, 5, 6, 7, 8, 9" & $I & "[Ajax] FruitCount, ?ajCalc=y") WorkWith "Demo.Oranges#" Set "Label", "`Oranges?" Set "Attr", ("`[!] 0, 1, 2, 3, 4, 5, 6, 7, 8, 9" & $I & "[Ajax] FruitCount, ?ajCalc=y") WorkWith "Demo.Fruit#" Set "Label", "`Total Fruit" Set "Attr", "`[R]" End WorkWith 'Set up our Ajax destination inside of Demo.Fruit Set "Demo.Fruit", "0" EndRem 'Put it on the page, in our FruitDemo Template Insertion Point HtmlForm "FruitDemo", " Do Something", "" End Method Method Form.Ajax.Calc() [Pull] Demo.Apples Demo.Oranges Html (Demo.Apples + Demo.Oranges) End Method Function Form.Fruit.Total(pFirstName, pLastName, pApples, pOranges) If pApples == 0 : And pOranges == 0 Return "&warning", "Oops, it looks like you didn't select any fruit to share with us!" Else Return "&success", ("Thank you " & pFirstName && pLastName & "," & _ " for sending us " & pApples & " Apples " & _ " and " & pOranges & " Oranges.") End If End Function Method Form.Proc() Rem 'Fetch our incomming form data [Pull] "Request", "MemTab.Person.", "FirstName LastName" [Pull] "Request", "Demo.", "Apples Oranges" EndRem 'Call a processing Function that has four input parameters and two return values [New] AlertClass, UserMessage = Form.Fruit.Total FirstName, LastName, Apples, Oranges HtmlAlert "FruitDemo", AlertClass, UserMessage 'Display Alert Form.Build 'Display Form again End Method
For comparison only, here is an example of the same form being implemented with PHP, instead of using MOX in Moxie.Build. This source is about twice as large, and less modular, than the MOX equivalent.
//Ajax response if(isset($_GET['ajax'])){ //sanitize the form fields $oranges = intval(filter_input(INPUT_POST | INPUT_GET, 'Oranges', FILTER_SANITIZE_SPECIAL_CHARS)); $apples = intval(filter_input(INPUT_POST | INPUT_GET, 'Apples', FILTER_SANITIZE_SPECIAL_CHARS)); //add them echo $apples + $oranges ; } else { $firstname = ""; $lastname = ""; //normal request respond as page //check if user is logged in if($_SESSION['logged_in']){ try { //connect to the database $db = new PDO("mysql:host=localhost;dbname=mysql", "moxiedb", "m0xi3" ); //get firstname and lastname from the user, using a prepared statement to avoid sql injections :) $stmt = $dbh->prepare("SELECT firstname,lastname FROM users WHERE id= :user_id"); $stmt->bindParam(':user_id', $_SESSION['user_id'], PDO::PARAM_INT); $stmt->execute(); $result = stmt->fetchAll(); foreach($result as $row) { $firstname = $row['firstname']; $lastname = $row['lastname']; } $dbh=null; } catch(PDOException $e) { echo $e->getMessage(); } } else { //otherwise use $_POST if it exists yet and sanitize the inputs we were given if(isset($_POST['MemTab.Person.FirstName']){ $firstname = filter_input(INPUT_POST | INPUT_GET, 'MemTab.Person.FirstName', FILTER_SANITIZE_SPECIAL_CHARS); } if(isset($_POST['MemTab.Person.LastName']){ $firstname = filter_input(INPUT_POST | INPUT_GET, 'MemTab.Person.LastName', FILTER_SANITIZE_SPECIAL_CHARS) } } //decide on the dialog to use and display their name if appropriate if(isset($_POST['MemTab.Person.FirstName']) && ($_POST['Demo.Apples'] != "0" || $_POST['Demo.Oranges'] != "0")){ ?> <div class="alert alert-success"> Thank you if($firstname != ''){ echo ' '. $firstname; } if($lastname != ''){ echo ' '. $lastname; }?> , for sending us echo $_POST['Demo.Apples']; ?> Apples and echo $_POST['Demo.Oranges']; ?> Oranges.</div> <?php } else if(isset($_POST['MemTabPersonFirstName']) && ($_POST['Demo.Apples'] == "0" || $_POST['Demo.Oranges'] == "0"){ ?> <div class="alert alert-warning"> Oops, it looks like you didn\'t select any fruit to share with us! </div> <?php } ?> <script> $(document).ready(function($){ $('form').submit(function(E){ E.preventDefault(); $.post({ Oranges: $("#DemoOranges").val(), Apples: $("#DemoApples").val() }, function(string){ $("#FruitCount").text(string); }); }); }); </script> <form role="form" class="form-horizontal" action="" method="post"> <div class="form-group"><label for="MemTabPersonFirstname" class="col-lg-2 control-label">First Name</label> <div class="col-lg-8"><input class="form-control" name="MemTab.Person.Firstname" id="MemTabPersonFirstname" accesskey="f" value="Jordan" type="text"></div> <span class="help-block col-lg-2"></span> </div> <div class="form-group"><label for="MemTabPersonLastname" class="col-lg-2 control-label">Last Name</label> <div class="col-lg-8"><input class="form-control" name="MemTab.Person.Lastname" id="MemTabPersonLastname" accesskey="l" value="Evans" type="text"></div> <span class="help-block col-lg-2"></span> </div> <div class="form-group"><label for="DemoApples" class="col-lg-2 control-label">Apples?</label> <div class="col-lg-8"><select class="form-control" name="Demo.Apples" id="DemoApples" accesskey="a" onchange="mAjax('FruitCount', '?ajCalc=y', getFieldsForm25E72064())"> <option value="0">0 </option><option value="1">1 </option><option value="2">2 </option><option value="3">3 </option><option value="4">4 </option><option value="5">5 </option><option value="6">6 </option><option value="7">7 </option><option value="8">8 </option><option value="9">9 </option></select></div> <span class="help-block col-lg-2"></span> </div> <div class="form-group"><label for="DemoOranges" class="col-lg-2 control-label">Oranges?</label> <div class="col-lg-8"><select class="form-control" name="Demo.Oranges" id="DemoOranges" accesskey="o" onchange="mAjax('FruitCount', '?ajCalc=y', getFieldsForm25E72064())"> <option value="0">0 </option><option value="1">1 </option><option value="2">2 </option><option value="3">3 </option><option value="4">4 </option><option value="5">5 </option><option value="6">6 </option><option value="7">7 </option><option value="8">8 </option><option value="9">9 </option></select></div> <span class="help-block col-lg-2"></span> </div> <div class="form-group"><label for="DemoFruit" class="col-lg-2 control-label">Total Fruit</label> <div class="col-lg-8"><span class="help-block"><span id="FruitCount">0</span></span></div> <span class="help-block col-lg-2"></span> </div> <div class="form-group"><div class="col-lg-12"><button type="submit" class="btn btn-default" id='submitform' name="Form25E72064Submit" accesskey="d"><span class="glyphicon glyphicon-cog"></span> Do Something</button></div></div> </form> <?php } ?>
For comparison only, here is an example of the same form being implemented with Node.js, instead of using MOX in Moxie.Build. This source is about twice as large as the MOX equivalent.
/****** App.js ******/ var express = require('express'); var session = require('client-sessions'); var app = express(); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.use(express.logger('dev')); //setup databse var mongoose = require( 'mongoose' ); var Schema = mongoose.Schema; var User = new Schema({ email : String, firstname : String, lastname : String }); mongoose.model( 'User', User ); mongoose.connect( 'mongodb://localhost/moxiedb' ); //sets up sessions app.use(session({ cookieName: 'session', secret: 'OAE9DHdjAVhzhJ7ksO4LY9tr8Xo458af', duration: 30 * 60 * 1000, activeDuration: 5 * 60 * 1000, })); //display main page app.get('/', function(req, res){ if (req.session && req.session.user) { User.findOne({ email: req.session.user.email }, function (err, user) { if(!user){ res.render('index'); } else { res.render('index', { user: user }); } } } else { res.render('index'); } }); //handles ajax request app.get('/addfruit', function(req, res){ var result = parseInt(req.query.apples) + parse(req.query.oranges); res.send(result); }); //form submits to this app.post('/submit', function(req, res){ res.render('index', { firstname: req.body.firstname, lastname: req.body.lastname, apples: req.body.apples, orange: req.body.oranges }); }); app.listen(8001); /**** index.jade Note: the jade templating engine automatically sanitizes variables when outputed with #{} Markdown style HTML, automatically gets rendered by Express ****/ body p Just a simple form with one Ajax calculated field. p if(firstname.length > 0 && (oranges > 0 || apples > 0) .alert.alert-success button.close(type='button', data-dismiss='alert') × b Thank you #{firstname} #{lastname}, for sending us #{apples} Apples and #{oranges} Oranges. else if(firstname.length && (oranges == 0 && apples == 0)) .alert.alert-warning button.close(type='button', data-dismiss='alert') × b Oops, #{firstname} #{lastname} it looks like you didn't select any fruit to share with us! form.form-horizontal(role='form', action='/submit', method='post') .form-group label.col-lg-2.control-label(for='MemTabPersonFirstName') First Name .col-lg-8 if(user) input#MemTabPersonFirstName.form-control(name='firstname', accesskey='f', value='#{user.firstname}', type='text') else input#MemTabPersonFirstName.form-control(name='firstname', accesskey='f', value='', type='text') span.help-block.col-lg-2 .form-group label.col-lg-2.control-label(for='MemTabPersonLastName') Last Name .col-lg-8 if(user) input#MemTabPersonLastName.form-control(name='lastname', accesskey='l', value='#{user.lastname}', type='text') else input#MemTabPersonLastName.form-control(name='lastname', accesskey='l', value='', type='text') span.help-block.col-lg-2 .form-group label.col-lg-2.control-label(for='DemoApples') Apples? .col-lg-8 select#DemoApples.form-control(name='apples', accesskey='a') option(value='0') 0 option(value='1') 1 option(value='2') 2 option(value='3') 3 option(value='4') 4 option(value='5') 5 option(value='6') 6 option(value='7') 7 option(value='8') 8 option(value='9') 9 span.help-block.col-lg-2 .form-group label.col-lg-2.control-label(for='DemoOranges') Oranges? .col-lg-8 select#DemoOranges.form-control(name='oranges', accesskey='o') option(value='0') 0 option(value='1') 1 option(value='2') 2 option(value='3') 3 option(value='4') 4 option(value='5') 5 option(value='6') 6 option(value='7') 7 option(value='8') 8 option(value='9') 9 span.help-block.col-lg-2 .form-group label.col-lg-2.control-label(for='DemoFruit') Total Fruit .col-lg-8 span.help-block span#FruitCount 6 span.help-block.col-lg-2 .form-group .col-lg-12 button.btn.btn-default(type='submit', name='icogDoSomethingSubmit', accesskey='d') span.glyphicon.glyphicon-cog | Do Something p script. $('#DemoApples').select(function(){ $.get('/addfruit', { Apples: $('#DemoApples').val(), Oranges:$('#DemoOranges').val(), ajax: true }, function(data){ $('#FruitCount').text(data); } });
Moxie.Build v4 includes a Web Server, an In-Memory Managed-Relationships Database, a clear-cut Content Management System ready to build on top of, and an Admin Interface for developers and back office staff. The MOX Server Side Scripting Language 'does so much for you' making complex tasks easy, while always providing a way to customize it. A robust security framework and baked-in E-Commerce make it easier to profit from your efforts. Moxie.Build is high performance, stable, easy to learn, easy to maintain, and has professional support and training available.
Moxie.Build is all about server side scripting, and making front end development as automated as possible. These sources are built right in and managed for you. Each version of Moxie.Build comes with compatible client side sources that are integrated and tested.
Available Now
Coming Soon
"I love how fast it is!" - Daniel
"Favorite thing: Speed" - Jordan
"Far more effective and many times simpler than Oracle" - Kerry
"All the good stuff from a CMS, but you still have very strong low-level control over dynamic content" - Alex
"It is certainly simpler to get data out of it and onto the page than other systems" - Leonard
"Its error reporting is awesome after dealing with PHP" - Jordan
"Moxie.Build elegantly sums up the world of CMS, eCom, DB, and programming" - Kerry
"Now that I've seen it in action...wow." - Sasa