how to hide <f:param> parameter value on page view source - html

1. this is .xhtml file
there is a ...xhtml page and in that page's p:dataTable included another page i.e plandata.xhtml and in plandata.xhtml we have written:
< h:commandLink value="#{plan.rmsId}"
action="#{planBean.viewPlanAction}" ajax="false">
< f:param name="rmsPlanId" value="#{plan.rmsId}" />
< f:param name="planStatus" value="#{plan.planStatus}" />
< f:param name="pendingWith" value="#{plan.pendingWith}" />
< f:param name="pendingWithRole" value="#{plan.pendingWithRole}"/>
and this is bean code:
pendingWithVar = myRequest.getParameter("pendingWith");
if(null == pendingWithVar){
pendingWithVar = planMapping.getPendingWith();
}
plan.setPendingWith(pendingWithVar);
String pendingWithRole = myRequest.getParameter("pendingWithRole");
if(null == pendingWithRole){
pendingWithRole = ""+planMapping.getPendingWithUserRole();
}
I have used f:param tag with commandLink. But when right click and select view source option it shows that parameter value and i want to hide that values.Is there any solution on this?

What you can do is use <f:attribute .../> (it's not shown in the source).
<h:commandLink ...>
<f:attribute name="pendingWith" value="#{plan.pendingWith}"/>
<f:attribute .../>
</h:commandLink>
To obtain the value your backing bean, you need to obtain your UIComponent instance (you can use the binding attribute of h:commandLink and do:
myUiComponent.getAttributes().get("format")

Related

Primefaces steps skip validation on primefaces file uploader [duplicate]

since fileLimit doesn't exist in primefaces 3.4 anymore I'm trying a work around implementing a validator, the problem is that the method validate is never invoked. That's my Validator:
#FacesValidator(value ="fileLimitValidator")
public class FileLimitValidator implements Validator {
#Override
public void validate(final FacesContext context, final UIComponent component,
final Object value) throws ValidatorException {
final String fileLimit = (String)component.getAttributes().get("fileLimit");
final String size = (String)component.getAttributes().get("size");
if (fileLimit!=null && size!=null) {
if (Integer.valueOf(size) >= Integer.valueOf(fileLimit)) {
FacesUtils.throwErrorExceptionFromComponent(component,"fichero_confidencialidad_error");
}
}
}
}
and in my facelet I've tried:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" >
<f:validator validatorId="fileLimitValidator"/>
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
and:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="fileLimitValidator">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
and:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
and:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator.validate}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
but the validate method is never called. What is the correct way to do it?
According to the FileUpload and FileUploadRenderer source code, the validator is only invoked when mode="simple" is been used (note: this in turn requires ajax="false" on command). The advanced mode will namely not set the uploaded file as component's submitted value, causing it to remain null until the listener method is invoked. As long as the submitted value is null, the validators are not invoked.
I'm not sure if this is intentional. Theoretically, it should be possible to set UploadedFile as submitted value and have the validator to rely on it. You might want to create an enhancement report at PrimeFaces issue tracker.
In the meanwhile, in spite of it being a poor practice, your best bet is really performing the validation in fileUploadListener method. You can just trigger validation failure add faces messages through the FacesContext like follows:
if (fail) {
context.validationFailed();
context.addMessage(event.getComponent().getClientId(context), new FacesMessage(
FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
}
Otherwise, you'd need to create a custom renderer for the <p:fileUpload> which sets the submitted value during the decode() (I however don't guarantee that it would work in practice, you'll maybe stumble upon a peculiar problem which may turn out to be the reason why PrimeFaces didn't initially implement it like that).
By the way, your first and second validator attempt are correct. The third attempt works only if you used #ManagedBean instead of #FacesValidator (which is often done when injection of an #EJB is mandatory — which isn't possible in a #FacesValidator). The fourth attempt is invalid.
For validating a required primefaces file upload in mode advanced (ajax) it is possible to use this:
<f:metadata>
<f:event listener="#{bean.processValidations()}" type="postValidate" />
</f:metadata>
Where the implementation of the bean.processValidations() method would be something along the lines of:
public void processValidations() {
FacesContext context = FacesContext.getCurrentInstance();
UIInput fileUploadComponent = fileUploadsBean.getFileUploadComponent();
if (fileUploadComponent!=null && !isFileUploaded()) {
fileUploadComponent.setValid(false);
context.addMessage(fileUploadComponent.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
context.validationFailed();
}
}
Where fileUploadsBean would be a REQUEST scoped CDI bean (won't work with standard JSF ManagedBeans) which you inject to your bean which has the processValidations() method defined, the method fileUploadsBean.getFileUploadComponent() returns the primefaces file upload component (you will use <p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...> for that). The method isFileUploaded() will determine if the file has been uploaded or not (probably just a null check on a member variable which you fill from fileUploadListener).
If you want to highlight the file upload button you can of course conditionally add a styleClass which you can then use for adding a red border for example.
styleClass="#{fileUploadsBean.fileUploadComponent.valid ? '' : 'validationFailed'}"
As a result the validation failed message for the primefaces file upload will be displayed along with all other jsf validation messages. You might have problem with maintaining order of the validation messages (will be always at the end), but it still beats displaying the failed upload file validation after user dealt with all the standard jsf validation messages from different fields and your action in a backing bean has been finally reached.

Render component in primefaces by value [duplicate]

How can I show/hide component with JSF?
I am currently trying so do the same with the help of javascript but not successfull.
I cannot use any third party libraries.
Thanks| Abhi
You can actually accomplish this without JavaScript, using only JSF's rendered attribute, by enclosing the elements to be shown/hidden in a component that can itself be re-rendered, such as a panelGroup, at least in JSF2. For example, the following JSF code shows or hides one or both of two dropdown lists depending on the value of a third. An AJAX event is used to update the display:
<h:selectOneMenu value="#{workflowProcEditBean.performedBy}">
<f:selectItem itemValue="O" itemLabel="Originator" />
<f:selectItem itemValue="R" itemLabel="Role" />
<f:selectItem itemValue="E" itemLabel="Employee" />
<f:ajax event="change" execute="#this" render="perfbyselection" />
</h:selectOneMenu>
<h:panelGroup id="perfbyselection">
<h:selectOneMenu id="performedbyroleid" value="#{workflowProcEditBean.performedByRoleID}"
rendered="#{workflowProcEditBean.performedBy eq 'R'}">
<f:selectItem itemLabel="- Choose One -" itemValue="" />
<f:selectItems value="#{workflowProcEditBean.roles}" />
</h:selectOneMenu>
<h:selectOneMenu id="performedbyempid" value="#{workflowProcEditBean.performedByEmpID}"
rendered="#{workflowProcEditBean.performedBy eq 'E'}">
<f:selectItem itemLabel="- Choose One -" itemValue="" />
<f:selectItems value="#{workflowProcEditBean.employees}" />
</h:selectOneMenu>
</h:panelGroup>
Generally, you need to get a handle to the control via its clientId. This example uses a JSF2 Facelets view with a request-scope binding to get a handle to the other control:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head><title>Show/Hide</title></h:head>
<h:body>
<h:form>
<h:button value="toggle"
onclick="toggle('#{requestScope.foo.clientId}'); return false;" />
<h:inputText binding="#{requestScope.foo}" id="x" style="display: block" />
</h:form>
<script type="text/javascript">
function toggle(id) {
var element = document.getElementById(id);
if(element.style.display == 'block') {
element.style.display = 'none';
} else {
element.style.display = 'block'
}
}
</script>
</h:body>
</html>
Exactly how you do this will depend on the version of JSF you're working on. See this blog post for older JSF versions: JSF: working with component identifiers.
Use the "rendered" attribute available on most if not all tags in the h-namespace.
<h:outputText value="Hi George" rendered="#{Person.name == 'George'}" />
You should use <h:panelGroup ...> tag with attribute rendered. If you set true to rendered, the content of <h:panelGroup ...> won't be shown. Your XHTML file should have something like this:
<h:panelGroup rendered="#{userBean.showPassword}">
<h:outputText id="password" value="#{userBean.password}"/>
</h:panelGroup>
UserBean.java:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class UserBean implements Serializable{
private boolean showPassword = false;
private String password = "";
public boolean isShowPassword(){
return showPassword;
}
public void setPassword(password){
this.password = password;
}
public String getPassword(){
return this.password;
}
}
One obvious solution would be to use javascript (which is not JSF). To implement this by JSF you should use AJAX. In this example, I use a radio button group to show and hide two set of components. In the back bean, I define a boolean switch.
private boolean switchComponents;
public boolean isSwitchComponents() {
return switchComponents;
}
public void setSwitchComponents(boolean switchComponents) {
this.switchComponents = switchComponents;
}
When the switch is true, one set of components will be shown and when it is false the other set will be shown.
<h:selectOneRadio value="#{backbean.switchValue}">
<f:selectItem itemLabel="showComponentSetOne" itemValue='true'/>
<f:selectItem itemLabel="showComponentSetTwo" itemValue='false'/>
<f:ajax event="change" execute="#this" render="componentsRoot"/>
</h:selectOneRadio>
<H:panelGroup id="componentsRoot">
<h:panelGroup rendered="#{backbean.switchValue}">
<!--switchValue to be shown on switch value == true-->
</h:panelGroup>
<h:panelGroup rendered="#{!backbean.switchValue}">
<!--switchValue to be shown on switch value == false-->
</h:panelGroup>
</H:panelGroup>
Note: on the ajax event we render components root. because components which are not rendered in the first place can't be re-rendered on the ajax event.
Also, note that if the "componentsRoot" and radio buttons are under different component hierarchy. you should reference it from the root (form root).
check this below code.
this is for dropdown menu. In this if we select others then the text box will show otherwise text box will hide.
function show_txt(arg,arg1)
{
if(document.getElementById(arg).value=='other')
{
document.getElementById(arg1).style.display="block";
document.getElementById(arg).style.display="none";
}
else
{
document.getElementById(arg).style.display="block";
document.getElementById(arg1).style.display="none";
}
}
The HTML code here :
<select id="arg" onChange="show_txt('arg','arg1');">
<option>yes</option>
<option>No</option>
<option>Other</option>
</select>
<input type="text" id="arg1" style="display:none;">
or you can check this link
click here

Validation length component depending on chosen h1/h2

Where is a correct place in code to write validation(adding maximum lenght on text field) depending on two diference input's. User can chose an textfield size between h1 or h2. When user chose h1 I want to limit text to 10 elements, when chose h2 limit will be 7 elements. I use AEM 6.2.
I try to Validate an htl file, validate an cq_dialog.When I try to validate an htl file I have an problem with implementation ( it doesn't work), but in cq_dialog.xml file I can only validate an text label once, and I can't change a logic that my validation was change depending which size of text user chose.
This is My cq_dialog code and the most comfortable for me will be adding all logic here but I don't know this is posible?
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Text"
sling:resourceType="cq/gui/components/authoring/dialog">
<content jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<title
jcr:primaryType="nt:unstructured"
name="./title"
fieldLabel="Text"
sling:resourceType="granite/ui/components/foundation/form/textfield"
fieldDescription="Max 10 elements"
/>
<type
sling:resourceType="granite/ui/components/foundation/form/select"
fieldLabel="Type"
name="./type"
jcr:primaryType="nt:unstructured"
>
<items jcr:primaryType="nt:unstructured">
<h1 jcr:primaryType="nt:unstructured" text="H1" value="h1"/>
<h2 jcr:primaryType="nt:unstructured" text="H2" value="h2"/>
</items>
</type>
</items>
</column>
</items>
</content>
You have to create a clientlib and add JS to register a validator for this use case. The clientlib's category must be referenced by the dialog. Using some OOTB category used by the dialog like 'cq.authoring.editor' will make your clientlib work for dialog validation.
Once you have the clientlib set up, register the validator with the granite framework. Refer https://helpx.adobe.com/experience-manager/6-4/sites/developing/using/reference-materials/granite-ui/api/jcr_root/libs/granite/ui/components/coral/foundation/clientlibs/foundation/js/validation/index.html#validator on how to register the validator.
Here's a sample of how you can do this for your usecase.
var foundationRegistry = $(window).adaptTo("foundation-registry");
foundationRegistry.register("foundation.validation.validator",{
selector: "[name='./title']",
validate: function(el){
var text = el.value;
var type = $("[name='./type']").val();
var limit = type === 'h1' ? 10 : 7;
var numberOfElements = getNumberOfElements(text); //not sure what number of elements means in your context
if(numberOfElements > limit){
return "The input cannot exceed "+limit+ " elements for type "+type;
}
//the field is considered invalid if this method returns a string,
// the string returned is also used as the error message.
}
});
* the code has not been tested
Since the category of the clientlib is generic, this validator will be bound for all dialogs. You can either make the selector of the field more specific or change the clientlib category and explicitly reference it only on this dialog.

CommandLink within PrimeFaces Mobile DataList is not referencing the correct element after being filtered

I'm working on a PrimFaces mobile employee directory app and have hit a road block. Its a simple app which consists of two screens (employee filter/list + employee detail).
I was able to load a datalist without issues. Clicking on the commandlink properly loads the employee detail. I then was able to implement a custom employee filter which was somewhat painful, but I got that working. The filter works by repopulating the employee datalist's model with the filtered results.
The issue is, after I use the filter to repopulate/filter the datalist, clicking on an employee (commandlink) does not pass the correct employee ID back to the model. Instead, the employee ID that was there before the filter was performed is passed. It's like the JSF model is not matching the DOM.
I'm using:
TomEE (MyFaces 2.1.7)
PrimeFaces Mobile 0.9.3
PrimeFaces 3.3
Both of my backing models are #ViewScoped
<pm:view id="peopleDirView" onload="">
<pm:header title="People Directory" fixed="true">
</pm:header>
<pm:content>
<h:form id="form">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<p:inputText id="searchCriteria" value="#{peopleDirectoryBean.criteria}" type="search"
onkeyup="delay(function() {filterResults();}, 500);" />
</fieldset>
</div>
<p:dataList id="peopleDataList" value="#{peopleDirectoryBean.people}" var="person" rowIndexVar="rowIndex">
<p:column>
<p:commandLink action="#{peopleDirectoryDetailBean.loadPersonDetail(person.employeeId)}" update=":personDetailView">
<img src="/phonedir/people/image/#{person.employeeId}?width=75&height=100" width="90" height="100"
onerror="missingImage(this);" id="per-search-picture" />
<h1>#{person.nameLast}, #{person.nameFirst}</h1>
<p>#{person.deptName}</p>
<p>#{person.jobTitle}</p>
</p:commandLink>
</p:column>
</p:dataList>
<p:remoteCommand name="filterResults" update="peopleDataList" action="#{peopleDirectoryBean.peopleSearch}" />
</h:form>
</pm:content>
<pm:footer fixed="true">
<pm:navBar>
<p:button value="People" icon="home" href="#peopleDirView?reverse=true" styleClass="ui-btn-active" />
<p:button value="Locations" icon="info" href="#locationsView?reverse=true" />
<p:button value="Conference" icon="search" href="#conferenceRoomsView?reverse=true" />
</pm:navBar>
</pm:footer>
<script>
var delay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
function missingImage(image) {
image.onerror = "";
image.src = "missing-person.jpg";
return true;
}
</script>
</pm:view>
Okay, looks like the mistake was on my part.
In my backing bean, I was using javax.inject.Named (#Named) because I was trying to make use of my container's ability to do CDI. Once I changed it to javax.faces.bean.ManagedBean (#ManagedBean ) the problem went away. The TomEE docs state that it supports #Named so I'm not sure what the deal is.

How to use p:ajax oncomplete event on p:fileUpload. Getting error when using

I am using PrimeFaces 2.2. I am using p:fileuplaod, when fileUploads then using update i change the image on my page. Here it is.
<p:fileUpload id="countryFlag" widgetVar="uploader" description="Image"
update="Flag" allowTypes="*.jpg;*.png;*.gif;*.jpeg;" auto="true"
fileUploadListener="#{countryPages_Detail.imageUpload}">
<p:ajax oncomplete="test('Flag')" />
</p:fileUpload>
<p:graphicImage id="Flag" value="#{countryPages_Detail.imagePath}"
width="80" height="50" cache="false">
<f:event type="preRenderComponent" listener="#{countryPages_Detail.putImage}" />
</p:graphicImage>
What i want to do using script is that when upload completes, and using ajax when the image has been changed, then i want to check the image src attribute. Here is my test() function, it is not complete, but here it is
function test(imageId) {
var imgId = imageId;
var image = $("#saarcImagesTable tr").find("img[id='imageId']")
alert("Image change");
}
But I am getting error that
Parent not an instance of ClientBehaviorHolder: org.primefaces.component.fileupload.FileUpload#e39f71
Why am I am getting this error? What am I doing wrong?
Thanks
The p:fileUpload component does not implement the ClientBehaviorHolder interface as the message states and therefore is no component that can contain the ajax tag (see this post).
I am not familiar with the fileUpload component, but I've seen in the documentation of PF 3.2 that the p:fileUpload has an oncomplete attribute.