Feedback form in the Express

We will be continuing our previous example with same code, now we will how to added the feedback form on the page. The Express js help us to create the web server with the Javascript.

To create the dynamical web page, where we allowed the client to communicate with the server. Here we are creating API to get or retrieve the client feedback from feedback.json file and allow the client to give feedback as in form.

What we are learning

  1. Adding a new page called feedback page in existing page.
  2. Reading existing feedback data from app/data/feedback.JSON through HTTP GET method.
  3. We will create the Javascript function to manage feedback form.
  4. We learn HTTP method to manage to feedback.JSON data. We can add new user data, delete existing data and retrieve all the user data with api.js file in app/routes.

Step 1:  First we will add feedback page code in app/views/feedback.ejs.

<!DOCTYPE html>
<html>
  <head><% include partials/template/head.ejs %></head>
  <body id="<%= pageID %>">
    <% include partials/template/header.ejs %>
    <div class="container">
      <div class="row">
        <div class="col-sm-4">
          <h1 class="feedback-form-title">Send us feedback</h1>
          <form class="feedback-form">
            <div class="form-group">
              <label for="feedback-form-name">Name</label>
              <input type="text" class="form-control" id="feedback-form-name" placeholder="Enter your name">
            </div>

            <div class="form-group">
              <label for="feedback-form-title">Title</label>
              <input type="text" class="form-control" id="feedback-form-title" placeholder="Title of your feedback">
            </div>

            <div class="form-group">
                <label for="feedback-form-message">Message</label>
                <textarea type="text" placeholder="Enter your message, then hit the submit"  class="form-control" id="feedback-form-message" rows="6"></textarea>
            </div>
            <button type="submit" class="btn btn-default pull-right">Submit</button>
          </form>
        </div><!-- primary -->
        <aside class="col-sm-8">
          <div class="maincontent feedback">
              <h2 class="article-title">Recent Feedback</h2>
              <div class="feedback-messages"></div>
          </div>
        </aside><!-- secondary -->
      </div>
    </div><!-- container -->
    <% include partials/template/jsdefaults.ejs %>
  </body>
</html>

The above code will generate feedback form on the page and retrieve existing data from feedback.json and put the retrieve data on div element having class feedback-messages with help of public/js/feedback.js function.

<div class="feedback-messages"></div>

Step 2: We will have to add routing information to our feedback page.  url : localhost:3000:feedback. Add the following code in app/routes/feedback.js

var express = require('express');
var router = express.Router();

router.get('/feedback', function(req, res) {

  res.render('feedback', {
    pageTitle: 'Feedback',
    pageID: 'feedback'
  });

});

module.exports = router;

Add the following routing information in app/app.js

app.use(require('./routes/feedback'));
app.use(require('./routes/api'));
Step 3: We add the following feedback data in app/data/feedback.json
[
    {
        "name":"T Arun",
        "title":"Best Meetup Ever",
        "message":"I really love this meetup. Please don't let it end."
    },
    {
        "name":"Lie",
        "title":"Meeting Time",
        "message":"Would you consider moving the meeting time 30 minutes to about 6pm. It's tough to make it to the meetings on time right after work."
    },
    {
        "name":"Bhim",
        "title":"Great Speaker",
        "message":"I really enjoyed the speaker this month. Would love to hear another presentation."
    }
]

 

Step 4:  In this web apps example, app/routes/api.js and app/public/js/feedback.js are two most important file, where we manage the feedback form and data in feedback.JSON file.  The api.js allow us to uses HTTP method like GET, POST and DELETE to manage the data in app/data/feedback.JSON file. We can add new user data to feedback.JSON, delete existing user information in feedback.JSON and can retrieve all existing data in feedback.JSON file.

The first we will use HTTP GET method in app.js to retrieve JSON data from app/data/feedback.JSON. In api.js GET method http://localhost:3000/api  will no render like page but  it will retrieve data from api/data/feedback.json and add the following code in app/routes/api.js

var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var fs = require('fs');
var feedbackData = require('../data/feedback.json');

router.get('/api', function(req, res) {
  res.json(feedbackData);
});

router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: false }));

router.post('/api', function(req, res) {
  feedbackData.unshift(req.body);  // To add latest data at top
    fs.writeFile('app/data/feedback.json', JSON.stringify(feedbackData), 'utf8', function(err) {
    if (err) {
      console.log(err);
    }
  });
  res.json(feedbackData);
});


router.delete('/api/:id', function(req, res) {
  feedbackData.splice(req.params.id, 1); // remove one element or feedback message
  fs.writeFile('app/data/feedback.json', JSON.stringify(feedbackData), 'utf8', function(err) {
    if (err) {
      console.log(err);
    }
  });
  res.json(feedbackData);
});

module.exports = router;

With above code, we can route to Visit: localhost:3000/api  will retrieve feedback.JSON data from app/data/feedback.json


We have to install Node.js middleware called body-parser.  The npm install –save body-parser. To handle HTTP POST request in Express.js version 4 and above, you need to install middleware module called body-parser. The body-parser handle the formatting of request data and extract the entire body portion of an incoming request stream and exposes it on req.body. Also, we have to import fs node file system module to work with a file.

Step 5: We also have to add a feedback.js file in routes to render the feedback page.  To url : localhost:3000/feedback and add the following code in app/routes/feedback.js

var express = require('express');
var router = express.Router();

router.get('/feedback', function(req, res) {
  res.render('feedback', {
    pageTitle: 'Feedback',
    pageID: 'feedback'
  });
});

module.exports = router;

 

Step 6: We will create a Javascript function that let us manage data in feedback.json. Inside the public/js/ folder add file called feedback.js.  To manage the feedback form the app/public/js/feedback.js file allows us to perform Javascript event like a form submits, delete and reload the existing feedback data into the web page.

$(function() {
  $.getJSON('api', updateFeedback);
  
  $('.feedback-form').submit(function(e) {
    e.preventDefault();
    $.post('api', {
      name: $('#feedback-form-name').val(),
      title: $('#feedback-form-title').val(),
      message: $('#feedback-form-message').val()
    }, updateFeedback);
  });
  
  $('.feedback-messages').on('click', function(e) {
      if (e.target.className == 'glyphicon glyphicon-remove') {
        $.ajax({
          url: 'api/' + e.target.id,
          type: 'DELETE',
          success: updateFeedback   //will call updateFeedback method to feedback data to page
        }); //ajax
      } // the target is a delete button
  }); //feedback messages
  
  function updateFeedback(data) {   //To load the feedback msg data to page.
   var output = '';
   $.each(data,function(key, item) {
     output += '     <div class="feedback-item item-list media-list">';
     output += '       <div class="feedback-item media">';
     output += '       <div class="media-left"><button class="feedback-delete btn btn-xs btn-danger"><span id="' + key + '" class="glyphicon glyphicon-remove"></span></button></div>';
     output += '         <div class="feedback-info media-body">';
     output += '           <div class="feedback-head">';
     output += '             <div class="feedback-title">' + item.title + ' <small class="feedback-name label label-info">' + item.name + '</small></div>';
     output += '           </div>';
     output += '           <div class="feedback-message">' + item.message + '</div>';
     output += '         </div>';
     output += '       </div>';
     output += '     </div>';
   });
   $('.feedback-messages').html(output);  // Add the output variable result in div oc class name feedback-message in view/feedback.ejs
  }
});

In above code, api is api route and we are using Jquery, with Jquery we can easily handle the ajax request which is how to get data in the page.

  1. We are sending Jquery getJSON request to api in routes folder. In api.js file in routes folder will be sent HTTP GET request to app/data/feedback.JSON. Once all data from app/data/feedback.json are put in output variable containing HTML and data.
  $('.feedback-messages').html(output);

where feedback-messages is the name of div class in file feedback.ejs in views folder.  Here we appending out variable to this div class.

2. When a user clicks on submit button in a feedback form, it will generate an event as e as shown in the code as variable e is an event. We can trap or caught this event e and we can use e.preventDefault(); to prevent the form from reloading in the server. With help of Jquery will send our submitted form data in URL as POST method to our api route. Once form data is sent, we want to call updateFeedback method to load existing feedback message in form.

3. To delete existing feedback message in the page.  To invoke delete event we will click on glyphicon-remove icon. 

The $(‘.feedback-messages’).on(‘click’, function(e) {  

The feedback-messages element in view/feedback.ejs element has the list of all the messages. First, we have to select the target element that is feedback-messages div and then we are sending ajax request with URL and a target id of the element to api route to delete a feedback message. 

 

 

Step 6: We have to set condition in app/views/partials/template/jsdefaults.ejs file, as we will run the app/public/js/feedback.js  Javascript file only when we route to localhost:3000/feedback.  The feedback.js in js folder we will call to api of route and call to api route will return the information from the file feedback.JSON data.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

<% if(typeof artwork !== "undefined") { %>
  <script src="/js/pixgrid.js"></script>
<% } %>


<% if(pageID == 'feedback') { %>
  <script src="/js/feedback.js"></script>
<% } %>

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script src="/reload/reload.js"></script>