I'm having difficulty finding support on this topic, because I know how to pass parameters to a template. What I want to do is pass parameters to not be used as parameters to the template but to a component within the template.
For example, in primefaces, you can write the following logic to create a button:
<p:commandButton action="#{printBean.print}">
<f:attribute name="report" value="report.jrxml" />
</p:commandButton>
This is all fine and good when I don't need to pass parameters. However, I need to construct a template which allows me to specify parameters to pass to the report dynamically. My first attempt was to do the following:
<p:commandButton actionListener="#{printBean.print}">
<f:attribute name="report" value="report.jrxml" />
<ui:insert name="reportParams" />
</p:commandButton>
Which would allow me to use the template in the following manner:
<ui:decorate template="templates/report.xhtml" >
<ui:define name="reportParams>
<f:attribute name="reportParam1" value="paramVal1" />
<f:attribute name="reportParam2" value="paramVal2" />
<f:attribute name="reportParam3" value="paramVal3" />
...
</ui:define>
</ui:decorate>
However parameters passed in this way are not received in my action listener in printBean, yet parameter "report" is. I think the attributes passed in this way are interpreted to mean that it is referring to the ui:define tag, and not to be inserted in the template as I would want.
Is there an alternative way of achieving the same way? Keep in mind I'm using JSF 2.0 and primefaces, but not Seam or any added libraries and ideally I would not have to add any libraries to make it work.
I apologize if an answer to this question already exists, but it's maddening searching for an answer to this question.
EDIT: The number of parameters is variable, meaning I can't simply use ui:param and put the value of that parameter as an attribute value within the template, because there could be many such parameters.
Use a composite component instead of a template.
Create this file /resources/mycomponents/printReport.xhtml:
<ui:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui"
>
<cc:interface>
<!-- No attributes. -->
</cc:interface>
<cc:implementation>
...
<p:commandButton value="Print" action="#{printBean.print}" />
...
</cc:implementation>
</ui:component>
Use it as follows:
xmlns:my="http://java.sun.com/jsf/composite/mycomponents"
...
<my:printReport>
<f:attribute name="reportParam1" value="paramVal1" />
<f:attribute name="reportParam2" value="paramVal2" />
<f:attribute name="reportParam3" value="paramVal3" />
</my:printReport>
Rewrite the print method as follows:
public void print() {
UIComponent composite = UIComponent.getCurrentCompositeComponent(FacesContext.getCurrentInstance());
String reportParam1 = (String) composite.getAttributes().get("reportParam1");
String reportParam2 = (String) composite.getAttributes().get("reportParam2");
String reportParam3 = (String) composite.getAttributes().get("reportParam3");
// ...
}
Related
Here is the scenario (simplified):
There is a bean (call it mrBean) with a member and the appropriate getters/setters:
private List<String> rootContext;
public void addContextItem() {
rootContext.add("");
}
The JSF code:
<h:form id="a_form">
<ui:repeat value="#{mrBean.stringList}" var="stringItem">
<h:inputText value="#{stringItem}" />
</ui:repeat>
<h:commandButton value="Add" action="#{mrBean.addContextItem}">
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
</h:form>
The problem is, when clicking the "Add" button, the values that were entered in the <h:inputText/> that represent the Strings in the stringList aren't executed.
Actually, the mrBean.stringList setter (setStringList(List<String> stringList)) is never called.
Any idea why?
Some info -
I'm using MyFaces JSF 2.0 on Tomcat 6.
The String class is immutable and doesn't have a setter for the value. The getter is basically the Object#toString() method.
You need to get/set the value directly on the List instead. You can do that by the list index which is available by <ui:repeat varStatus>.
<ui:repeat value="#{mrBean.stringList}" varStatus="loop">
<h:inputText value="#{mrBean.stringList[loop.index]}" />
</ui:repeat>
You don't need a setter for the stringList either. EL will get the item by List#get(index) and set the item by List#add(index,item).
I have to say I always try to keep code simple and beautiful, mainly using design patterns when possible. Also, I am impressed I did not find anything related to this on the internet (except simple and very vague examples, mostly in javascript using json).
The scenario is: I have to parse/build concrete objects from a file, whose content may be XML, JSON and/or other formats. Heres an example:
Concrete object:
// Contains the common states for the entities
struct EntityModel
{
int hp;
int level;
int armor;
int speed;
// Other attributes...
};
class Entity
{
// Stuff (protected/public/private attributes and functions/methods)
private:
EntityModel* m_model; // Pointer to the model used (flyweight)
// Other attributes...
}
File (XML, in this case):
<entity name="Skeleton" class="Undead">
<attributes>
<hp value="150" />
<level value="10" />
<armor value="75" />
<speed value="15" />
<width value="32" />
<height value="32" />
<experience value="372" />
<texture value="skeleton.png" />
<intelligence value="skeleton.script" />
</attributes>
<restistances>
<resist type="Shock" value="30" />
<resist type="Fire" value="10" />
</resistances>
<attacks>
<spell name="Blizzard" mp="50" damage="130" distance="0" />
<spell name="Fireball" mp="30" damage="100" distance="0" />
</attacks>
<loot>
<drop item="Gold Coin" min="30" max="50" probability="1" />
<drop item="Ruby" min="0" max="2" probability="0.7" />
<drop item="Enchanted Sword" probability="0.25" />
</loot>
</entity>
This is the example of the relationship between an entity model and its file. There will also be other objects that have to be able to be parsed/built/created from their files.
Some may say that a design pattern is not really necessary in this case, as I have seen in a few implementations, although I do really believe there is one. The whole entity creation system involves the abstract factory, pool and flyweight patterns (a createEntity call is requested to the factory, which will see if a flyweight model has already been created and cached in the pool or create and cache the new model).
So, the question is: Are there any proper way to do that? Which one?
I'll be basing on the answer for this very case and adapt to the other object creations, as I have stated. In other words, I need a generic answer.
If this post is missing some information, or is in a wrong section, please forgive me as this is my first post here.
Thanks in advance.
Try the Boost Serialization Library. It has xml, binary, and text save formats. It's not too complicated and has good documentation.
I recommend a derivative of the Factory Design Pattern.
The pattern allows you to construct objects based on a criteria, such as a name or number. The traditional pattern creates objects based on a common base class.
This is a very basic XSL question and I am just getting started with the topic in the context of Umbraco:
I've defined a macro with a XSLT file. The macro has a parameter of type 'ContentPicker'. What I want to do with the macro, is to render the picked content in a certain way. The relevant bit of my XSLT file is this:
<xsl:param name="source" select="/macro/BlogPostSource"/>
<xsl:template match="/">
<div>
<xsl:value-of select="$source/blogPostIntroduction"/>
</div>
I define a parameter, which is set to the parameter of the macro (this works). Now I simply want to render the property blogPostIntroduction which is a generic property on the picked content. This doesn't work. If I use
<xsl:value-of select="$source"/>
the ID of the content is rendered.
Question A: How do I select fields of the selected content?
Question B: Is my idea correct in general or am I missing a better way to do what I need, rather than using macros and XSLT?
I want to use creationDate field in my template in umbraco.
I know that i can extract this field with this
<umbraco:Item field="createDate" runat="server" />
but I want to store this data as a xsl:variable and manipulate it.
How can I do it?
All of a node's attributes and properties are automatically available in your XSLT macros through a variable called currentPage. So, in your macro simply use the following line:
<xsl:variable name="myDate" select="$currentPage/#createDate" />
Should you wish to then format the date, use the function provided by the umbraco.library extension, like so:
<xsl:value-of select="umbraco.library:FormatDateTime($myDate, 'dd-MM-yyyy')" />
If you need more precise manipulation over your date var, look into the Exslt.ExsltDatesAndTimes extension that comes packaged with Umbraco. There's about forty-odd functions in there, too.
I created an xslt called GraphicsRowSlider with the following parameters
<xsl:param name="mediaFolderId" select="/macro/mediaFolderId" />
<xsl:param name="title" select="/macro/title" />
And added the parameters title and mediaFolderId to the related macro.
I then created new Macro Container data type and selected the macro GraphicsRowSlider as allowed macro. I then added a new field of the new data type into a document type and then imported that field into a template.
Finally, from the content, I inserted the macro and added a title and selected media folder... However, I could see that the macro calls the correct xslt with the correct title and mediaFolderId but the parameters are always empty!
Any thought?! Note, I always get this
<?UMBRACO_MACRO macroalias="GraphicsRowSlider" title="Add Title here" mediaFolderId="1159" />
The syntax you are using suggests that you are using an old umbraco version, which one are you using?
The definition how to work with macro parameters can be found on the umbraco wiki: http://our.umbraco.org/wiki/reference/templates/umbracomacro-element/macro-parameters
hth
Your input is an attribute (at least your xml example suggests this) so your xpath should look like this:
<xsl:param name="mediaFolderId" select="/macro/#mediaFolderId" />
<xsl:param name="title" select="/macro/#title" />