Spring-mvc + Thymeleaf: dealing with complex form - javascript

I'm working on an internal tool using spring-mvc and thymeleaf.
A section of this tool is used to create an entity we save in the database.
This entity is quite complex; it contains many properties and relations. Some of these relations contain list and other properties.
I have 2 constraints:
Single page. No "wizard".
To only save a completed object in the database.
Now, I'm not really asking for a specific issue. I know my way around thymeleaf, spring #ModelAttribute, etc.
My question is mostly which strategy are you choosing or how to deal with really complex object creation.
Now I can see 3 ways to do it :
Rendering page with thymeleaf. Every time a new element need to be added to a list, I use Ajax to add the new element on the server and rerender the specific fragment. So doing back and forth to the server with my #ModelAttribute and only save at the end.
Rendering a basic page with thymeleaf. Using JavaScript to create html elements and instead of submitting to a #ModelAttribute, I'm serializing my form to JSON and submit this JSON to the server. (kind of client side model)
Rendering a basic page with thymeleaf. Create the html element dynamically with JavaScript when I need to add list item (being sure I'm putting proper name="" to fit with my Java form object) and submit the whole thing at the end.
I'm personally unsure between 1 or 2.
I feel dealing with complex object is much more easier using JSON than form submission. Also, the input value/field with sub object and property can be quite nasty. Having this kind of syntax
does not sound great to me...
3 can probably work but the way spring data binding is done with sub property is lacking some detail in my humble opinion (section 7.4.1 - http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html).
What do you think ?

Personally I use Thymeleaf's own dynamic field management to ensure clean addition of objects and fields to object.
So I will recommend option 4: Dynamic Field management by Thymeleaf.
Have a read of http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields.
I use that for both single field additions as well as addition of nested forms. Does the trick no questions asked.
Hope that helps.

Related

Alfresco custom UI controls - Associations

I'm trying to build a custom UI control in alfresco to display the associations of an object type that I have.
Basically I have two object types; Code, which is a key value pair, and CodeScheme which contains multiple child associations to codes, it's essentially a mirror of a map structure I have in a different system.
The problem I have is that the codes are automatically generated, so they get the UID names, whereas really I'd like to present them as 'key=value', 'key=value', etc (ideally I'd like to present it as a table).
I've already created a custom control and added it to share-config-custom, and confirmed that the configuration is working correctly. What I'm not really clear on now is:
a) How to attach a javascript to the control so that I can process the association data.
b) How to get hold of the codes in javascript, and read their properties.
I'm just looking for a push in the right direction.
Thanks :)
One idea would be to use a form filter. Your form filter could iterate over the child references, fetch each child node, grab the data you want to display and then add one or more new properties with that data.
Then, your form control is hooked to the fields your form filter dynamically added to the form data. It can then read and display the data as needed.
Without a form filter I think you'd have to use JavaScript to parse the child association refs and use AJAX calls to fetch each child's node data, then format that as needed. The form filter idea would be less traffic from the browser.

How to ng-include a partial view that requires a lot of data (parameters) to be rendered?

I have a Angular.js Web UI for editing complex and large mathematical objects. I'm trying to build a view that displays results for such an object. Thus, the edited object needs to be sent to the back-end and the back-end would compute a partial view based on its data.
The ordinary (easy) way of doing so would be to use the ngInclude directive:
<div ng-include=".../resultView?data=[JSON_stringyfied_object_here]>
This works. However the problem is that the object can be quite big in terms of numbers of chars used in a JSON representation (as they contain a lot of floating point number and dates etc.). So, I'm afraid of running into practical limitations of the length of a query string.
Instead, I'd rather send the object as payload of the GET (or even POST?) request. I'm just not sure how to accomplish this the Angular way. Is there a way of doing so?
Worst case, I can also live with a solution that displays a "Compute" button which would then fetch the partial view by calling a function that uses $http. How would I include this view in the DOM in this case?
I appreciate any hints in how people would tackle this problem.
EDIT: The view can look quite different depending on the (dynamic) type of the mathematical object and its computed results. Thus, rendering a static view and then filling data won't work.
What I would do is use ng-include to include a static templated page and then make a $http.put call to fetch the data and have it populate onto the templated page.

What is meant by 'tying data to DOM' in JavaScript, and why is it bad?

Almost all articles say that tying data to the DOM is bad. But what does that mean, exactly; and how can I avoid it?
Usually separating application logic, data and the display of data makes the application itself more clear and easy to maintain. Usually each part has their own separate problems (how to organize user data (model) is not related to what color/position username should be shown in on screen). How the username is transferred to the screen (controller) is also separate from the display (view).
I don't know which case you mean by tying data to the DOM, but one risk is that your model & view get mixed and it becomes difficult to separate display from data.
One way of doing this is MVC (model-view-controller) division and other similar separations like MVVM etc. Some more about MVC here.

How to handle non-trivial form input? JSP or Javascript?

I'm working on a Spring MVC app, which should let user alter contents of a list.
The list consists of Book-objects with simple properties like name and author. The view is a JSP page that displays the list of books and lets the user alter the contents.
Altering the list can mean adding books, removing them or changing the order of the books in the list.
Question is, how do I get the altered list back to the server? I can write JavaScript to control the list, but how do I post it to the Spring controller? On the other hand I can write a JSP form for altering the model which would be trivial to submit back to the server, but am I then limited to basic text fields in form input?
EDIT:
In JSP it is very easy to alter a single model's properties using a form like
<form:form action="myaction" method="post" commandName="mybook">
but if your model is a (ordered) list of objects then how do you edit it?
In Javascript I can get the list of objects from the response and change it as needed, but how do I submit it back to the server? Something like
$.post("/modifybook.do",{ name: "Spring in Action", author: "Graig Walls" } );
works, but only for single objects.
Having never used Spring this may well not be appropriate but could you not convert the list into XML and then post that back to Java and then work on it retaining all intricacies and changes?
You should avoid manipulating the whole list, period. I can't see a scenario where populating entire list of items and sending it back to the server is desired, when only one list element is being changed (edited, added or removed).
What I usually do in my app is I create a handler (controller) for returning a whole list of objects in one go and then add another handlers for adding, editing and removing single entries within that list. I also try to stick to REST in such scenarios, so that I have a clean API which represents server resources and the frontend (AJAX + jQuery) makes use of it.
This solution works really well for me so I suggest sticking to it as well.

Passing data between elements in UI

I'm new to web applications and am trying to understand the best way to work with data in HTML. I'm using Appengine (Python) and have managed to load a bunch of data to the view. In the simplest form, it's a set of movie names and each name has associated details with it (e.g. year, rating etc). Now how do I pass data between the movie link and then a div where all the details will be displayed? I'll be using jQuery for some controls in my application so I'm wondering if there's a way to do data binding to controls with that?
Additionally, can anyone tell me what're the standards around this i.e. if I load all this data to the UI in one call (assuming it's not a lot of movie titles), wouldn't it make it easy for people to screen scrape this information? Or is there some obfuscation that's typically used here?
Sorry if I'm not very clear but I really am an absolute beginner with web development!
Update1:
I found the jQuery data() api. It seems like this'll work. Comments?
Update2:
Some testing later and it turns out that data() actually attaches the data to the elements rather than showing it in a div itself.
There's a few ways to do it but the basic idea is to put the data in the HTML in a way that is not visibly rendered, then use Javascript to parse the HTML and pull the data out when you need it.
The easiest way on modern browsers is to use data- attributes. These are any attribute that start with data-, and you can name the rest yourself. For example:
Czar Wars
In this case, the user will only see a link called "Tsar Wars" but your javascript can easily access the data- attributes to get the data it needs. The other benefit of this approach is that jQuery will automatically make data- attributes accessible by the data() api.
Another way to do it is to have a hidden HTML list element with all your data elements in the list, but you'll have to parse this all yourself.
There's no standard obfuscation. You'll need to obfuscate yourself on the server side, and unobfuscate in your JS. It's not too difficult to figure out any obfuscation algorighm in js, so this is not worth your while.
If the data really is private, then you would have to architect it as to do all the processing on the server. For example, only show tokens (like 1234), and use AJAX calls to pass the token to the server so the server can do the data processing and spit back publicly safe results to the script.

Categories