How to add parameterized fragment in form recursively in Thymeleaf? - java

I have a data structure, it contains primitive and complex values.
public class Topic{
private String topicUrl = "";
private String key = "";
private String name = "";
private String value = "";
private String type;//RECORD/ARRAY/ENUM/PRIMITIVE
private List<String> enumValues = new ArrayList<>();
private List<Topic> fieldList = new ArrayList<>();
//getters setters
//isEnum()
//isPrimitive()
//isRecord()
}
And I have created thymeleaf frontend to submit Topic objects. only value fields of primitive objects can be edited on frontend. example object is like
Before submit as JSON:
{
"topicUrl": "url",
"key": "",
"name": "object1",
"value": "",
"type": "RECORD",
"fieldList": [
{
"topicUrl": "",
"key": "",
"name": "object1.1",
"value": "",
"type": "INT",
"fieldList": []
},
{
"topicUrl": "",
"key": "",
"name": "object1.2",
"value": "",
"type": "RECORD",
"fieldList": [
{
"topicUrl": "",
"key": "",
"name": "object1.2.1",
"value": "",
"type": "INT",
"fieldList": []
}]
}]
}
After submit as JSON:
{
"topicUrl" : "url",
"key" : "",
"name" : "object1",
"value" : "",
"type" :"RECORD",
"fieldList":[{
"topicUrl" : "",
"key" : "",
"name" : "object1.1",
"value" : "11",
"type" :"INT",
"fieldList":[]
},{
"topicUrl" : "",
"key" : "",
"name" : "object1.2",
"value" : "",
"type" :"RECORD",
"fieldList":[{
"topicUrl" : "",
"key" : "",
"name" : "object1.2.1",
"value" : "121",
"type" :"INT",
"fieldList":[]
}]
}]}
Form page
<form th:action="#{/writeTopic}" th:object="${selectedTopic}" method="post" class="form-horizontal">
<fieldset>
<input type="submit" class="btn btn-primary" th:value="Write"></input>
<table class="table table-striped table-bordered">
<tbody>
<tr>
<td th:text="TopicUrl"></td>
<td>
<input readonly th:field="*{topicUrl}" class="form-control form-control-lg"/>
</td>
</tr>
<tr>
<td th:text="Key"></td>
<td>
<input th:field="*{key}" class="form-control form-control-lg"/>
</td>
</tr>
</table>
<div th:replace="fragments/topicFieldsTable :: topicFieldsTable(topic=${selectedTopic})"></div>
</fieldset>
</form>
Every Topic object contain Topic elements in fieldList if type is "RECORD". so that I have created topicFieldsTable.html fragment for recursion
<table th:fragment="topicFieldsTable(topic)" class="table table-bordered table-striped">
<thead class="thead-dark">
<tr>
<th scope="col" th:text="${topic.className}"></th>
<th scope="col">Type</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody>
<tr th:each="field, itemStat : ${topic.fieldList}">
<td>
<!--field.name-->
<label th:text="${field.name}">Name</label>
</td>
<td>
<!--field.type-->
<label th:text="${field.type}">Type</label>
</td>
<td th:if="${field.isEnum()}">
<select class="form-control form-control-lg">
<option th:each="eval : ${field.enumValues}"
th:value="${eval}"
th:text="${eval}">Value</option>
</select>
</td>
<td th:if="${field.isRecord()}">
<div th:replace="fragments/topicFieldsTable :: topicFieldsTable(topic=${field})"></div>
</td>
<td th:if="${field.isPrimitive()}">
<!--field.value-->
<input name="value" th:name="${field.name}" th:value="${field.value}" class="form-control form-control-lg"/>
</td>
</tr>
</tbody>
</table>
Additionally I couldn't assign fields with th:field in fragment.
Do you have any idea?

Related

How to implement error output during validation for each field separately?

I'm doing backend validation in Java and return in AngularJS error info after validation. How can I display errors for each checked field separately?
Main.js - file with AngularJS
var app = angular.module('myShoppingList', ['ngRoute','ngStorage', 'ngMessages']);
//some code
$scope.listCustomers;
$scope.postFunc = function(){
if ($scope.formCust) {
$scope.listCustomers =this.formCust;
$scope.formCust = {};
}
var urlInfo = "/save";
var config = {
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
var dataArr = $scope.listCustomers;
$http.post(urlInfo, dataArr, config).then(function (response) {
$scope.postDivAvailable = true;
$scope.postCust = response.data;
}, function error(response) {
$scope.postResultMessage = response.data;
});
$scope.listCustomers = [];
$scope.result = 'Success!';
}
});
shipping.html - html file with input form
<!DOCTYPE html>
<html ng-app='myShoppingList' ng-cloak="">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.11/ngStorage.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-messages.js"></script>
<script type="text/javascript" src="/js/main.js"></script>
<title>Shipping Page</title>
</head>
<body>
<h1>Shipping information</h1>
<form ng-submit="postFunc()" ng-controller="myCtrl">
<table>
<tr>
<td><label for="firstName">First name:</label><td>
<td><input type="text" id="firstName" placeholder="Enter first name" ng-model="formCust.firstName" required/><td>
<tr>
<tr>
<td><label for="phoneNumber">Phone number:</label><td>
<td><input type="text" id="phoneNumber" placeholder="Enter phone number" ng-model="formCust.phoneNumber" required/><td>
<tr>
<tr>
<td><label for="cardNumber">Card number:</label><td>
<td><input type="text" id="cardNumber" placeholder="Enter card number" ng-model="formCust.cardNumber" required/><td>
<tr>
</table>
<button type="submit">Submit</button> {{postResultMessage}}
</form>
</body>
</html>
Now my response looks like this:
How i can put each error info near the corresponding field?
For backend validation of the form fields , the best option is to go for Schema Validation
First create your schema that will validate all fields of the object and store this in your class path of backend code.
schema.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from the catalog",
"type": "object",
"properties": {
"firstName": {
"description": "The first name of the user",
"type": "string"
},
"phoneNumber": {
"description": "Phone number of the user",
"type": "string"
},
"cardNumber": {
"description": "Card number of the user",
"type": "string",
}
},
"required": ["firstName", "phoneNumber", "cardNumber"]
}
dependency
<dependency>
<groupId>org.everit.json</groupId>
<artifactId>org.everit.json.schema</artifactId>
<version>1.3.0</version>
</dependency>
This can be used in the Validator class in Java
JSONObject jsonSchema = new JSONObject( new
JSONTokener(JSONSchemaTest.class.getResourceAsStream("/schema.json")));
JSONObject jsonSubject = new JSONObject(userObject);
Schema schema = SchemaLoader.load(jsonSchema);
schema.validate(jsonSubject);
This will validate entire object and return exception if any field is invalid . you can return that exception to Angular JS code from java.
First of all , give your form a name so that it can be checked whether form is submitted or not .
Then span tag can be used within each block for each field as given in the following code .
If form is submiited and any required field is missing then the correcsponsing error message will be shown near the respective field .
<form name="myForm" ng-submit="postFunc()" ng-controller="myCtrl">
<table>
<tr>
<td><label for="firstName">First name:</label>
<td>
<td><input type="text" id="firstName" placeholder="Enter first name" ng-model="formCust.firstName" required />
<td>
<span ng-if="myForm.$submitted && !formCust.firstName">First Name is required to be filled up.
</span>
<tr>
<tr>
<td><label for="phoneNumber">Phone number:</label>
<td>
<td><input type="text" id="phoneNumber" placeholder="Enter phone number" ng-model="formCust.phoneNumber" required />
<td>
<span ng-if="myForm.$submitted && !formCust.phoneNumber">Phone Number is required to be filled up.
</span>
<tr>
<tr>
<td><label for="cardNumber">Card number:</label>
<td>
<td><input type="text" id="cardNumber" placeholder="Enter card number" ng-model="formCust.cardNumber" required />
<td>
<span ng-if="myForm.$submitted && !formCust.cardNumber">Card Number is required to be filled up.
</span>
<tr>
</table>
<button type="submit">Submit</button> {{postResultMessage}}
</form>

Datatable not showing in Spring MVC data

I am trying to get the data from Spring MVC and show it in datatables.
On a webpage, the datatable is showing processing.
I tried to console out my value and in console my arrays are showing.
Can anyone help out?
JSP table:
<div>
<table id="myTable" class="table table-bordered table-striped">
<thead>
<tr>
<th class="col-sm-1">Department Id</th>
<th class="col-sm-3">Department Name</th>
</tr>
</thead>
</table>
</div>
JavaScript code:
<script>
$(document).ready(function () {
table = $("#myTable").DataTable({
"processing": true, // for show progress bar
"serverSide": true, // for process server side
"filter": false, // this is for disable filter (search box)
"orderMulti": false, // for disable multiple column at once
"ajax": {
"url": "/com-employee-record/department/listDataTable.json",
"type": "POST",
"datatype": "json",
"success" : function(data, i){
console.log(data[0]);
}
},
"columns" : [
{ "data": "department_id"},
{ "data": "department_name"}
]
});
});
</script>
Controller code:
#RequestMapping(value = "/listDataTable.json", method = RequestMethod.POST, headers = "Accept=application/json")
#ResponseBody
public List<Department> dataTable(HttpServletRequest request) {
return departmentService.getDepartments();
}
Here is what my console is showing:
{department_id: 1, department_name: "Information Technology"}
I think you need to use the:
"dataSrc": ""
setting, because your API response does not have a top level js property called "data".
The code below is working.
<script src="https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/datatables.min.js"></script>
<script>
$(document).ready(function() {
$('#example3').DataTable({
"ajax": {
"type": "GET",
"url": 'https://jsonplaceholder.typicode.com/todos',
"contentType": 'application/json; charset=utf-8',
"dataSrc": "",
},
"columns": [
{
"data": "id"
},
{
"data": "title"
}
]
});
});
</script>
<table id="example3" class="display" style="width:100%">
</table>
Everything seems to be fine just change ajax part of your code to this
"ajax": {
"url": "/com-employee-record/department/listDataTable.json",
"type": "POST",
"contentType": "application/json",
"dataSrc" : "[]"
},
dataSrc was missing in your code. No need to have success block.

Can not fill DataTable with json data

I am creating java web application. For display data in table i am using datatable plugin. Here is my function which send post to servlet and get json data. When i check returned json i see everything okay but i can not display this data in my datatable.
What is json return:
{"data":[{"id":32,"fullName":"Murad Heydarov Cefer","name":"Murad","surname":"Heydarov","middleName":"Cefer","department_name":"Proqramlasdirma","startedToWork":"11/03/2017","note":"must go this week"}]}
$(document).ready(function () {
$('#example').DataTable({
"ajax": {
"url": "../employer/list",
"type": "POST",
"datatype": "json",
"success": function (data) {
console.log(data);
}
},
"columnDefs": [{
"searchable": false,
"orderable": false,
"targets": 0
}],
"order": [[1, 'asc']],
"columns": [
{"data": null},
{"data": "fullName"},
{"data": "name"},
{"data": "surname"},
{"data": "middleName"},
{"data": "department_name"},
{"data": "startedToWork"},
{"data": "note"},
{"data": "id"}
]
});
});
Here is my Servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
HttpSession session = request.getSession();
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
int worker_id;
String str = (String) session.getAttribute("SID");
SimpleDateFormat tsdf = null;
if (u.module(request).equals("employer"))
{
Gson gson = new Gson();
JsonObject jsonObject = new JsonObject();
switch (u.view(request))
{
case "list":
JsonElement workerListJson = gson.toJsonTree(workerAction.Connect());
jsonObject.add("data", workerListJson);
out.println(jsonObject.toString());
break;
}
}
}
Jsp file:
<table id="example" class="ui celled table" cellspacing="0" width="100%">
<thead>
<tr>
<th>#</th>
<th>full name</th>
<th>department name</th>
<th>started to work</th>
<th>days remain</th>
<th>period</th>
<th>times</th>
<th>note</th>
<th>action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>#</th>
<th>full name</th>
<th>department name</th>
<th>started to work</th>
<th>days remain</th>
<th>period</th>
<th>times</th>
<th>note</th>
<th>action</th>
</tr>
</tfoot>

Datatables Plugin 'ColumnFiltering()'

I have this two codes.
Why get i no filtering options with this code below?
I want the regular filtering for each column
$(function(){
oTable = $('#escapeTbale).DataTable().columnFilter({
"aoColumns": [
{
type: "text",
bRegex: true,
bSmart: true
},
{
type: "text",
bRegex: true,
bSmart: true
},
{
type: "text",
bRegex: true,
bSmart: true
}
],
"sDom": 'TC<"clear">lfrtip',
"bJQueryUI":true,
"sPaginationType": "full_numbers",
"processing": true,
});
my HTML Code:
</tbody>
<tfoot>
<tr>
<th>name</th>
<th>address</th>
<th>age</th>
</tr>
</tfoot>
many thanks ;-)
Please ensure that you have included 'columnFilter.js' in your html and need to follow table structure with thead and tbody as below to make datatable plugins working
<table id="escapeTbale">
<thead>
<tr>
<th>name</th>
<th>address</th>
<th>age</th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td>address</td>
<td>age</td>
</tr>
</tbody>
</table>
Also check that function name dataTable starts with small d and not caps D. But may be this does not matter much

Json serialize to java pojo with nested List<pojo> property

Below is my code attempt to post an Json serialize object (java pojo having list of other pojos) with JQuery Ajax call to Spring MVC controller.
Getting Bad request error from server.
When the modalForm data is removed from the Json object the MainPojo data received correctly at server side.
Html Code
Fisrt form
-------------
<form id="mainForm">
.....
</form>
Form in the modal
-----------------
<form id="modelform" ..>
<div id="row">
<input type="text" id="subject" />
<input type="text" id="max" />
<input type="text" id="min" />
</div>
<div id="row">
<input type="text" id="subject" />
<input type="text" id="max" />
<input type="text" id="min" />
</div>
.............
</form>}
Jquery
var mainObject = $('#mainForm').serializeObject();
var modelObject = $('#modelform').serializeObject();
mainObject.marks = modelObject;
Json ( Expected)
{
"name": "Some Name",
"age": "10",
"marks": [
{
"subject": "maths",
"max": "20",
"min":"12"
},
{
"subject": "english",
"max": "20",
"min":"12",
}
]
}
Json (actual output with the above code)
{
"name": "Some Name",
"age": "10",
"marks": [
{
"subject": "maths",
"subject": "english"
},
{
"max": "20",
"max":"20",
},
{
"min": "12",
"min":"12"
}
]
}
//Ajax call
$.ajax({
url: '/save',
type: 'POST',
contentType: 'application/json',
mimeType: 'application/json',
data : JSON.stringify(mainObject),
dataType: 'json',
success: function(data) {
alert(data.msg);
},
error:function (xhr, ajaxOptions, thrownError) {
alert('Technical error occured');
}
});
Java Pojo's
public class MainPojo {
private String name;
private String age;
private Lists<marks>
..................
}
public class ModelPojo {
private String subject;
private String maxMarks;
private String minMarks;
.....................
}
Controller Method
#RequestMapping(value = "save", headers = "Accept=application/json",
method = RequestMethod.POST)
public #ResponseBody String save(#RequestBody final MainPojo mainPojo) {
}
Please help me to identify the problem.
Thank You.
Modify html text like this
<form id="mainForm">
<input name="name" type="text" value="Some Name">
<input name="age" type="text" value="20">
</form>
<form class="modelform">
<input type="text" value="subject" name="subject"/>
<input type="text" value="max" name="max"/>
<input type="text" value="min" name="min"/>
</form>
<form class="modelform">
<input type="text" value="subject" name="subject" />
<input type="text" value="max" name="max"/>
<input type="text" value="min" name="min"/>
</form>
Then write javascript code to assign object value
<script>
var mainObject = $('#mainForm').serializeObject();
var modelObject = [];
$('.modelform').each(function(o){
modelObject.push($(this).serializeObject());
})
mainObject.marks = modelObject;
</script>
i have
#RequestMapping(value = "/save", method = RequestMethod.POST)
public #ResponseBody
MyEvent saveOrganization(#RequestBody Organization organization) {
return new MyEvent('save',organization);
}
y your mvc-servlets.xml
<context:component-scan base-package="com.jrey.project.controllers" />
<context:annotation-config></context:annotation-config>
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
my jquery post
$.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;
};
<script>
$(document)
.ready(
function() {
$('.submit', '#form')
.click(
function() {
var data = JSON
.stringify($('#form')
.serializeObject());
console.log(data);
$
.ajax({
type : "POST",
url : '${pageContext.request.contextPath}/controller/organization',
data : data,
dataType : 'json',
contentType : 'application/json;charset=UTF-8',
success : function(data) {
$(
'<div>'
+ data.message
+ '</div>')
.dialog(
{
title : 'Organizacion',
modal : true,
buttons : {
'Aceptar' : function() {
document.location.href = data.location;
}
}
}
);
},
});
});
});

Categories