Select2 Infinite Scroll with Remote Data With Spring MVC

Select2 Infinite Scroll with Remote Data With Spring MVC

This tutorial is main for spring mvc 3, jquery and select2. Let’s get started.

[googlefont font=”Enriqueta” fontsize=”30″].html[/googlefont]
Don’t overlook the documentation, you need to change your input element to hidden text fields.

<!DOCTYPE html>
<html>
     <head>
        <link rel="stylesheet" type="text/css" href="css/select2.css"/>
        <link rel="stylesheet" type="text/css" href="css/others_css.css"/>
        <script src="js/jquery.min.js"></script>
        <script src="js/select2.min.js"></script>
        <script src="js/othersjavascript.min.js"></script>
     </head>
     <body>

             <div class="row">
                   <label> Vessel </label>
                   <input type="hidden" id="vesselCode" name="vesselCode"/>
             </div>

             // codeomitted
     </body>
</html>

[googlefont font=”Enriqueta” fontsize=”30″]Javascript[/googlefont]

$(document).ready( function() {

    function dataFormatResult(aaData) {
        /* you can format you data like display 
            thumnail or table here with html. 
            For demo purpose i just return text
        */

        return aaData.vesselCode;
    }

    function dataFomatSelection(aaData) {
        /* onclick event happen here */
        return aaData.vesselCode;
    }

    $("#vesselCode).select2({
         placeholder : "Select vessel code",
         minimumInputLength : 4,
         ajax : {
              url : 'http://yourdomain/rest_api_url/get_data',
              dataType: 'json',
              quietMillis: 100,
              data: function(term, page) {
                   /*  
                     This part show the parameter can get on server side.
                     These parameters has same usage as the other library.
                     I'm reusing both on the same server code.
                   */
                   return {
                         q: term,
                         iDisplayStart : (page - 1) * 20,
                         iDisplayLength : 20,
                         sEcho: 0,
                         iSortCol_0: 0,
                         sSortDir_0: 'asc'
                   } 
              },
              results: function(data, page) {
                   var more: ( page * 20 ) < data.iTotalDisplayRecords;
                   return { results: data.aaData, more: more};
              }
         },
         formatResult : dataFormatResult,
         formatSelection : dataFormatSelection,
         dropdownCssClass : "bigdrop",
         escapeMarkup : function(m) { return m; }                           
    });
});

[googlefont font=”Enriqueta” fontsize=”30″]Common problem[/googlefont]
Sometimes your infinite scroll may work well but you can’t select the items from the results. This problem was due to select2 required you provide the property id to differentiate from unique fields. To overcome this problem, you can over write like this:

<script th:inline="javascript">
/*<![CDATA[ */

    $("#vessel_code").select2({
          placeholder: "Search for vessel code",
          minimumInputLength: 4,
          id: function(obj) {
               return obj.vesselCode;
          }
          ajax : {
               // code omitted
          }
          // code omitted   
    })

/* ]]> */
</script>

 

Related discussion can be found on stackoverflow

[googlefont font=”Enriqueta” fontsize=”30″]Sample Server Code[/googlefont]

@RequestMapping(value = "/get_data", produces = "application/json")
public @ResponseBody String showData (
  @RequestParam(value="iDisplayStart", required=false) Integer iDisplayStart,
  @RequestParam(value="iDisplayLength", required=false) Integer iDisplayLength,
  @RequestParam(value="sEcho", required=false) Integer sEcho,
  @RequestParam(value="iSortCol_0", required=false) Integer iSortCol_0,
  @RequestParam(value="sSortDir_9", required=false) String sSortDir_9,
  @RequestParam(value="q", required=false) String q,
  HttpServletRequest request, HttpServletResponse response)
{
    String result = StringUtils.EMPTY;
    iDisplayStart = (iDisplayStart == null ? 0: iDisplayStart.intValue());
    iDisplayLength= (iDisplayLength== null ? 10: iDisplayLength.intValue());

    long totalRecords = service.countTotal();
    long nrOfPage = totalRecords / iDisplayLength;

    List<Vessel> list = service.findEntries(iDisplayStart, iDisplayLength, iSortCol_0, sSortDir_9, q);

    DataTableRequest<Vessel> json = new DataTableRequest<Vessel>();
    json.setAaData(list);
    json.setiTotalDisplayRecords(totalRecords);
    json.setiTotalRecords(nrOfPage);
    json.setsEcho(sEcho);

    ObjectMapper mapper = new ObjectMapper();
    try {
        result = mapper.writeValueAsString(json);
    } catch (Exception e) {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    }
    return results;
}

[googlefont font=”Enriqueta” fontsize=”30″]Update record. Pre-populate data[/googlefont]
When update record, you need to pre-populate the data as in stored in database. So you need to used the initSelection section.

ajax : {
   // code omitted
},
initSelection: function(element, callback) {
    var id=$(element).val();
    if (id!=="") {
        $.ajax({
            // I'm using thymeleaf here, u have to change to ur rest api call.
            url : [[${#httpServletRequest.contextPath}+'/vessel/get_record/']],	
            data : {
                 // parameter pass to server side
	         vesselCode : id
	   },	
	   dataType: "json"
        }).done(function(data) { callback(data); });
    }
},
// code omitted

[googlefont font=”Enriqueta” fontsize=”30″]Sample backend code[/googlefont]

@RequestMapping(value = "/get_record", produces = "application/json")
public @ResponseBody String showExtactData(
@RequestParam(value = "vesselCode", required = false) String vesselCode,
    HttpServletResponse response) throws IOException {

    Vessel entity = service.findVessel(vesselCode);

    ObjectMapper mapper = new ObjectMapper();
    String result = StringUtils.EMPTY;
    try {
        result = mapper.writeValueAsString(entity);
    } catch (Exception e) {
	response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    }
    return result;
}

Write a Reply or Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.