Can Not Read id on JSF Components - java

I have a little problem
I am trying to use MartkItUp JQuery rich text editor on JSF textarea component.
My form looks like this:
<h:form id="comment">
<h:inputTextarea id="commentBody" cols="10" rows="10" value="#{postComment.commentBody}" required="true" requiredMessage="Comment Body is reqguired" >
<f:validateLength maximum="500" minimum="2" />
</h:inputTextarea>
<%-- more of the form... %-->
The problem is that on output it gives me the id for textarea like that
id="comment:commentBody"
When I try in JQuery to point to it nothing happens.
$('#comment:commentBody').markItUp(mySettings);
I had a plain textarea before, and there was no problem. Now, I have a lot of them.
How do I point to id in JQuery, thats looks like comment:commentBody
P.S: I know i can point to this text area by $('textarea').markItUp(mySettings); however i am looking for solution to point to specific text area by it's ID.

Try this, $('#comment\\:commentBody'), for JQuery version 1.1.3 or greater.

try this:
$("textarea[id$='commentBody']").markItUp(mySettings);
this will select text area having ID ending with commentBody.
to select control with ID starting with particular string replace $ with ^

You can read about JSF IDs here, but in this case you may also find the h:form prependId attribute useful.

Related

In Primefaces inputText required=true, how can I remove ui-state-error as soon as something is entered?

When submitting a form that includes a required inputText, the styles that indicate not validated fields remain in place until submitting again. I want the styles to disappear as soon as the field is edited.
<p:inputText value="#{data.bezeichnung}"
id="bezeichnung"
styleClass="panelInputField input_mandatory"
required="true"
title="Bezeichnung"/>
After a lot of trying around, I found the easiest answer to add a "onkeyup" as follows:
<p:inputText value="#{data.bezeichnung}" id="bezeichnung"
styleClass="panelInputField input_mandatory"
required="true"
onkeyup="$(this).removeClass('ui-state-error');"
title="Bezeichnung"/>
If the jquery code needs to be in a more general place, the following might work as well: (it may be helpful to know the escaping codes used here)
onfocus="$('.ui-state-error').removeClass('ui-state-error');"
onkeyup="$('input[name="form:bezeichnung"]').removeClass('ui-state-error');"
onkeyup="$('input[name$=bezeichnung]').removeClass('ui-state-error');"

importing content into jsf h:inputTextarea

We are currently converting a Spring mvc/jsp app into a jsf app.
Previously we could import the content of a JSP segment file into a text area like this
<textarea id="sectionSixPointOne" name="sectionSixPointOne">
<jsp:include page="sect_six_point_one.jspf"/>
</textarea>
Magically the content of the jsp appeared into the content of the text area.
We are trying to do the same with JSF, but I am about ready to shoot myself in the face.
We've tried
<h:inputTextarea id="sectionSixPointOne">
<ui:include src="section_six_sect_one.xhtml"/>
</h:inputTextarea>
But it includes the content after the textarea not inside it.
I have tried to include the content of as the value parameter of h:inputTextarea but the compiler gets it's knickers in a knot about the syntax/quotes/anglebrackets etc.
<h:inputTextarea id="sectionSixPointOne" value=<ui:include src="section_six_sect_one.xhtml"/>
</h:inputTextarea>
I would much rather include the content directly in the jsf pages rather than mucking about loading it into a backing bean.
Anyone got any ideas can what I want to do be done with jsf (apologies for any idiocy I am a total JSF newb?
Just put the <h:inputTextarea id="sectionSixPointOne"> with it's value to include in the file you want to include.
That way you don't need to insert it in some component, you just extracted the whole thing into its own file.
So you code looks like:
<ui:include src="section_six_sect_one.xhtml"/>
and in section_six_sect_one.xhtml":
<ui:composition xmlns=... >
<h:inputTextarea id="sectionSixPointOne" value="yourIncludedText"/>
...

how to make \n work in <h:inputTextarea>

I am using \n in my java bean and output of the variable in console is displayed correctly. Whereas while fetching this value from bean to JSF \n seems not working.......
can any one suggest me how can i make \n work in of JSF.
The simplest way would be to apply CSS white-space: pre on the parent element containing the text of which you would like to preserve newline \n characters. Given this CSS style class:
.preformatted {
white-space: pre;
}
You could apply this as follows:
<div class="preformatted">#{bean.text}</div>
or
<h:panelGroup layout="block" styleClass="preformatted">#{bean.text}</h:panelGroup>
or
<h:outputText value="#{bean.text}" styleClass="preformatted" />
etc.
This style property is by the way also exactly what the <textarea> element is by default using. You could also make use of it and make it uneditable by setting disabled="true" or readonly="true".
<h:inputTextarea value="#{bean.text}" disabled="true" />
You can of course also replace all occurrences of \n by the HTML <br/> element. This way you can display it in an element which does not use white-space: pre and/or is not a <textarea> element. One of the ways is using fn:replace().
<h:outputText value="#{fn:replace(bean.text,'\\n','<br/>')}" escape="false" />
This is IMO only uglier than white-space: pre.
You should replace all \n with <br/> before you send the value to your <h:inputTextarea>.
Html uses <br/> for line break and not the \n like java.
Also, you should add escape="false" to your <h:outputText (almost sure...).
Replace all occurrences of \n with </br> before displaying it.
When looking into text recorded in my database via a <h:inputTextarea> I found that special characters were being persisted.
Thus, after investigating what I thought was some dark art of persistence, I appreciated that the default display of the JSF component was in fact what was letting me down.
I shortly found that adding white-space: pre-wrap; to <p> on my stylesheet fixed this problem for my <h:outputText> tags which were being supplied with text from a JPA pojo.
In my case, I needed pre-wrap rather than pre because pre was wrapping by character, rather than by word.
Hope this helps someone!
I have solved it using the following method
Declare an inputtextarea where a user can provide multi-line description. Before saving it to database, I have replaced new line to branch
String fpDescriptionCombined = fpDescription.replaceAll("(\r\n|\n)", "<br />");
During showing in screen, i again replaced branch to new line
String finalStr = splitStr.replaceAll("<br />", "\n");
In screen, I used above-mentioned CSS
.showLineBreak {
white-space: pre;
}
<h:outputText value="${templateListController.getFlowPointDescriptionForTab(eachFPType)}" style="display:block;width:860px;" styleClass="showLineBreak" />
I had to do this because my description can be exported/imported via csv. So adding multi-line description will be treated as a new record if not handled properly

Reducing the JSF component tree/state by an alternate approach. Is it Okay?

Unfortunately, I made a mistake of choosing JSF for an internet facing, high traffic application, now I am wondering as to how to improve the scalability of this JSF webapp.
I have a JSF page that displays a large no of items each of which may be commented upon.
Inorder to reduce the state & improve performance I am trying to reduce the no of forms /commandButtons on the page.
1. Through what ways can I reduce the component tree/ statefulness of JSF ? Do the plain html elements(that are mixed in between the jsf tags) also form part of component tree ? I dont know how component state saving has been helpful to my app since I have been following plain request/response model while designing my app, (may be it is helpful for just JSF's internal requirements)!?
2. I was thinking of an approach where instead of creating a separate <h:form> (each with a separate commandButton) for every item like below,
(Usual Approach)
<h:form> <!-- for each item a separately -->
<h:outputText value="Add comment"/>
<h:inputTextarea value="#{itemController.comment}" required="true"/>
<p:commandButton actionListener="#{itemController.addUserComment(123)}" value="Add" />
</h:form>
(Alternate Approach)
I am trying to make the above better by just putting a single remoteCommand for all the items & pass the required parameters to this remoteCommand.
<form>
<input id="item1_comment"/>
<button onclick="addComment(123, 'item1_comment');"/>
</form>
<script type="text/javascript">
function addComment(itemId, id) {
$('#comment_in').attr('value', $('#'+id).attr('value'));
$('#forItem_in').attr('value', itemId);
addComment_RC(); // call remoteCommand to show the content in dialog
}
</script>
<h:form prependId="false" > <!-- for all items, just single remoteCOmmand -->
<h:inputHidden id="comment_in" value="#{itemController.comment}"/>
<h:inputHidden id="forItem_in" value="#{itemController.forItem}"/>
<p:remoteCommand name="addComment_RC" process="#form" actionListener="#{itemController.addComment()}" />
</h:form>
Is it better to do it this way (or are there any issues with this approach)?
Performance issues in the situation you describe are often caused by the large number of EL expressions, That burdens the server.
One approach to tackle this issue is to compute the comments on the client side, and pass them all at once to the server. Thus reducing the number of comment EL expression to one or none, and use only one button.
Place all the elements in one form. The comments fields are not binded.
<h:form>
// first element
<h:outputText value=#{first element}
// first comment
<h:inputTextarea id="comment1"/> <-- notice there is no EL expression
But we use a unique id for each comment
// second element
<h:outputText value=#{second element}
// second comment
<h:inputTextarea id="comment2"/>
.
.
.
</h:form>
From here you could either
1. after each blur event in any of the comment fields, ajax the server and pass as parameters the comment and the id of the comment from which the ajax call was made. on the server update your model accordingly
Or You can also gather all the comments on the client side and send them to the server at one time.
2. When the user press the submit button call a js function to aggregate all the comments in a structure that you will be able to parse easily on the server side
(ie. "{c1,comment a};{c2,comment b};{c5=,comment e}...").
pass that string to the server, parse it and update your model accordingly.
3. after each blur event in any of the comment fields, call a js function that updates an hidden field.
<h:inputHidden value="{myClass.allComments}" />
when the user submits the form parse allComments and update your model accordingly.
EDIT:
To address the general performance issue I've added recommendations from an article that I found helpful speed up part 1 Speed up part 2.
Hope this helps
btw, I would recommend the first approach rather than the last two.

Spring is eating </textarea> tags

In my web application (my first with Java, Spring, OR Roo), I'm building a form that has nothing to do with any JPA objects, it's just a form. I really don't want to use JSTL to build my forms here, because there's no data backing for them at this point. I'm using tiles to assemble the pages, so the guts of this form comes from a view, but apart from that there's nothing JSPish about it; it's just a form.
Inside that form, I have a text area that I've written:
<textarea id="whatever" name="whatever"></textarea>
When that comes to the screen, the </textarea> tag is gone. Different browsers deal with that differently, up to and including swallowing up the whole rest of the body HTML inside the text area field.
So I tried putting some content inside that textarea. Spaces and line breaks don't change its behavior, but it appears that any non-space character does. If I go
<textarea>.</textarea>
... it respects my close textarea tag. But then of course my text area renders on the screen with a dot in it, which isn't what I want.
Is this a known issue? Am I doing something wrong?
EDIT:
#bozho: Here's a pertinent chunk of my jsp:
<div id="notes" class="detailPanel">
<div class="panelLabel">Notes</div>
<table >
<thead><tr><th>Date</th><th>By</th><th>Note</th></tr></thead>
<tbody id="notesBody"></tbody>
</table>
<textarea id="newNote" rows="5" cols="80" >.</textarea>
<button id="addNewNote" onClick="saveNote();">Add New Note</button>
</div>
Absolutely nothing fancy going on here (I populate the tbody with rows on the client, is why that's empty). Without the dot in the third-to-last line, the closing textarea tag does not come out in the resulting HTML.
EDIT2 (Solution):
This URL became googlable after hearing some key words from people responding here:
http://www.jroller.com/komu/entry/textareas_with_jspx
Turns out that when jspx pages are parsed, empty tags are collapsed into a single self-closing tag, which breaks text areas. The solution is to put an empty jsp:text in the middle:
<textarea><jsp:text /></textarea>
(Which is STAGGERINGLY stupid, but there it is.)
You are using jspx files right?
In general jspx remove something (or in your case it shorten it: check this: I expect that it addes a slash to the former opening tag, so it becomes: <textarea id="whatever" name="whatever"/> ) where it belives that is not needed. What exactly depends ona bit on the implementation.
So put a <jsp:text> tag in the text area tag to prevent it from "closing"
<jsp:text>
<textarea id="whatever" name="whatever"></textarea>
</jsp:text>
<textarea id="whatever" name="whatever"><jsp:text /></textarea>
for an more complex example have a look at this answer: websphere 7 (and Spring Roo) incompatible with javax.el.ELException

Categories