Showing posts with label HTML. Show all posts
Showing posts with label HTML. Show all posts

Monday, January 23, 2017

Send/receive data from Javascript to Node.js using Express

One of the most basic requirement while creating node js web applications is to send and receive data between HTML client and Nodejs server pages. This blog post shows how can we send data from HTML forms using javascript to node.js server and receive the response.

There can be multiple ways to achieve the above-mentioned task. My post explains this communication with one simple example. In this example, we have one HTML form with username and password. Once the user submits the form data, it goes to node.js server and response is send back to HTML page about the status of the user.

To begin with, we need to have node.js installed on the workstation to start coding. Download link to node.js is shared below:

Node.js - https://nodejs.org/en/

We can use open source editors like sublime, atom or visual studio code for writing our codes. Download links for them are shared below:

Atom - https://atom.io/

Sublime - https://www.sublimetext.com/3

Visual Studio Code - https://code.visualstudio.com/

Once we are done with the setup, we start by initializing our project. Navigate to command prompt and change directory to the project folder. Please refer screenshot below for node project initialize command.

Node.js command for project initialize


Once "npm init" command is executed on command prompt you will set up your project by entering all the required fields as shown below:

Node.js command for project initialize


After the execution is complete, we can see a "package.json" file which stored all the information. Also keep a note of entry point "index.js" file as shown above. The main purpose of "package.json" file is to document for what packages your project depends on. It also makes our build reproducible which means, if we share our code with other developers it is easier for them to load dependencies and run the project easily.

To use the express server, we will install it in our current project. Any dependency required in the project is installed with npm command. In this example, we will install express using "npm install express" command.

Adding express server to node.js project


As mentioned in the initialize project configuration, we can create our index.js file. 

index.js

This file acts as main launch file for the node js web application. This file would be listening to a port which will act as a server.

var express = require('express');
var app = express();
app.use(express.static('public'));

//Routes
app.use(require('./routes'));  //http://localhost:8000/    http://localhost:8000/login
var server = app.listen(8000, function () {
  var host = server.address().address
  var port = server.address().port 
  console.log("Example app listening at http:// ", host, port);
});

One very important thing apart from listening to port is "Routes" in the index.js file. We create a routes file and define the behavior of our web application navigation in this file. Lets us have a look at our routes.js file below:

routes.js

The first route defined in the below file is for the index.html file. The index.html file is main launch file which is connected or mapped to the root of the application. The second route which is "/login" route will be used as POST URL from javascript in our HTML file. As shown below, we are also having a new dependency which we need to install with the command "npm install body-parser". body-parser gives you a middleware which uses the incoming request data to await the full, raw contents of the request body before "parsing it". "body-parser" extracts the entire body portion of an incoming request stream and exposes it on req.body as something easier to interface with.

var express = require('express');
var router = express.Router();
var path = require('path');
var bodyParser = require('body-parser')
var urlencodedParser = bodyParser.urlencoded({ extended: false })


// Define the home page route
router.get('/', function(req, res) {  
  res.sendFile(path.join(__dirname +'/index.html'));
});


// Define the login route
router.post('/login',urlencodedParser, function(req, res) 
{
     if (!req.body)
     return res.sendStatus(400);  
    
     console.log("userid -> ",req.body.userid)
     console.log("password -> ",req.body.pwd)

     // we can connect and validate username and password from database
     // this project example does not include scope for database connection
     // here we will try to send static values from node.js to html and see response on client side
     var userstatus = false;

     res.setHeader('Content-Type', 'application/json')        
     res.end('{"userexist": '+userstatus+'}'); // userstatus is send to html client as response from node.js

});

module.exports = router;

The main client file which is connecting to the node.js server code is index.html. This file acts as the entry point of the application and loads a view to interact with the server.

index.html

The code below is used to render HTMLform which is sending data to the node.js code. The most important part in the code below in script tag which contains the javascript which is used for communication.

As shown, jQuery ajax call is made with POST method to connect to node route "http://localhost:8000/login" . The 'data' property is used to send the data to node.js server in JSON object format.

<!DOCTYPE html>
<html>
<head>
  <title>New Website</title>
 
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="css/style.css">

</head>

<body>


<div class = "container">
  <div class="wrapper">
    <form  method="post" name="Login_Form" class="form-signin" id="form.login" action="/login" >       
        <h3 class="form-signin-heading">Welcome ! Please Sign In</h3>
        <hr class="colorgraph"><br>
        
        <input type="text" class="form-control" name="InputUsername" id="InputUsername" placeholder="Username"  required="" autofocus="" />
        <input type="password" class="form-control" name="InputPassword" id="InputPassword" placeholder="Password"  required=""/>          
       
        <button class="btn btn-sm btn-primary btn-block"  id="SubmitBtn" value="sendData" type="button" >login</button> </br>
       
        <div id="select_link"  style="display:none ">
          <h6> You are not registered user. <a href="/signup">Click here </a> to signup.</h6>
        </div>
    </form>     
  </div>



<script type="text/javascript">
    $(document).ready(function(){
    $("#SubmitBtn").on("click",function(){
       //reading form data to send information to node.js
       var userid =$("#InputUsername").val(); 
       var pwd =$("#InputPassword").val();

       //send data as POST to node url defined in node routes
        $.ajax({
        type: 'POST', 
        url: 'http://localhost:8000/login',
        data: {"userid":userid,"pwd":pwd},        
        //success function executes once communication with node.js is complete and we receive response from node as data params
        success: function (data) {
            var receivedData = data;            
            if (receivedData.userexist == false) {
              $("#select_link").show()
            }
        },
        error: function (xhr, status, error) {
            console.log('Error: ' + error.message);
            console.log('Error connecting to the server.');
        }
        });
    });
  });
  </script>
 
</div>
</body>
</html>

The complete working example of this communication can be seen in video below:




Download completed project files - Click here

-Nitin



Friday, April 11, 2014

Using BackboneJS and RequireJS to create simple CYU

This post explains using Backbone JavaScript framework to load a question from XML document and process it in the form of a check your understanding(cyu).

First I would list down the libraries/framework required to build this example.

Jquery - http://jquery.com/
Backbone - http://backbonejs.org/
Underscore - http://underscorejs.org/
RequireJS - http://requirejs.org/
TextJS - https://github.com/requirejs/text

Each of the libraries listed above can be downloaded or referred using CDN link. I have downloaded and placed them in the lib folder of the app structure. To begin with lets create cyu index.html page.

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CYU Example Backbone</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-main="js/app" src="js/require.js"></script>
</head>
<body>
</body>
</html>

index page includes require.js along with the data-main attribute which is the first place our application boots from. It refers to the configuration file as described below:-

app.js

require.config({
baseUrl :'js/lib',

paths:{
app: '../app',
tpl: '../tpl'
},

shim:{
'backbone':{
deps:['underscore','jquery'],
exports:'Backbone'
},
'underscore':{
exports:'_'
}
}
});


require(['jquery','backbone','app/router'],function($,Backbone,Router){
var router = new Router();
Backbone.history.start();
});

Please refer to RequireJS - http://requirejs.org/ for details about the configuration. Once config is complete we load the Backbone - Router class along with its dependencies which as shown above are Jquery and Backbone. Once this is done we create new instance of Router which triggers the start of application. Lets look into Router file.

router.js

define(function(require){
"use strict";

var $ = require('jquery'),
Backbone = require('backbone'),
MainView = require('app/views/main'),
$body = $('body'),
mainView = new MainView({el:$body}).render(),
$content = $("#question_container", mainView.el)

return Backbone.Router.extend({
routes:{
"":"home"
},

home:function(){
require(["app/views/questiondisplay","app/models/quesdata"],function(QuestionDisplay,models){
var quesdata = new models.QuesData();
quesdata.fetch().then(function(){
var dataobject = {question:quesdata.pluck('question'),qoptions:quesdata.pluck('qoptions')}
var questionDisplay = new QuestionDisplay({el : $content});
questionDisplay.render({model:dataobject});
});

});
}
});
});

Router class above first of all loads the MainView. MainView in this example is the main container which holds the entire app. Let's have a look at the MainView (Backbone-View) and its template.

mainview.js

define(function(require){
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
tpl = require('text!tpl/Main.html'),

template = _.template(tpl)

return Backbone.View.extend({

render:function(){
this.$el.html(template());
return this;
}
});
});

Main.html

<div class='container'>
<div style='width:100%;text-align:center;'><h1>Check your understanding<h1></div>
<div id='question_container' style='width:100%'></div>
</div>

Once mainView gets loaded by the Router class it looks for the home route which in our example is the home function added in the Router class. The 'home' function does actually loads the XML using a Backbone model and then renders it using 'questiondisplay' view and 'quesdata' model.

First lets look into Model of this app which gets created from cyu.xml file.

cyu.xml

<?xml version='1.0' encoding='UTF-8'?>

<qdata>
<question><![CDATA[What does AJAX stand for ?]]></question>
<choices>
<opt cval='0'><![CDATA[Asynchornous JS]]></opt>
<opt cval='0'><![CDATA[Synchornous JS]]></opt>
<opt cval='0'><![CDATA[Javascript and XML]]></opt>
<opt cval='1'><![CDATA[Asynchornous Javascript and XML]]></opt>
</choices>
<feedback>
<correct><![CDATA[Congrats! Correct Answer.]]></correct>
<incorrect><![CDATA[Incorrect! Please try again.]]></incorrect>
</feedback>
</qdata>

quesdata.js

define(function(require){
"use strict";

var $ = require('jquery'),
Backbone = require('backbone'),

QuesData = Backbone.Collection.extend({
url: 'js/app/models/cyu.xml',
initialize:function(){
},

parse: function (data) {

var parsed = [];
var questionoptions = [];

$(data).find('opt').each(function (index) {
var opts = $(this).text();
questionoptions.push({option:opts,cval:$(this).attr("cval")})
});

var question = $(data).find('question').text();

parsed.push({question: question, qoptions: questionoptions});

return parsed;
},

fetch: function (options) {
options = options || {};
options.dataType = "xml";
return Backbone.Collection.prototype.fetch.call(this, options);
},


sync: function(method, model, options) {
 var params, data;  
 options || (options = {});  
 data = {xml: options.response};

 params = {
url: this.url,
type: 'POST', 
dataType: 'xml',
data: data
 };
return $.ajax(_.extend(params, options));
}

});

return{
QuesData:QuesData
}

});


Once as the model gets ready we proceed with the cyu view using 'questiondisplay' which is a Backbone-View extended class.

questiondisplay.js

define(function(require){
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
tpl = require('text!tpl/QuestionDisplay.html'),

correctAnswerIndex,
correctAnswerCode = '1',

template = _.template(tpl)

$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};

return Backbone.View.extend({

render:function(options){

var o = {};

_.each(options.model.qoptions[0], function(e,i) {
o[e.option] = e.value;

if(e.cval === correctAnswerCode){
correctAnswerIndex = i;
}

});

this.$el.html(template({options:options}));
return this;
},

events:{
'submit .cyu-user-form':'submitAnswer'
},

submitAnswer:function(ev){

if($(ev.currentTarget).serializeObject().ans == correctAnswerIndex){
console.log("CORRECT ANSWER :: ");
alert("CORRECT ANSWER :: ");
}else{
console.log("INCORRECT ANSWER ::: ");
alert("INCORRECT ANSWER ::: ");
}
return false;

}


});
});

QuestionDisplay.html

<div id="question"><%= options.model.question %></div>
<div id="choices">
<form class="cyu-user-form">
<ul class="list-unstyled">
<% _.each(options.model.qoptions[0], function(e,i){ %>
<li><input type='radio' name='ans' value="<%=i%>"><span><%= e.option %></span></li>
<% }); %>
</ul>
<button class='btn btn-primary cyubtn' type="submit">Submit</button>
</form>
</div>

Backbone view classes has events property where we can add events to the buttons and other DOM elements which gets loaded via template. The 'submitAnswer' gets fired up as soon as user clicks the submit button. The correct answer is validated using the model 'quesdata' and feedback is shared in form of alert messages.

All the associated files can be downloaded and hosted on webserver/localhost to test.

Download Link:- Click Here

-Nitin

Reference Links:-

http://coenraets.org/blog/2012/02/sample-app-with-backbone-js-and-twitter-bootstrap/

http://coenraets.org/directory/


Thursday, June 18, 2009

Have you heard of HTML5?

HTML5 is a new standard of the World Wide Web, HTML. The most important and amazing thing about html5 that can let everone thinking about is the "video" html tag. The video tag will make it possible to add video into html webpages and have it playback across different browsers that implements html5.

In addition to basic markup, HTML 5 specifies scripting application programming interfaces (APIs). Existing Document Object Model (DOM) interfaces are extended and de facto features documented. There are also new APIs, such as:

  • The canvas tag for immediate mode 2D drawing
  • Timed media playback
  • Offline storage database
  • Document editing
  • Drag-and-drop
  • Cross-document messaging
  • Browser history management
  • MIME type and protocol handler registration

Source : Wikipedia

The canvas element for drawing graphics on-the-fly is a good example; new in HTML 5, it’s already supported by every major browser except Internet Explorer (and there are workarounds for IE too).

Lesser-known HTML 5 features like offline data storage, cross-document messaging, and access to the back/forward stack, which are mainly of interest to JavaScript developers, are also popping up in the newest browsers, including IE8.

Source : Sitepoint

More Information could be gathered from links below:


-Nitin-

Using FormBuilder, Validators & FormGroup in Angular 2 to post data to Node server (node.js)

This blog explains usage of  FormBuilder , Validators , FormGroup classes in Angular 2 projects. In this post we will create HTML form a...