Friday 20 February 2015

JqGrid and Spring 3 MVC Integration With MongoDB

Hi Guys,
In this tutorial we will build a Spring 3 MVC Application which uses MongoDB in the back-end for retrieving and updating  the jqGrid data from presentation layer.

What is jqGrid?

jqGrid is an Ajax-enabled JavaScript control that provides solutions for representing and manipulating tabular data on the web. Since the grid is a client-side solution loading data dynamically through Ajax callbacks, it can be integrated with any server-side technology, including PHP, ASP, Java Servlets, JSP, ColdFusion, and Perl.

jqGrid uses a jQuery Java Script Library and is written as plugin for that package.

Source: http://www.trirand.com/jqgridwiki/doku.php

Here's a screenshot of what we will be doing:


Our application is a simple system for managing a list of users. The presentation layer uses a jqGrid to display the data which is built on top of the JQuery, a great JavaScript framework. The business layer is composed of simple Spring beans annotated with @Controller and @Service. We are using MongoDB for storing our user information, which in-turn used by Spring for retrieving  and updating the data from jqGrid.

Let's start by defining our domain User for MongoDB to map our bean with database.

User.Java

package in.grid.dao;

/**
 * A simple POJO to represent our user domain for MongoDB connection  
 *
 */

import java.util.Date;

import org.springframework.data.annotation.Id;

import org.springframework.data.mongodb.core.index.Indexed;

import org.springframework.data.mongodb.core.mapping.Document;



@Document(collection = "users")

public class User {


@Id

private String id;
@Indexed
private String ic;
private String name;
private int age;
private Date createdDate;

public User(String ic, String name, int age, Date createdDate)
{
this.ic = ic;
this.name = name;
this.age = age;
this.createdDate = createdDate;
}

  /**
   * Getters and Setters
   *
  */
}


Now we define our RequestDao Domain which used to Map JSON data from presentation layer to Business Layer.

RequestDao .java

package in.grid.dao;

import java.util.Date;

public class RequestDao {

private String id;

private String ic;

private String name;

private int age;

private Date createdDate;

        /**
      * Getters and Setters 
     */
}

Let's move on to the controllers. 
GridController.java

Notice our controllers are simple classes annotated with @Controller and @RequestMapping. Same with the @Service annotation, this class becomes a Spring Controller that's capable to handle URI-template-based requests.

package in.grid.controller;

import in.grid.dao.RequestDao;
import in.grid.dao.User;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class GridController {

@Autowired
MongoOperations mongoOperations;

@RequestMapping(value = "/getGridData",method=RequestMethod.GET)      
    public @ResponseBody String getAll(HttpServletRequest request){
String result = null;
System.out.println("Fetching Data From DB");

try
{
List<User> users = mongoOperations.findAll(User.class);

ObjectMapper mapper = new ObjectMapper();
result = mapper.writeValueAsString(users);

}catch(Exception e)
{
e.printStackTrace();
}


System.out.println("Data: "+result);

        return result;
    }

@RequestMapping(value = "/saveGridData",method=RequestMethod.POST)      
    public @ResponseBody String saveData(@RequestBody RequestDao requestDao,     HttpServletRequest request){

String id = requestDao.getId();
System.out.println("Saving data to db");

try
{
Query query = new Query();
query.addCriteria(Criteria.where("id").is(id));
User user = mongoOperations.findOne(query, User.class);
user.setAge(requestDao.getAge());
user.setCreatedDate(requestDao.getCreatedDate());
user.setIc(requestDao.getIc());
user.setName(requestDao.getName());
mongoOperations.save(user);

List<User> users = mongoOperations.findAll(User.class);
System.out.println(users);


}catch(Exception e)
{
e.printStackTrace();
return "Some Thing Happened Please try after some time!!!";
}

return "Data Stord Successfully!!!";  
    }

}


The GridController has twomappings: 
/spring/getGridData -- reterive data from MongoDb
/spring/saveData -- Save data to MongoDB after editing form jqGrid

Let's move on to the presentation layer. 
index.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JQGrid Example</title>
<link href="<c:url value="/resources/css/jquery-ui.css" />" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" type="text/css" href="<c:url value="/resources/css/ui.jqgrid.css" />"/>
  <script src="<c:url value="/resources/js/jquery-1.9.1.js" />"></script>
  <script src="<c:url value="/resources/js/jquery-ui.min.js"/>"></script>
  <script src="<c:url value="/resources/js/grid.locale-en.js"/>"></script>
    <script src="<c:url value="/resources/js/jquery.jqGrid.min.js"/>"></script>
    <script src="<c:url value="/resources/js/grid.js"/>"></script>
</head>
<body>
<div id="griddiv" align="center">
<table id="rowed5" align="center"></table>
 <div id="pager"></div> <br>
 <input type="button" id="upload-trigger" Value="Save Data">
 </div>
</body>
</html>

Note: Do not ignore DOCTYPE in your jsp!!!. In jqGrid the pager will become very large.

I created a custom js file called grid.js for defining all my javascript code.

$(function() {
$('#upload-trigger').prop('disabled', true);

  $("#rowed5").jqGrid({      
    url : "spring/getGridData",
    datatype : "json",
    mtype: "GET",
    colNames:['Id','Ic', 'Name', 'Age','CreatedDate'],
    colModel:[
        {name:'id',index:'id', width:250, sorttype: "int", editable:false,editoptions:{readonly:true,size:10}},
        {name:'ic',index:'ic', width:90,editable:true,editoptions:{size:25}},
        {name:'name',index:'name', width:200, editable:true,editoptions:{size:10}},
        {name:'age',index:'age', width:60,align:"right",editable:true,editoptions:{size:10}},
        {name:'createdDate',index:'createdDate',width:200, editable: true}
    ],
    onSelectRow: function(id){
    $('#upload-trigger').prop('disabled', false);
    },
    rowNum:5,
    rowList:[5,10,15],
    pager:'#pager',
    rownumbers:true,
    autoencode: true,
    sortname: 'id',
    viewrecords: true,
    sortorder: "asc",
    caption:"JQGrid Example",
    height:"auto",
    loadonce: true,
    editurl: 'clientArray',
    jsonReader : {
    root: "d.rows",
        page: "d.page",
        total: "d.total",
        records: "d.records",
        repeatitems: false
    }

  }).jqGrid('navGrid', '#pager', { edit: true, add: false, del: true, search: true }, {closeAfterEdit: true}, {closeAfterAdd:true}, {}, {closeAfterSearch: true});

  $("#upload-trigger").click(function() {
console.log("Inside save");
   var selRowId = $("#rowed5").jqGrid ('getGridParam', 'selrow');
   var rowObject = $('#rowed5').getRowData(selRowId);
   console.log(JSON.stringify(rowObject));
   $.ajax({
   type: 'POST',
   contentType : 'application/json; charset=utf-8',
   url: 'spring/saveGridData',
   data: JSON.stringify(rowObject),
   success: function (response) {
    alert(response);
   
   },
   error:function(request, textStatus, errorThrown) {
       alert(errorThrown);
   }
});
 
});

});


Another important setting you must look at is the jsonReader we declared inside the jqGrid: jsonReader : { root: "d.rows", page: "d.page", total: "d.total", records: "d.records", repeatitems: false } The names in colmodel must exactly match the properties you're passing in your JSON data. It's case sensitive! FIRSTNAME and firstName are not the same names!
Let's return to Spring. Typical with any Spring application, we must declare a few required beans in the xml configuration. dispatcher-servlet.xml web.xml
web.xml
<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         metadata-complete="true">
  <display-name>Archetype Created Web Application</display-name>

  <welcome-file-list>
        <welcome-file>/WEB-INF/views/index.jsp</welcome-file>
</welcome-file-list>

  <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/spring/*</url-pattern>
    </servlet-mapping>
 
  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </context-param>
</web-app>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd"> <context:component-scan base-package="in.grid"/> <mvc:annotation-driven /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewRes olver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!-- Connection to MongoDB server --> <mongo:db-factory id="mongoDbFactory" host="localhost" port="27017" dbname="gridpoc"/> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" /> </bean> </beans>
Note: I created this application on Maven dependency, we need to add all our dependencies to pom.xml.
Hope you guys got good idea on Jqgrid With Spring MVC using MongoDb..
That's all Folks...

Monday 9 February 2015

Validate Multiple-Select List Box Using JavaScript

Hi Guys,
In this post we are going to see how to Validate Multiple-Select list box using JavaScript.

Recently i came to worked on validating Multiple-Select List box. For e.g i have a 5 items in my list box, the user need to select maximum of 2 items not more than that. For this i need to write a JS code for validating Multiple-Select list box.

Lets see how to validate the list box using JavaScript.
Index.jsp

<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript">
function get(){

var list=document.getElementById("demo");
console.log(list);

var selectd_items=0;

for(var i=0;i<list.length;i++){

if(list[i].selected){
console.log(list[i].selected);

selectd_items++;

}

}

if(selectd_items==0 || selectd_items==1){

alert("Please select at least two item");

}else if(selectd_items>2){

alert("Don't select more than two items");

}

}
</script>
</head>
<body>
<form>
<select id="demo" multiple="multiple">
<option value="1">Volvo</option>
<option value="2">Saab</option>
<option value="3">Mercedes</option>
<option value="4">Audi</option>
</select>
<input type="button" value="Submit" onclick="get()">
</form>
</body>
</html>


Inside script i wrote a function called get() which should calls from button onclick and it gets all the list items from Multiple-Select box, Once i get the items iterate the list and store the selected items in a variable selectd_items. After getting the items check whether the user selected maximum of 2 items, not more than that.

That's all folks.. Hope You got some ideas from this post..