Hello All,
I want to extend the Dialog component, so that it has some other components already set and also to have some properties set with default values, to not repeat every time.
First, I tried to extend as a JSF Composite Component, but I don't know if it's possible to set default properties in CC, I tried using JSTL <c:set> but it did not work.
So I think that the best is to create a class extending org.primefaces.component.dialog. { Dialog or DialogRenderer }, but I don't know what method I have to override to do it.
All that I want is to do something like:
<my:customDialog name="aName" title="A Title For The Dialog" controller="#{aController}">
<variable custom content>
</my:customDialog>
Then, in CustomDialog (class or CC) I set id and widgetVar to be "aName", header to be title, set other properties to some default, and create some other components, like buttons, that uses the controller property.
Code for Composite Component I tried (DON'T WORK):
...
<body>
<cc:interface componentType="org.primefaces.component.Dialog" >
<cc:attribute name="name" required="true" />
<cc:attribute name="controller" required="true" />
<cc:attribute name="title" required="true" />
</cc:interface>
<cc:implementation>
<c:set property="id" value="#{cc.attrs.nome}" />
<c:set property="widgetVar" value="#{cc.attrs.nome}" />
<c:set property="modal" value="true" />
<c:set property="resizable" value="false" />
<c:set property="appendTo" value="@(body)" />
<c:set property="header" value="#{cc.attrs.title}" />
<h:form id="form">
<h:panelGroup id="display">
<p:panelGrid columns="1">
<cc:insertChildren />
</p:panelGrid>
<p:commandButton actionListener="#{cc.attrs.controller.save}"
value="Save" update="display,@(body)"
onclick="#{cc.attrs.name}.hide()" immediate="true" ajax="true"
resetValues="true">
</p:commandButton>
<p:commandButton ajax="true" global="false"
actionListener="#{cc.attrs.controller.cancel}" value="Cancel"
onclick="#{cc.attrs.name}.hide()" immediate="true" resetValues="true">
</p:commandButton>
</h:panelGroup>
</h:form>
</cc:implementation>
</body>
...
What I want to know is, if it's possible to set properties in CC, how to do it, or, if not possible, what method I have to override from dialog class, and what class (Dialog or DialogRenderer).
God bless you,
Leandro.
How to extend a Primefaces component (as Composite Component or Java class) to add or modify properties
-
- Posts: 84
- Joined: 11 Sep 2014, 10:13
- Location: Brussels, Belgium
Hi Leandro,
your question touches some quite advanced topic/problems of custom component development, which is why I want to ask you to be more specific about your question because your text is a little contradictory:
On one hand you ask how to modify an existing component (here: org.primefaces.component.Dialog) to have some pre-set attributes. On the other side you offer a composite component implementation that uses a lot of different components assembled together which hints at completely different needs.
So what exactly do you want to do? i mean in terms of a use case (eg "I want to use a Dialog with two input fields and a caption that always reads 'LeandroDialog'"!)
The reason for this question is to determine whether you need to go for a composite component (which is what you tried, you are bundling UIComponents together via XHTML), a custom component (no XHTML, a component class and renderer class registered in a taglib instead) or a mix of the two, each requiring quite a longish answer.
Even not knowing your exact needs, there are various issues with the code you provided and it won't work indeed, but pointing those out might be a waste of time if a composite turns out not to be the right path of solution.
@kukeltje's: Usually you'd be right about your comment with the form within a dialog but in this specific case the dialog seems to be going to be hardcoded to appendToBody which is save regarding nested forms.
your question touches some quite advanced topic/problems of custom component development, which is why I want to ask you to be more specific about your question because your text is a little contradictory:
On one hand you ask how to modify an existing component (here: org.primefaces.component.Dialog) to have some pre-set attributes. On the other side you offer a composite component implementation that uses a lot of different components assembled together which hints at completely different needs.
So what exactly do you want to do? i mean in terms of a use case (eg "I want to use a Dialog with two input fields and a caption that always reads 'LeandroDialog'"!)
The reason for this question is to determine whether you need to go for a composite component (which is what you tried, you are bundling UIComponents together via XHTML), a custom component (no XHTML, a component class and renderer class registered in a taglib instead) or a mix of the two, each requiring quite a longish answer.
Even not knowing your exact needs, there are various issues with the code you provided and it won't work indeed, but pointing those out might be a waste of time if a composite turns out not to be the right path of solution.
@kukeltje's: Usually you'd be right about your comment with the form within a dialog but in this specific case the dialog seems to be going to be hardcoded to appendToBody which is save regarding nested forms.
@JanEckert: Well, yes and no... it still may not be a nested form BEFORE the dialog is moved from its rendered position in the DOM to right before the body close tag. That part happens client-side after the initial rendering and it still is illegal to have nested forms before that move.
-
- Posts: 84
- Joined: 11 Sep 2014, 10:13
- Location: Brussels, Belgium
Good point, thanks for the food for thought.kukeltje wrote: ↑18 Jan 2018, 11:08@JanEckert: Well, yes and no... it still may not be a nested form BEFORE the dialog is moved from its rendered position in the DOM to right before the body close tag. That part happens client-side after the initial rendering and it still is illegal to have nested forms before that move.
Primefaces 6.1+
Wildfly 11
Wildfly 11
As I wrote, what I want is to set the properties of the component inside itself, but it isn't possible. What I tried is to set the Id and the widgetVar properties with the value of the name attribute.
What I want to create is a "pre-filled" form dialog, so I just need to add the input components/labels, instead of coding the entire dialog every time.
The composite with a <p:dialog> inside works, but then I have to refer to it with 1 indirection level. For example, in update property, instead of writing update=" :myDialog1 :myDialog2" (just an example) I have then to write update=":myDialog1:theDialog :myDialog2:theDialog".
Well, I have to wrote in various places the same code for a form inside a dialog, with save and cancel buttons, for various "register forms". So, what better than create a template, right?Jan Eckert wrote: ↑18 Jan 2018, 09:34Hi Leandro,
your question touches some quite advanced topic/problems of custom component development, which is why I want to ask you to be more specific about your question because your text is a little contradictory:
On one hand you ask how to modify an existing component (here: org.primefaces.component.Dialog) to have some pre-set attributes. On the other side you offer a composite component implementation that uses a lot of different components assembled together which hints at completely different needs.
So what exactly do you want to do? i mean in terms of a use case (eg "I want to use a Dialog with two input fields and a caption that always reads 'LeandroDialog'"!)
The reason for this question is to determine whether you need to go for a composite component (which is what you tried, you are bundling UIComponents together via XHTML), a custom component (no XHTML, a component class and renderer class registered in a taglib instead) or a mix of the two, each requiring quite a longish answer.
Even not knowing your exact needs, there are various issues with the code you provided and it won't work indeed, but pointing those out might be a waste of time if a composite turns out not to be the right path of solution.
@kukeltje's: Usually you'd be right about your comment with the form within a dialog but in this specific case the dialog seems to be going to be hardcoded to appendToBody which is save regarding nested forms.
So first I "templatized" it, but I had problems with duplicated ids, etc... So I moved to create a "composite component", but then I can't set the properties of the composite component inside itself (to set the id and widgetVar to be the value of name), so then I moved to create the component in java, with no success too (but this is because of my lack of knowledge).
I understand the composite component. I just asked why you (think you) need the c:set. You can use the EL directly in the places where you need the other variable (all but the id one). Then that part should work... setting the ID dynamically on child components does not work and even if it did, setting the id based on a name attribute might be confusing when troubleshooting.
Defining (extending?) an existing class is not how this is meant to be used afaik. So take a step back. Put a `<p:dialog>` as the first tag. But all in there and try.
Defining (extending?) an existing class is not how this is meant to be used afaik. So take a step back. Put a `<p:dialog>` as the first tag. But all in there and try.
-
- Posts: 84
- Joined: 11 Sep 2014, 10:13
- Location: Brussels, Belgium
Hey again!
Sorry for the late answer. but honestly I wrote an elaborate answer just to throw it away in the end because - in all arrogance - I think what you need to know is not what you are asking for. But first your question:
Please note that I removed the attribute 'component-type' from the interface tag. Referencing org.primefaces.component.Dialog here makes btw no sense for many reasons. Neither do these c:sets belong there. I know this way to go about it from Facelet tag files and I think this is your true problem. I dare say that you are royally confused about the different mechanism JSF 2 offers for code re-usage. There is a ridiculously well-written, concise article by the one and only out there. Dig it until you get it.
https://stackoverflow.com/questions/682 ... ponen?rq=1
Hit us up with questions if you still have problems or we missed something from your question.
Sorry for the late answer. but honestly I wrote an elaborate answer just to throw it away in the end because - in all arrogance - I think what you need to know is not what you are asking for. But first your question:
it is possible to set properties within the cc. All the properties you define in the interface (and are potentially set when you re-use the tag) are accessible via the implicit #{cc}-object. Attributes you wish to hardcode can simply be provided within the implementation. If you want to create a CC however, your syntax is way off. Here a concise example:What I want to know is, if it's possible to set properties in CC, how to do it, or, if not possible, what method I have to override from dialog class, and what class (Dialog or DialogRenderer).
Code: Select all
<ui:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="renderText" type="java.lang.Boolean" />
</cc:interface>
<cc:implementation>
<p:outputText rendered="#{cc.attrs.renderText}" value="I am here!"/>
</cc:implementation>
</ui:component>
https://stackoverflow.com/questions/682 ... ponen?rq=1
Hit us up with questions if you still have problems or we missed something from your question.
Primefaces 6.1+
Wildfly 11
Wildfly 11
-
- Information
-
Who is online
Users browsing this forum: No registered users and 45 guests