Luffy
Luffy

Reputation: 1335

Filter dynamic data using ajax in spring

I'm working on a project in which I need to display records on jsp/client side. To do that I used a loop to display data like give below which is working fine for me.

JSTL code in JSP

<c:if test="${!empty students}">
    <c:forEach var="student" items="${students}">
        <c:if test="${student.type == 'event'}">
            <div class="student_card">
                <h3>Student Card</h3>
                <h4 class="stu_name" objType="${student.type}" objId="${student.obj.id}">${student.obj.name}</h4>
                <p class="stu-name">${student.obj.branch.name}</p>
                <div>
                    <div class="description">
                        <p>Description:</p>
                        <p class="description_text">${student.obj.description}</p>
                    </div>
                    <div class="fee_date">
                        <img src="${pageContext.servletContext.contextPath}/resources/images/clock.png" alt="clock" id="clock">
                        <p class="date_gray">${student.formatDate(student.obj.startTime)}&mdash;${student.formatDate(student.obj.endTime)}</p>
                    </div>
                    <div class="stu_status">
                        <p>
                        Status: <span class="stu_green">${student.obj.status}</span>
                        </p>
                        <c:if test="${student.obj.status eq 'In Progress'}">
                            <div class="btn_compl" remove_it="event_${student.obj.id}">
                                <a class="compl_btn_blue">Complete</a>
                            </div>
                        </c:if>
                    </div>
                </div>
            </div>
        </c:if>
    </c:forEach>
</c:if>

I have a form having multiple fields e.g: Name, Gender, Age, class, etc. When a user click on any of these fields I need to display/filter data accordingly.

e.g: User click on gender radio button and select male option from it. So, I need to display all male student record I don't want to submit a form and load full page again to save time against it I used Ajax to filter data. My Ajax function is like this.

Ajax

var data = 'studentName='+studentName+'&gender='+gender+'&studentClass='+studentClass+'&grades='+grades;

$.ajax({
    url: '${pageContext.servletContext.contextPath}/student/filter',
    type: 'POST',
    data: data,
    async: true,
    success: function(response) {
        /* Removing earlier data */
        $('.stu_info').remove();
        /* To display data dynamically which is not working for me */
        <c:forEach var="student" items="${filter}">
            $('.main_content').append('<div class="stu_info"><p>${student.type}</p></div>');
        </c:forEach>
    }
});

Controller:

@RequestMapping(value = "/student/filter", method = RequestMethod.POST)
public @ResponseBody Map<String, ? extends Object> filterStudents(@ModelAttribute(value = "studentName") String studentName, @ModelAttribute(value = "gender") String gender, @ModelAttribute(value = "studentClass") String studentClass, @ModelAttribute(value = "grades") String grades, BindingResult result, WebRequest webRequest, ModelMap map, Principal principal) {

    -------------------
    Code to filter Data
    -------------------

    map.put("filter", studentFilter);
    return Collections.singletonMap("filter", studentFilter);
}

Issue:

My Ajax worked successfully here and I'm able to put data in filter which contain data of filter students. But I'm not able to display any information on jsp side. My jsp code is given below.

<c:if test="${!empty students}">
    <c:forEach var="student" items="${filter}">
        <c:if test="${student.type == 'event'}">
            <div class="student_card">
                <h3>Student Card</h3>
                <h4 class="stu_name" objType="${student.type}" objId="${student.obj.id}">${student.obj.name}</h4>
                <p class="stu-name">${student.obj.branch.name}</p>
                <div>
                    <div class="description">
                        <p>Description:</p>
                        <p class="description_text">${student.obj.description}</p>
                    </div>
                    <div class="fee_date">
                        <img src="${pageContext.servletContext.contextPath}/resources/images/clock.png" alt="clock" id="clock">
                        <p class="date_gray">${student.formatDate(student.obj.startTime)}&mdash;${student.formatDate(student.obj.endTime)}</p>
                    </div>
                    <div class="stu_status">
                        <p>
                        Status: <span class="stu_green">${student.obj.status}</span>
                        </p>
                        <c:if test="${student.obj.status eq 'In Progress'}">
                            <div class="btn_compl" remove_it="event_${student.obj.id}">
                                <a class="compl_btn_blue">Complete</a>
                            </div>
                        </c:if>
                    </div>
                </div>
            </div>
        </c:if>
    </c:forEach>
</c:if>

I think this is not working because JSTL code compile on server side before display content to the user and I also check this link: Using JSTL inside Javascript. Which state that we can't use jstl tags inside jQuery.

Data Response:

{
    "filter":
    [
        {
            "id":"123",
            "name":"jon",
            "class":"5",
            "startTime":1442206800000,
            "endTime":1444453200000,
            "percentage":88,
            "editable":true,
            "obj":
            {
                "id":"402880ed5012503801501252e2df0002",
                "authorizationRequired":false,
                "owner":
                {
                    "id":"402880f24ffeaaba014ffef2bb520015",
                    "school":
                    {
                        "id":"402880f24ffeaaba014ffef31aaf0017",
                        "name":"some school",
                        "enabled":true,
                        "size":300,
                        "sector":null,
                        "phone":"1231231232",
                        "location":"US"
                    }
                }
            }
        }
    ]
}

Question:

So, is there any way in which I can display new/dynamic data on client side.

Any suggestion or link will be helpful.

Upvotes: 0

Views: 2569

Answers (2)

Naman Gala
Naman Gala

Reputation: 4692

You have got problem in your ajax call. You are writing jstl code in your jquery code. Jquery runs on client side where as jstl code runs on server side.

var data = 'studentName='+studentName+'&gender='+gender+'&studentClass='+studentClass+'&grades='+grades;

$.ajax({
    url: '${pageContext.servletContext.contextPath}/student/filter',
    type: 'POST',
    data: data,
    async: true,
    success: function(response) {

        alert( "Response: " + response ); // <--------add this

        /* Removing earlier data */
        $('.stu_info').remove();

        // remove below code and write pure jquery code to iterate response as a json.

        /* To display data dynamically which is not working for me */
        <c:forEach var="student" items="${filter}">
            $('.main_content').append('<div class="stu_info"><p>${student.type}</p></div>');
        </c:forEach>
    }
});

Refer: jQuery loop over JSON result from AJAX Success?


Update: As discussed.

  1. Change return type to List.
  2. You can iterate list in your ajax response as below

    jQuery.each(response, function(index, item) {
        //now you can access properties using dot notation
        alert(item.id);
        alert(item.name);
        alert(item.obj.id);
        alert(item.obj.owner.school.phone);
    });
    

Upvotes: 1

sh0rug0ru
sh0rug0ru

Reputation: 1626

JSTL is rendered on the server. It will not help you if you have to render a response on the client. Use Javascript, specifically jQuery.

Assuming studentFilter is some kind of collection, you should directly return that:

@ResponseBody List<Student> filterStudent(...) {
}

Now, Spring will return a JSON representation of the Java data types, something like the following:

[
    {
        "type": "Some Value"
    },
    {
        "type": "Another Value"
    }
]

Now, in Javascript:

$.each(response, function(index, student) {
    $('.main_content').append('<div class="stu_info"><p>' + student.type + '</p></div>');    
});

Upvotes: 1

Related Questions