I would like to create a static (helper) function which will check if a given variable belongs to a set of predefined values. I want to use it as an EL function in order to reference it in a jsff file (via java's EL). The question is: how do I reference the custom function inside the JSFF since it is a page fragment and I cannot access the form templates which the fragment belongs to due to its compilation.
You can have an element from your jsff binded on this function by setting the function's class as the jsff scope in the adfc-config.xml in the "managed-bean" tab and the calling it as follow :
<af:outputText
id="pt1"
viewId="#{YOURSCOPE.YOURBEAN.YOURFUNCTION}"
You'll get a detailled how to in the documentation here : http://docs.oracle.com/cd/E17904_01/web.1111/b31974/web_getstarted.htm#ADFFD1746
Related
I have dynamic view panel and I am using a customizer bean to hide columns based on column names. However, I need to:
Know which view is loaded in the customizer bean
get document handle in the bean
add additional column in the bean
Why I need this: in my application I am dealing with document mappings. I want to create a column for mapped document details. as there can be different document types mapped, there can be multiple columns.
The work of seeing which view you're working with and generating the column defs (normally the same as the ones in the view, but you could add others) is done via the ViewFactory object that is returned by #getViewFactory in the customizer bean. You can see an example of overriding the method and returning a customized factory here. You can also find the source of the default one in the ExtLib here for another example. The job of the ViewFactory is to emit a ViewDef containing a series of ColumnDefs - basically, an abstract representation of the view design. That will cover 1 and 3.
Getting a handle on the document in question for number 2 is a bit more indirect. Since the customizer bean executes only during the initialization of the view, it has no direct hook to the process of rendering each row (which is where you can get the document). You can, however, set properties or content to method/value bindings that, themselves, access the document, so that they're executed per row. I do this in order to get color columns working: I create an SSJS binding for the style property that can then see the viewEntry object. If you modify that code, you could write some SSJS like #{javascript:var doc = viewEntry.getDocument(); ...other stuff here...}. If you do that, you should make sure to either always use "viewEntry" as the var name in the view or use panel.getVar() to find the variable name dynamically.
I have one abstract page, and prototype page that references it using hst:referencecomponent and adds one component to it. Now I want to create one more prototype page, and reference prototype page I created earlier. But when I try to create a new page using this newly created prototype page, I get error "[INFO] [talledLocalContainer] 05.07.2015 16:58:56 WARN http-nio-8080-exec-6 [HstComponentConfigurationService.populateComponentReferences:860] Cannot lookup referenced component 'hst:prototypepages/kkb.prototype.base' for this component ['hst:pages/investor-relations-kkb.prototype.base.plus']. We skip this reference"
So can one prototype page reference another prototype page, or I must create a lot of similar abstract pages, then reference them in prototype pages one by one?
I've give it a try and this is possible to reference a prototype page from another prototype page using the hst:referencecomponent attribute. Also looking at the CND this is coherent.
It seems looking at the stacktrace that you have created the second page that reference the first one in hst:pages but prototypes pages must be declared in hst:prototypepages
Can you try again to declare kkb.prototype.base.plus in the hst:prototypepages folder of the configuration?
I am using JDeveloper 11.1.2.3.0
I have to show a popup by clicking a link that is located in the page template. For this I created a popup within the pageTemplate then inserted a dialogBox and within the dialog box I dragged and dropped my VO from the DataControl panel and inserted it as an ADF form. The problem is that when I run and click the link (that contains the "ShowPopupBehavior") I am getting this error:
//C:/Oracle/Middleware/jdeveloper/jdev/system11.1.2.3.39.62.76.1/MyNew/ViewControllerWebApp.war/WEB-INF/templates/myTemplates.jsf #58,118 value="#{bindings.TypeName.inputValue}": Target Unreachable, 'TypeName' returned null
ADF_FACES-60097:For more information, please see the server's error log for an entry beginning with: ADF_FACES-60096:Server Exception during PPR, #2
This happens for every View that I can insert here. Is this comming because I am not allowed to insert ADF forms within the page template?
If so please give me a hint to achieve what I explained in the first sentence.
I just figured out the solution to this problem. Each page has its own bindings, so a page that uses the templates (or if want to use bindings from other pages) has to declare that page in the Executables section of the page Bindings. The new executable should have the ID of the page (of the template in this case) and the path of the page. Then the bindings of the template can be accessed as explained here:
public String cb1_action() {
BindingContext bctx = BindingContext.getCurrent();
DCBindingContainer bindings =
(DCBindingContainer)bctx.getCurrentBindingsEntry();
//access the page template Pagedef file reference in the
//Executable section of the consumer page's Pagedef file
DCBindingContainer templateBinding =
(DCBindingContainer)bindings.get("ptb1");
//get the MethodBinding
OperationBinding printMethod =
(OperationBinding)templateBinding .get("printThis");
//invoke the print method exposed on the template's PageDef file
printMethod.getParamsMap().put("message","Hello World");
printMethod.execute();
return null;
}
https://blogs.oracle.com/jdevotnharvest/entry/how_to_invoke_adf_bindings
ps: Pay attention not to bind the value of the template in your page ex: value="#{bindings.ptb1}" - it is a bit strange but in this case you will not get the page bindings and will get only the template ones.
The value property containing #{bindings.ptb1} should be removed from the pageTemplate tag but the ptb1 reference has to be in the pages PageDef file.
I have a template in JSF, this template have a button whose action must be different for each page that will use this template.
I wonder if there is any way to set only a part of that action.
Eg
In the template, I have the following attribute on the button:
disabled = "#{managedBeanTemplate.EditMode}"
However, for each page that will use this template, it should replace ONLY the part where it says managedBeanTemplate, thus:
disabled = "#{managedBeanProduct.EditMode}"
disabled = "#{managedBeanSales.EditMode}"
Is there any way to do this?
I know there is the ui:param to replace parts of the xhtml, but i can't nest in the template using something like this:
disabled = "#{#{managedBeanName}.EditMode}"
in the template, and then
<ui:param name="managedBeanName" value="managedBeanProduct"/>
in the page that uses the template.
I found the answer here:
facelets: passing bean name with ui:param to action attribute
i can just do something like this in the template:
disabled = "#{managedBeanName['EditMode']}"
then, i can simply set the "managedBeanName" through the ui:param
you would be better served having method that takes a parameter. by having the template construct the back references to the server side you are creating a maintainance footprint where it should not be. replace the references with a method that abstracts away the logic of whether the component is disabled/rendered/etc.
ultimately the UX should not care "why", just whether it has to render a compoenent a certain way.
I have a composite component that bundles some input fields. The component will be used multiple times on a page and contains a button to copy the values of another of these components. For this I would need to access one of those siblings via its clientId as a target for an
<f:ajax execute=":XXX:siblingId" render="...">
My problem lies in constructing this ID. I have the name of the sibling and I can make sure that it is located in the same naming container as the component that contains the copy button, but I can't control the complete nesting hierarchy, so it might be :form:foo:bar:parent:child or just form:parent:child. So essentially I would want to get the prefix of the current composite component, but without the component's own ID and then attach the ID of the component from which to copy.
This is similar to these questions:
How to address the surrounding naming container in jsf
How to access the parent naming container of composite
However, both answers make use of PrimeFaces-sepcific features like #parent and widgetVar, which does not apply to my project.
When experimenting with EL's implicit objects I basically tried the same things as the poster of the second question - with the same results: cc.parent.clientId is always empty. I also tried cc.namingContainer.clientId and some combinations of the two, alas - no success. Especially the fact that parent does not work as expected confuses me...
So: Is there a component-library-agnostic way to access the "path" of containing naming containers for a composite component? How is the parent object supposed to work, especially: when can we use it and when not?
PS: I was thinking about using the composite's full clientId and then trimming its actual ID with fn:split, however, if there was a more direct way I'd be happy to use it.
The #{cc.parent} resolves to UIComponent#getCompositeComponentParent() which returns the closest parent composite component. In other words, it returns only non-null when the composite component is by itself nested in another composite component.
The #{cc.namingContainer} simply refers to #{cc} itself, fully conform as specified in UIComponent#getNamingContainer():
Starting with "this", return the closest component in the ancestry that is a NamingContainer or null if none can be found.
Composite components namely implicitly implement NamingContainer themselves.
So your attempts unfortunately won't work. I also do not see any "standard API" ways to achieve the concrete functional requirement. The CompositeComponentAttributesELResolver causes that the #{cc.parent} doesn't resolve to UIComponent#getParent() which is what you ultimately want.
You can however provide a custom UIComponent implementation for the composite which adds an extra getter with an unique name which in turn properly delegates to UIComponent#getParent().
Here's a kickoff example:
#FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {
public UIComponent getParentComponent() {
return super.getParent();
}
}
If you register it as follows in the composite interface:
<cc:interface componentType="myComposite">
then you'll be able to use
#{cc.parentComponent.clientId}
to get the client ID of the real parent UIComponent.
Ultimately you should be able to use the following construct to refer the sibling:
process=":#{cc.parentComponent.clientId}:siblingId"