I'm building a page that has a search box that will populate a grid on the same page. There is also a button the user can select to bring up a "window" (JQuery UI "pop-up" in the same page) that lets the user configure said grid.
These are two separate forms but I don't want what was submitted as part of one to undo the other (so when the user submits to change the grid layout the search needs to re-run as well.
I'd rather not store things in session for this since that brings with it its own issues (search results may be large, shouldn't be saved when the page is re-entered later, etc.).
I've considered doing "one large form" (i.e. surrounding all the inputs) for the entire page that is backed by a form backing bean. I would then use which button is clicked to determine the action to take. There will eventually be other buttons on the page as well to add more functionality. This would be similar to how .NET (non-MVC) handles things.
I'm interested in how others may have solved similar challenges. Are there potential issues with my approach that I'm not seeing? Better ways that work with the framework?
What do you mean with:
but I don't want what was submitted as part of one to undo the other
. Are you referring to posting the form and loading the whole page, which in turn will "reset" the other form?
If that is the case I would still keep one page with two forms and make the posts using Ajax (as you may know jQuery makes this a breeze). Upon receiving a response for either call you will need to update the other form accordingly.
Note that you may still have your forms in two separate views if it helps keeping the code clean and then pull their html with Ajax calls into another view. But my point is that at the end I would still keep both in one page since it sounds like they depend on each other so updating one when the other changes may be easier this way,
Let me know if I misunderstood your question.
Related
As I train myself on Selenium, I'm using Page Object Model as my design. My practice site is https://www.beeradvocate.com (I like beer and it's presenting some testing challenges I was looking for).
Once such instance is a page overlay or modal window.
I know in POM each page has it's own Class where the page objects are located and the corresponding methods/actions to be taken upon them. Furthermore, if I click a link that navigates to another page, that would return a new page object in the function such as:
return new HomePage();
When the Login link is clicked it generates an overlay modal window. It seems that Frames aren't treated as their own Page Class. It takes a switchToFrame() action. Would the same apply for this overlay? Perhaps just a getWindowHandles() action to navigate to it?
I'm working on this too, and the main problem is that you need to find a way to login to the website. If you are not logged in, you can get only actually receive the first 25 reviews..
I would suggest creating a separate class to represent your modal, especially if it's shared by other pages or may be moved out of that page one day.
But if the modal is super-simple and only included on one page and really specific to that page, then it could be represented by a group of functions within that POM. However you'd need to recognise those methods as a "region" or a sub-group in some way, like namespacing the methods, or using decorators, which I always think in OO terms smells like there's a sub-object here which needs dividing out!
Dividing and composing is pretty cheap in Java so there's not much penalty. But having a big page object with tons of "sub components" can get messy. It probably depends on how well sub-structured the site itself is which will guide your decision. Like if the selector for the modal is relatively clean and separate from the host page itself, it's less "owned" by the page.
This similar answer points out that a "POM" is more of a module reprentation than an entire "page" (whatever that means these days!).
https://stackoverflow.com/a/47141290/209288
This answer also asks the same question.
https://stackoverflow.com/a/49002231/209288
I came looking for a similar answer, and have just made my mind up to decompose my modals, while reading these discussions. (So my answer is based on 15 minutes of thought, not experience!)
How can i get the page URL in single-approver-definition.xml in the e-mail template that is used to send an e-mail to the content creator once the reviewer approves or rejects the submission. The existing xml is as follows:
<template>
Your submission has been reviewed and the reviewer has applied the following:
${taskComments}.
</template>
I tried ${serviceContext.getAttribute("contentURL")} and it didn't work.
I want to be able to do - Your submission for ${pageURL} has been reviewed and the reviewier has applied the following: \n ${taskComments}.\n
Any suggestions will be appreciated.
I don't get what variable exactly you want to process in your notification. As I can only assume, you are using it for Web Contents and all interesting variables are stored in two places.
Workflow context variables - they are available directly. Few examples like:
${taskComments}
${entryType}
${userId}
${userName}
...
ServiceContext variables - they are available using $serviceContext. Few examples:
$serviceContext.getAttributes().get("version")
$serviceContext.getAttributes().get("articleId")
${serviceContext.getPortalURL()}
...
For all interesting variables check this url https://www.liferay.com/web/igor.beslic/blog/-/blogs/workflow-in-action-kaleo-workflow-context-variables Some could change already, however most of them is working fine for current version.
Content changes might be made on a page, they can also be triggered through Control Panel (or the API for that matter). When you're in a workflow, you typically don't have this context any more - if you find it somehow I'd not rely on it to be there. A workflow is unrelated to the UI and pages.
Also, an article might be submitted on one page, where it might be replaced/removed before it's even approved. In that case the link wouldn't help.
What might work is to check the concept behind "Web Content Display Pages" (if your article has them configured and you deal with web content). But the mechanics will vary depending on the actual content type you're dealing with. And content that goes through workflow might not be displayed on any page at all (e.g. when submitted through Control Panel) or on many different pages (either explicitly - Web Content Display - or implicitly - Asset Publisher).
#tomic basically provides pointers to what you have, I'm only reasoning why your initial problem is problematic to solve at best - it's not fully specifiable.
We pull data from server and for that If we are using Struts, then we can pull either by submitting a page which MVC Architecture or we cam make an AJAX call but conventions is of using forms and render response but we also face challenges to give rich user experience, so we compromise convention and start using excessive AJAX, so how we should make balance between two?
I personally think that AJAX should be used for displays updates and form submissions should be done via a page reload. Reasoning?
When submitting forms, you are telling the application to do something. Users tend to want to feel that it was done. When a page doesn't reload, users are often left wondering "Did that work?". Then they have to check to make sure what they did was right.
On the other hand, when you are displaying a chart or something, and the user says to "display 2011 data....now 2012 data" for instance, they aren't "doing" something (creating new entities, sending emails, etc). So AJAX can provide a nice user interface in this case. Page reloads would be annoying here.
In conclusion, I think form submission should be done via page reloads (let the user see it working), whereas display updates should use AJAX (prevent annoying page reloads).
Of course, this is a preference thing. Some of my company's applications use AJAX all over. But those are the applications that are the most difficult to maintain and debug. ;)
Regular old HTML form submission and fancy ajax forms are not mutually exclusive.
First, make the plain HTML form work correctly. Then, add javascript to hijack the form and send an ajax request.
The controller and model don't care if the user's browser supports (or has enabled) javascript. The rendered view is decided by whether the call was made with javascript or a simple form submission. This is one of the strengths of the MVC pattern, not a constraint.
I think that the choice between the two is somewhat intrinsic:
a form submission is synchronous and it reloads the page.
an ajax call is asynchronous and it does not reload the page.
If a certain action will change a lot of UI elements or needs to poll a lot of data to be rendered, I would go with form submission. On the other hand, if a certain action is used for simple actions, like populating a select box or improving user experience, then I would go for an AJAX call.
There is nothing avoiding you to use as many ajax calls or form submissions as you need, so in the end is up to you.
In this day and age, there is virtually no case to use the old standard HTML form submission method (other than pure nostalgia, or perhaps not knowing).
The <form> tags themselves can still be useful if you want to take advantage of the .serialize() function (which grabs all name-data pairs within the form into a query string), but other than that we don't need to use <form> tags at all these days.
Using AJAX, the developer has more control over the entire process, in a more condensed code base. But more importantly, we just don't do things that way anymore.
Consider:
(Old Style - Forms) When an HTML form submits: (a) it gathers the form field name= attribute values (these become the defacto variable names) (b) together with user-entered data in the form fields (which become the variable values), and posts these data-pairs to a PHP file (as specified in the action= attribute on the form tag). THEN, the page changes to that other page, causing a noticeable refresh of the screen and loss of all previously inputted user data. Even using the trick action="", wherein the form data is posted back to the same page it started from, the page is still reset/refreshed.
(New Style) Exactly the same process can easily be programmed using javascript/jQuery - except that the page does not refresh. All previously entered user data/text can remain undisturbed.
Back to your question:
With the old-style HTML form submission, the page changes - so if you want to do field validation you use javascript/jQuery to cut into the submit process, thus:
$('myform#btnSubmit').click(function(){
var some_fields_failed = false;
//check form field values here, set: some_fields_failed = true
if (some_fields_failed){
return false; //halts the HTML Form Submit process and returns control to the user
}
});
in which case you already are using most of the AJAX construct that would replace the HTML form submission process.
This simple introduction to AJAX provides some compelling reasons to use AJAX instead of the old-style HTML Form Submission process:
AJAX is a developer's dream, because you can:
Update a web page without reloading the page
Request data from a server - after the page has loaded
Receive data from a server - after the page has loaded
Send data to a server - in the background
Note that you can write ajax code in pure javascript, but until very recently it was considerably simpler (much less typing, more consistent) to use the jQuery (javascript) library. Hence, all examples above use jQuery. To include jQuery in your project, it is only necessary to include a reference to the jQuery library:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
StackOverflow maven, Schabse Laks, created a simple jQuery tutorial that is worth stepping through (IMPORTANT: Use Down Arrow to step through the pages)
If you have errors between submissions of data the only forms method you could check on the server. On the other hand if you make Ajax calls you could check that errors on the client side. So, out of this different technologies of transmitting data we could follow a decision that they serve different purposes.
When sending a form with AJAX, you generate the POST request and not the browser, so you have more control over it. Even if you don't need that control to begin with, in time it might become necessary.
One case would be protection against CSRF attacks on forms. It can be implemented by adding a hidden form input field containing a CSRF token, which is sent together with the form data. But a preferred implementation would be to add a custom header to the submitted POST request. However, you can't do the latter when using the old form submission method - the browser composes the request and you can't add your own headers.
I have to 4 objects, Group, sections and Questions and their options. Every Group has different Sections and Sections have Multiple Questions and Questions have options. Now I have to design form input system so that every group and sections can be covered up step by step. I’m doing all this in spring mvc.
Can you tell me a way, how can I solve this problem?
You can surely do that in Spring MVC thanks to easy list binding.
Spring MVC allows a big lot of freedom, so basically if you only use this framework, you will have to come up with a solution from scratch.
Here is a use case and a solution. It is a bit tough to implement, as it is from scratch. Feel free to adapt it to your specific needs, add whatever fancy UI framework you want, but you should get a general idea. You can skip to part III for a quick answer.
Let's say you want to create/edit a group in one single page :
you want to edit/add sections to the group
you want to edit/add questions to any section
you want to edit/add options to any question
I. Page design :
You have a JSP Group page with one big single form (again this is just an example)
There will be buttons to add nested stuff. When clicked, some javascript will show a blank form allowing with the information of the stuff. This blank form will itself have buttons to add nested nested stuff to it, and so on (until the stuff is an option).
The design is the same for existing stuff that you want to display/edit, except that the forms won't be blank
You are able to tell whether you are creating or editing the current group (context of the page or javascript/html tricks).
There may be a list of existing sections you could "drag & drop" inside a group thanks to some javascript/jQuery
II. Code design :
You have a GroupController corresponding to the JSP
The Group object has a List<Section> sections attribute, the Section object has a List<Questions> questions attribute, etc.
You have methods createGroup and editGroup
When submitting your JSP form and calling createGroup or editGroup, you are able to know if the submitted elements of the group already exist, so you can decide to add or edit/update them in the DB. All this logic could be done in another class, like a Spring service.
You always provide a possible list of existing sections (by adding this list to the model in both methods, or better yet, by doing a single method annotated with #ModelAttribute). This list could be computed in another class (a Service/DAO/both which taps the DB in the end).
III. The magic : binding the JSP form with the Java controller :
In the page you'll have a <form:form commandName="group">, and in the controller methods parameters you'll have a #ModelAttribute("group") Group group.
Now, to submit the name of the very first option, you would have this in the JSP :
<form:input path="sections[0].questions[0].options[0].name" />
(or the equivalent in html generated by some javascript).
I have a Java web application which stores some data in the session. The data in the session changes as the user interacts with the application (e.g. flow is managed by a controller, each controller has several form pages, on each form page some data is updated in the session and flow goes to the next form page).
The problem is that some users are opening more than one tab to the application, each tab with a different step in the flow. At this point data in the session is messed up since the tabs share the same session (app uses cookie managed sessions).
Telling the users to use different browsers to avoid sharing the same session id (e.g. one Firefox window and one IE window) is not an option since surely at some point somebody will forget to do this and instead use tabs, thus messing up their data.
Adding some verifications that detect that another flow is requested from another tab and display a message to the user saying this is not allowed is not an option either since it pisses of the users and we don't want that do we? :D
The fact is that using another tab is useful for the users because they are more efficient in what they use the application for, so I am keeping this option. But the question now is how best to manage the one session data for the more tabs?
What I thought of, was to have the controller generate a token when it starts the flow and pass this token to each form page which in turn sends it back to identify itself. If another tab requests the same controller action when there is an ongoing flow then generate another token and pass that around.
Basically, I want each flow to have a token and inside the session I won't just keep one set of data but have a set of data for each token and then match requests based on the token.
Now the problem is that this approach will need a lot of rewritings to the application and I was wondering if there is a best practice for managing such a situation or can someone suggest other approaches. I am open to ideas.
Have you encountered this situation? How did you handle it?
This is usually done by assigning a windowId for each tab/window and passing it on each request. Jsf supports this via orchestra. Spring mvc will support it in the next version.
I recently needed this for a simple case, so I implemented it myself. Took half an hour. However, my scope was very limited:
pass a windowId with each request, and return it back for the next request. The first time - generate it.
for any attribute you want to store in the session, put a Map<String, Object> where the key is the windowId
This is exactly what Seam was created to handle. In Seam there's a concept called a Conversation which basically does exactly what you are explaining. Conversations are basically are a way to divide the Session into many pieces that can expire at some timeout. You can look at the source code for org.jboss.seam.core.Manager class to see how it's actually implemented and get inspired ;)
Depending on the complexity of your application, you may want to investigate implementing tabs within your application. This gives you wholesale control over the flow, while still providing users with the functionality they want. I'd argue it's, bugwise, the most robust solution, since you won't have a dependency on the way the browser handles sessions, minimising the number of "known unknowns".
Of course, there'll be potentially a large upfront cost to this, depending on how your application is structured. Without more information about your app, you're the best placed person to decide.
You can also try to wrap your application inside Adobe Air
And then limit your web application to be only accessable from this air. By doing this you dont need to consider the web browser fragmentation and their unique behaviour.