I'm building a web page using spring that needs to build a table using an API call that returns a dynamic number of elements.
Here is what I have now:
@RequestMapping(value = "/managecustomerconfigurations", method = RequestMethod.GET)
public ModelAndView setUpPage(){
ModelAndView model = new ModelAndView("customerconfigurations");
model.addObject("cdata", custServe.listAllCustomers());
return model;
}
I can get cdata in my web page if I type
<p th:text="'Customer:' + ${cdata}" />
but I cannot see it if I just type
${cdata}
or if I put the data in any JavaScript (even if I use an onload method)
Quick sidenote: I am using HTML 5 not JSP.
Ideally I would want to pass in the API response into JavaScript and build a table based on that response.
I'm building a web page using spring that needs to build a table using an API call that returns a dynamic number of elements.
Here is what I have now:
@RequestMapping(value = "/managecustomerconfigurations", method = RequestMethod.GET)
public ModelAndView setUpPage(){
ModelAndView model = new ModelAndView("customerconfigurations");
model.addObject("cdata", custServe.listAllCustomers());
return model;
}
I can get cdata in my web page if I type
<p th:text="'Customer:' + ${cdata}" />
but I cannot see it if I just type
${cdata}
or if I put the data in any JavaScript (even if I use an onload method)
Quick sidenote: I am using HTML 5 not JSP.
Ideally I would want to pass in the API response into JavaScript and build a table based on that response.
Share Improve this question edited Jul 23, 2018 at 19:43 Mahozad 25k19 gold badges159 silver badges182 bronze badges asked Mar 30, 2015 at 15:06 rbodrbod 611 silver badge5 bronze badges 2-
You should tag your question for
thymeleaf
, it totally changes the scope of the issue. Take a look at: thymeleaf/doc/tutorials/2.1/thymeleafspring.html – woemler Commented Mar 30, 2015 at 18:18 - ah ok doing that now. – rbod Commented Mar 30, 2015 at 18:49
3 Answers
Reset to default 2Dynamic content in Thymeleaf has to be defined only as th:attributes inside standard html tags. Html rendering engines just ignore unknown attributes unlike unknown tags or expressions within page content.
This is the main idea behind Thymeleaf's natural templating design, so there is no clutter of third party tags and expressions when statically displaying the page. Unlike jsp, the template processor resolves th:attributes only, not expressions elsewhere in the page so that's why your ${cdata}
does not work outside th:text
.
I believe (and I have used it successfully in production) that the cleanest way to pass back-end data to javascript in non-ajax way, is to use html5 data attributes. Html5 allows arbitrary attributes prefixed with data-
without plaining.
So you can use a container div for example to pass the data like so :
<div id="Some-Container" th:attr="data-someDescription=${cdataJson}"></div>
then if you use jQuery you can retrieve easily all html5 data attributes as jQuery data:
$("#Some-Container").data("someDescription");
If not using jQuery but some other js framework, there is probably some similar way. In plain js you just have to write more code.
Now, in order to export your data as a json formatted text, for being easily consumable by javascript, you have first of all add an object mapper in your application context :
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
declare an dependency in your controller:
@Autowired
private ObjectMapper jsonMapper;
and then, when you add the model attribute, use the object mapper to convert data to json:
String cDataJson = jsonMapper.writeValueAsString(custServe.listAllCustomers());
model.addAttribute("cdataJson", cDataJson);
If you are not using JSP, you are not going to be able to do string replacement in your HTML or JavaScript to plug the content of cdata
into your document. Even if you were using JSP, your object would need a valid toString()
method to convert it into readable JSON text. If you want to get your domain data into your web page without using JSP, you will have to fetch it via AJAX. Assuming your customer objects do not have any plex embedded objects, you should be able to serialize them pretty easily and read them into your page as JSON.
Create a new controller method for handling AJAX requests:
@RequestMapping(value = "/customerdata", method = RequestMethod.GET, produces = { "application/json" })
public ResponseEntity<List<Customer>> getCustomerData(){
List<Customer> customers = custServe.listAllCustomers();
return new ResponseEntity<>(customers, HttpStatus.OK);
}
Then request the data on your page in your JavaScript:
var cdata;
$.ajax({
url: "/customerdata",
dataType: "json",
method: "get"
}).done(function(data){
cdata = data;
//do stuff
});
Here is a dynamic dropdown without jquery using spring.
<select name="CustomerList" th:field="*{cdata}">
<option th:each="task : ${cdata}" th:value="${task}"
th:text="${task}"></option>
</select>
on the Spring side
@RequestMapping(value="/managecustomerconfigurations", method=RequestMethod.GET)
public ModelAndView setUpPage(){
ModelAndView model = new ModelAndView("customerconfigurations");
try{
JSONObject obj = new JSONObject(custServe.listAllCustomers());
List<Integer> list = new ArrayList<Integer>();
JSONArray array = obj.getJSONArray("returnObject");
for(int i = 0 ; i < array.length() ; i++){
int j = array.getJSONObject(i).getInt("id");
list.add(j);
}
model.addObject("cdata", list);
}
return model;
}