Struts 2 - Conditionallly display elements on page based on validation errors - validation

I'm looking into the fielderror tag for struts and was wondering if it was possible to conditionally show certain elements on the page based on whether or not there are any validation errors. I want to do something like this (which currently does not do what i want it to):
<s:fielderror>
This is a test link
<s:param>field1</s:param>
<s:param>field2</s:param>
<s:param>field2</s:param>
</s:fielderror>
I would like the anchor tag to show up ONLY if one of the fields referenced by the param tags is invalid. In other words, if something is invalid in this fielderror block, I would like to display some HTML. The way it is coded above, the anchor tag is always displayed.
I think I can certainly do this with jQuery, but i was wondering if there was a way to do this natively in Struts that perhaps I'm overlooking. I've tried looking at things like the label and title attribute, but nothing seems to be working.
thanks in advance!
~j

There's nothing out-of-the-box, at least not like the way you want it.
Personally, I find your construct quite counter-intuitive: it doesn't execute/render like it reads.
A few options: do it "manually", create a tag to do it, or do it outside of the view. All rely on using ValidationAware.getFieldErrors() to grab the map and do some minimal logic.
The manual approach would use <s:if> to check for the presence of fieldErrors['fieldName'] for each field. Wrapped up in a simplistic JSP-based custom tag would produce something like:
<if:fieldErrors for='field1, field2, field3'>
<a ...>
</if:fieldErrors>
IMO doing most of the work in Java is cleaner, and easier to test. This could mean doing all the work in the action (or utility) and exposing only a single flag to the view, or using a thin JSP-based tag to call the utility. Either way, it's easier to test outside of a container, and removes inappropriate view logic.

Related

Can Capybara select a checkbox or radio button within the scope of a specific field

I'm using Capybara on a form that has multiple checkbox fields with an "Other" option. The Capybara API gives us
page.check('Other')
but no way (that I can find) to limit the scope to a given field. You can limit the scope based on a CSS (or XPath) selector, but since none exist that make sense this requires that I either change the (ugly legacy) markup of the page just to accommodate Capybara, which seems like the wrong solution. (In a perfect world I'd have time to completely refactor the markup, and wind up with something semantically sensible that also gave me a way of selecting a scope for Capybara, but this is not a perfect world, and I don't want to just jam in classes all of the place to accommodate Capybara.)
This
page.within('[name=FieldName]') do
page.check('Other')
end
doesn't work, either, since Capybara is looking for a single parent node that it can use as the scope, and this gives a set of checkboxes. (It would be nice if Capybara supported that, but it doesn't.) It's like I'm passing a deck of cards to search through, and Capybara wants the box the cards go in, but I don't have any box.
I'd like to be able to do something like this
page.check('Other', :in => 'FieldName')
but I can't find anyway of doing that. As far as I can tell, the only options that can be passed in are text, visible, and exact. Am I missing something? Is there a way to do this without resorting to ugly workarounds?
Since you have a css-selector that can find the checkbox, you can use the find method to locate the checkbox.
page.find(:css, '[name=FieldName][value=Other]')
Then to check the checkbox, use set (which is used by the check method):
page.find(:css, '[name=FieldName][value=Other]').set(true)
You could also use the click method:
page.find(:css, '[name=FieldName][value=Other]').click
This is not the most elegant solution, but since no one is posting a better one (so far), here's the best I've come up with.
Just execute a script to do what you need. In my case I'm using jQuery:
page.execute_script('$("[name=FieldName][value=Other]").trigger("click");')

nl2br in JSF2 without violating MVC paradigm?

i'm trying to figure out how to most elegantly integrate something like PHP's nl2br() function into a current project done with JSF2/Spring. I could easily create getters using something like return text.replaceAll("\n","<br/>"); in my model classes, however that does seem like putting view related code where it does not belong. I have the same feeling about storing actual html content in my database.
I guess the cleanest solution would be using tags/EL for this, however i couldn't find something that seemed to do just that. How would you guys implement something like this? Thank you in advance, any hints are highly appreciated!
Use either CSS, assuming that the text doesn't contain any HTML
<div style="white-space: pre">#{bean.text}</div>
Or create a custom EL function and then display it unescaped (Facelets implicitly escapes HTML)
<div><h:outputText value="#{my:nl2br(bean.text)}" escape="false" /></div>
You should only make absolutely sure that it's free of XSS.
Well, in the first place JSF is a Web UI framework. So, anything that you expect to output to the user will end as HTML (with the only exception of javascript, though). So, I don't find it a grave violation of MVC (if any at all). Maybe you could even push the envelope and directly use <br/> inside the text, instead of replacing \n
In a more general sense, if you have different lines/paragraphs in your text, the more flexible/standard solution would be break your text in the different elements and let your presentation logic handle it. So, instead of a properties with
presentationPage.introductionText=Ipse Lorum ...sum.\nVini vidi vinci.
You would end with
presentationPage.introductionText.par1=Ipse Lorum ...sum.
presentationPage.introductionText.par2=vini vidi vinci.

In Zend Framework applications, what purpose does the /views/filters serve?

I have an idea of what view helpers do (/view/helpers), but I have no idea what a view filter (/view/filters) is, or what its used for, can some one please shed some light on the matter?
Thank You =)
At the end of rendering a view, Zend_View passes the output to any filter(s) you have registered, by calling the filter() method on the filter object.
One use of a filter could be to minify HTML output, stripping comments and whitespace to reduce the size of the content to send over the network.
In theory, you could write more sophisticated filters, that modify the DOM, altering, hiding or removing page elements. I wouldn't do that because it's more efficient for the view to render elements right on the first pass, than to tweak them with DOM operations after rendering. Or you could modify content, such as to translate English into French on the fly (if you had an automatic way of doing that, which ZF does not provide).
Zend_View filter is unfortunately undocumented, which makes me think there is little demand for it. I suspect that view filters are basically a victim of YAGNI. They were implemented without a good use case in mind.

extract xpath

I want to retrieve the xpath of an attribute (example "brand" of a product from a retailer website).
One way of doing it is using addons like xpather or xpath checker to firefox, opening up the website using firefox and right clicking the desired attrbute I am interested in. This is ok. But I want to capture this information for many attributes and right clicking each and every attribute maybe time consuming. Also, the other problem I have is that attributes I maybe interested in will be there for one product. The other attributes maybe for some other product. So, I will have to go that product & then do it manually again.
Is there an automated or programatic way of retrieving the xpath of the desired attributes from a website rather than having to do this manually?
You must notice that not all websites use valid XML that you can use xpath on...
That said, you should check out some HTML parsers that will allow you to use xpath on HTML even if it is not a valid XML.
Since you did not specify the technology you are working with - I'll suggest the .NET HTML Agility Pack, if you need others, search for questions dealing with this here on SO.
The solution I use for this kind of thing is to write an xpath something like this:
//*[text()="Brand"]/following-sibling::*
//*[text()="Color"]/following-sibling::*
//*[text()="Size"]/following-sibling::*
//*[text()="Material"]/following-sibling::*
It works by finding all elements (labels) with the text you want and then looking to the next sibling in the HTML. Without a specific URL to see I can't help any further.
This is a generalised version you can make more specific versions by replacing the asterisks is tag types, and you can navigate differently by replacing the axis following sibling with something else.
I use xPaths in import.io to make APIs for this kind of thing all the time, It's just a matter of finding a xPath that's generic enough to find the HTML no matter where it is on the page, but being specific enough to get the right data.

Reload the page without submitting it back to the server

the problem I have is that I have two sets of values in a drop down list. If type 'A' is selected I want a text box to be populated with a value from the database and be read only. If Type 'B' is selected the box is to be empty and editable.
My original code is written in jsp/struts and I have sort of achieved this by using
onchange="javascript:submit()" to reload the page, but this has the obvious drawback of saving any changes you have made which means you can't really cancel.
I also have other problems with the serverside validation due to this method.
Is there a way of making a jsp page reload on change, that way I could write javascript to change the way the page looks according to the values held in the session. That way the save/submit function will only be called when the page has properly been filled out and the server side validation will work as designed.
I know that this is something that AJAX is good at doing but I am trying to avoid it if possible.
AJAX is your only other option my friend, unless on the original page load you load all the other possible values of the Text Box so you don't need to go back to the database. Well, you could try putting the text box in an IFRAME, but you will probably run into more problems with that approach than just going with AJAX.
Without AJAX what you are asking is going to be difficult. Another option (which is ugly) is to write out all possible values for the second list box into a data structure like an array or dictionary.
Then write some javascript to get the values from the data structure when the user selects from the first list box. The amount of javascript you will have to write to get this done and to do it correctly in a cross browser way will be much more difficult than simply using AJAX.
Not sure why you'd try to avoid AJAX in today's world, the JS libraries out there today make it so simple it's crazy not to try it out.
I just had to replace a page that was written as Vincent pointed out. I assume at the time it made sense for the app, given the relative size of the data 4 years ago. Now that the app has scaled though, the page was taking upwards of 30 seconds to parse the data structures repeatedly (poorly written JS? maybe).
I replaced all the logic with a very simple AJAX call to a servlet that simply returns a JSON response of values for the 2nd drop down based on what was passed to it and the response is basically instant.
Good luck to ya.
One way is to change the form's action so that you submit the form to a different url than the "save" url. This lets you reload certain aspects of the form and return to the form itself, instead of committing the data.
<script>
function reload() {
document.forms[0].action="reloadFormData.jsp";
document.forms[0].submit();
}
</script>
<form action="saveData.jsp" method="post">
<select id="A" name="B" onchange="reload()"><!-- blah --></select>
<select id="B" name="B"><!-- blah B --></select>
<input type="submit">
</form>
If I understand you correctly, that you want either a dropdown (<select>) or a textfield (<input type="text">) depending on a choice (typically a checkbox or radiobuttons) somewhere above in a form?
I that case you may need to handle the two types of input differently on the server anyway, so why not have both the selectbox and textfield in the area of the form with different names and id and one of them hidden (display = none). Then toggle visibility when the choice changes. On the server you pick eiter the selectbox or textarea input (wich will both be present unless you disable (disabled="disabled") them too, wich I think is uneccesary) depending on the choice input.
Of course if you expect that the user usually just need the text-input, and a few times only, needing a massive list; it would be better to use ajax to retrieve the list. But if it's the other way around (you need the text-field only occationally), as I assumed above, it will be faster to have both present in the initial form.
If the drop down only contain easily generateable data, like years from now to houndreds of years back it could even be much faster (requiring less bandwidth on the server) to generate the data client side using a for loop in Javascript.
I know a taglib that can fit to your problem:
AjaxTags.
I use this taglib in my J2EE projects and it is very simple to integrate it into web applications.
This taglib give you several tags designed to execute AJAX request in your jsp files.
Here is the description of each tags: http://ajaxtags.sourceforge.net/usage.html
The tag which will help you is the ajax:select tag. It allows you to populate a select tag which depends on an other field without reloading the entire jsp page.
If you more informations about it, ask me and i'll try to answer quicky.
Along the lines of what Strindhaug said, but if you need dynamic data:
Could you have the backend write JS into the page, and then the JS would change the form as required? The backend could propagate some variables for descriptions and such, and then the JS could change/update the form accordingly. If you aren't familiar with this, libs like jQuery make things like this easier and more cross-browser than rolling-your-own (at least in my experience).
Aside:
If you're not using AJAX because it was hard to code (as I didn't for a while because my first experience was from scratch and wasn't pretty), as others have said, libs like MooTools and such make it really easy now. Also, there is not shame in using AJAX properly. It has a bad rap because people do stupid things with it, but if you can't simply write premade values into the form or you have to do live look ups, this is one of AJAX's proper uses.

Resources