JSF2 navigating to *.xhtml files from subfolder *.xhtml file - jsf-2

Is there any way how can navigation from file "file1.xhtml" to another file "file2.xhtml" which is located in parent folder be implemented that "faces-config.xml" navigation is not used at all.
ProjectName
+---+
WebContent
+---+
| subfolder
| +---+
| file1.xhtml
+---+
file2.xhtml
Navigation from file2.xhtml to file1.xtml:
<h:link value="Go to file1" outcome="subfolder/file2" />
Navigation from file1.xhtml to file2.xtml:
<h:link value="Go to file2" outcome="?" />

The following should work
<h:link value="Go to file1" outcome="/file1" />

Related

Trouble with XUL overlay, stringbundleset, getString is not a function, but createBundle method works

So I am working on an old XUL overlay add-on and encountered this problem, and simplified it to a minimal add-on. Was wondering if someone could explain to me if I am doing something wrong, if I misunderstood something, or how to get this to work as expected. Complete code below. Testing in both FF 29.0b1 and 49.0a1, same results.
In the main XUL file, I define a stringbundleset and a stringbundle, both with (very likely) unique IDs. In the JavaScript file, I want to simply get the bundle (not the set) by element ID, and use the getString (or getFormattedString) method. In the main JavaScript file, I have an event listener call a load function which can call other functions, including an init function, where I put the string grabbing code. All the string variables are defined globally with var (outside the init function). The problem is, I get getString is not a function. Further, console.log() DOES NOT EVEN WORK ANYWHERE IN THE FUNCTION, so I can't even check the value of variable that's supposed to hold the returned strings bundle.
In my add-on, I use the exact same pattern in Options and About XUL files, and it works, as the MDN documentation says it should. So I excluded this from the example code.
If attempting to build and test, note that in the example JavaScript code, I have the broken block that tries to use the XUL stringbundle and fails, and the working pure javascript-only technique which uses createBundle() is commented out. This is easily modified with the //* code /**/ comment pattern, just delete the 1st / and add a / on the other block and rebuild the xpi.
Here's an example screenshot of what the working code should create. The add-on relies on the old status bar. I used "The Addon Bar (Restored)" add-on. Note "TSBS" on the status bar. Right click "TSBS", a menu pops up with Options at the top. These labels are pulled in from the .dtd file. The Menu is a sub menu that has labels set by the tsbs.js script, pulling values from the .properties file. The example shows them pulled from the JS-only method. I am trying to get it to work from the XUL/DOM method.
I realize that XUL add-ons will die soon anyways. I realize that I shouldn't be relying solely upon the status bar. I realize I should just use the JS-only method as it seems more reliable. But I am asking this because I noticed it and wanted to learn from it. Any idea how to correct or improve the code pattern, or is this a known problem or common pitfall?
Directory tree:
test_string_bundle_set-1.0.0-fx
+-- chrome
| +-- content
| | +-- tsbs.js
| | +-- tsbs.xul
| +-- locale
| | +-- en-US
| | +-- contents.rdf
| | +-- tsbs.dtd
| | +-- tsbs.properties
+-- chrome.manifest
+-- install.rdf
chrome.manifest:
overlay chrome://browser/content/browser.xul chrome://{00735700-7357-7357-7357-073570073570}/content/tsbs.xul
content {00735700-7357-7357-7357-073570073570} chrome/content/
locale {00735700-7357-7357-7357-073570073570} en-US chrome/locale/en-US/
install.rdf:
<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>{00735700-7357-7357-7357-073570073570}</em:id>
<em:version>1.0.0</em:version>
<em:type>2</em:type>
<em:name>Test String Bundle Sets</em:name>
<em:description>Test String Bundle Sets</em:description>
<em:creator>Quite A. Character</em:creator>
<!--Firefox-->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>29.0</em:minVersion>
<em:maxVersion>49.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
chrome/content/tsbs.js:
var tsbs_strings;
var tsbs_string_4;
var tsbs_string_5;
var tsbs_string_6;
function tsbs_load( ) {
tsbs_init( );
return true;
}
function tsbs_close( ) {
return true;
}
window.addEventListener( 'load', tsbs_load, false );
window.addEventListener( 'close', tsbs_close, false );
function tsbs_init( ) {
//* XUL/DOM method
tsbs_strings = document.getElementById( 'tsbs-strings' );
console.log( 'TSBS->tsbs_init()->tsbs_strings: ' + typeof tsbs_strings );
tsbs_string_4 = tsbs_strings.getString( 'tsbs.properties.string.4' );
tsbs_string_5 = tsbs_strings.getString( 'tsbs.properties.string.5' );
tsbs_string_6 = tsbs_strings.getString( 'tsbs.properties.string.6' );
/**/
/* JS-only method
tsbs_strings = Services.strings.createBundle( 'chrome://{00735700-7357-7357-7357-073570073570}/locale/tsbs.properties' );
console.log( 'TSBS->tsbs_init()->tsbs_strings: ' + typeof tsbs_strings );
tsbs_string_4 = tsbs_strings.GetStringFromName( 'tsbs.properties.string.4' );
tsbs_string_5 = tsbs_strings.GetStringFromName( 'tsbs.properties.string.5' );
tsbs_string_6 = tsbs_strings.GetStringFromName( 'tsbs.properties.string.6' );
/**/
document.getElementById( 'tsbs-item-4' ).label = tsbs_string_4;
document.getElementById( 'tsbs-item-5' ).label = tsbs_string_5;
document.getElementById( 'tsbs-item-6' ).label = tsbs_string_6;
}
chrome/content/tsbs.xul:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://{00735700-7357-7357-7357-073570073570}/locale/tsbs.dtd">
<overlay id="tsbs-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://{00735700-7357-7357-7357-073570073570}/content/tsbs.js"/>
<stringbundleset id="tsbs-stringset">
<stringbundle id="tsbs-strings" src="chrome://{00735700-7357-7357-7357-073570073570}/locale/tsbs.properties"/>
</stringbundleset>
<statusbar id="status-bar">
<statusbarpanel
id="tsbs-display"
label="&tsbs.dtd.statusbarpanel.display;"
pack="end"
context="tsbs-contextmenu"
/>
</statusbar>
<window id="main-window">
<vbox id="tsbs-notifier">
<popupset id="mainPopupSet">
<menupopup id="tsbs-contextmenu" position="before_end">
<menuitem id="tsbs-options" label="&tsbs.dtd.options;"/>
<menuitem label="&tsbs.dtd.string.1;"/>
<menuitem label="&tsbs.dtd.string.2;"/>
<menuitem label="&tsbs.dtd.string.3;"/>
<menu id="tsbs-menu" label="&tsbs.dtd.menu;">
<menupopup id="tsbs-submenu">
<menuitem id="tsbs-item-4"/>
<menuitem id="tsbs-item-5"/>
<menuitem id="tsbs-item-6"/>
</menupopup>
</menu>
</menupopup>
</popupset>
</vbox>
</window>
</overlay>
chrome/locale/en-US/contents.rdf:
<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
<Seq about="urn:mozilla:locale:root">
<li resource="urn:mozilla:locale:en-US"/>
</Seq>
<Description about="urn:mozilla:locale:en-US">
<chrome:packages>
<Seq about="urn:mozilla:locale:en-US:packages">
<li resource="urn:mozilla:locale:en-US:{00735700-7357-7357-7357-073570073570}"/>
</Seq>
</chrome:packages>
</Description>
</RDF>
chrome/locale/en-US/tsbs.dtd:
<!ENTITY tsbs.dtd.statusbarpanel.display "TSBS" >
<!ENTITY tsbs.dtd.options "Options" >
<!ENTITY tsbs.dtd.menu "Menu" >
<!ENTITY tsbs.dtd.string.1 "One" >
<!ENTITY tsbs.dtd.string.2 "Two" >
<!ENTITY tsbs.dtd.string.3 "Three" >
chrome/locale/en-US/tsbs.properties:
extensions.{00735700-7357-7357-7357-073570073570}.description=Test String Bundle Sets
tsbs.properties.string.4=four
tsbs.properties.string.5=five
tsbs.properties.string.6=six
I believe this is your problem:
<stringbundleset id="tsbs-stringset">
In XUL overlays if a direct child of <overlay> has an ID, it's supposed to match an element in the base document. If it does, its contents is inserted under the matching element. If it doesn't this part of an overlay is ignored.
The existing stringbundleset in browser.xul can be matched using:
<stringbundleset id="stringbundleset">
Also I don't believe there's a 'close' event (use 'unload'), and you don't need the contents.rdf since Firefox 2 or so. Regarding console.log() not working - you checked the Browser Console, not the Web Console, right?

Does not work properly id generation on ui:repeat My faces 2.2.9 + prime faces 5.3

Actually I'm working with Myfaces version 2.2.9 and I've the following structure to generate any panel according with a specific number selected by the user.
...
<ui:repeat value="#{garajes}" var="garaje" varStatus="loop">
<p:panelGrid >
<h:outputLabel value="Numero de garaje #{loop.index+1}: " />
<h:outputLabel value="Matricula #{loop.index+1}: " />
<p:inputText value="#{garaje.numeroGaraje}" maxlength="5" >
</p:inputText>
<p:inputText id="matriculaInmobiliariaGaraje-#{loop.index+1}" value="#{garaje.matriculaInmobiliaria}"
maxlength="20">
</p:inputText>
...
</p:panelGrid>
</ui:repeat>
....
So, when is rendered the above code the identifiers are weird, has another things like the following image:
So I don't know how to remove this weird things inside of id
Note: I need a specific id to update another component inside of the loop.
What can I do to get a right identifiers inside of ui:repeat?
As to the concrete problem, just give all NamingContainer components a fixed ID. This includes the <ui:repeat> itself.
<ui:repeat id="garajes" ...>
As to the concrete requirement, you're overcomplicating things. A NamingContainer will all by itself worry about uniqueness of IDs of children. Your attempt in id="matriculaInmobiliariaGaraje-#{loop.index+1}" won't work at all as #{loop} variable isn't available during view build time, when the component is being instantiated with id. Get rid of it. You can inside a NamingContainer just use a relative ID to reference another component in the same NamingContainer.
<ui:repeat ...>
<p:inputText id="foo" />
<p:inputText ...><p:ajax ... update="foo" /></p:inputText>
</ui:repeat>
This will work just fine.
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
How to use EL with <ui:repeat var> in id attribute of a JSF component

How to to add a menu separator for a menuitem in firefox's context menu

I am trying to add a menu separator before and after my menuitem in firefox's contextmenu .
This is my expected output...
| |
| |
|Select All |
|---------------------|
|Show Meaning |
|---------------------|
| |
My code...
<popup id="contentAreaContextMenu">
<menuseparator />
<menuitem id="diction-show-meaning" label="Show meaning" oncommand="" insertafter="context-selectall"/>
<menuseparator />
</popup>
However the menu separators are appearing at the END of the context menu!
How does one enclose a menuitem for contentAreaContextMenu?
I don't prefer to do it dynamically through java script. But let me know if that's the only way possible...
Try
<popup id="contentAreaContextMenu">
<menuitem id="diction-show-meaning" label="Show meaning" oncommand="" insertafter="context-sep-selectall"/>
<menuseparator />
</popup>

Magento layout update XML change impacting all pages

I'm trying to add a static block (which is actually a text link) after my site's home page only, by using the Layout update XML box on the CMS pages interface.
--------------
| |
| Content |
| |
---------------
| Footer |
| Copyright |
---------------
| My Block |
---------------
I've tried adding the block using this code:
<reference name="footer">
<block type="cms/block" name="credits" after="-">
<action method="setBlockId"><block_id>my_block</block_id></action>
</block>
</reference>
The problem is: #1 that my block shows between the Footer and Copyright and #2: the change is visible on all the pages, whereas I only want it to show on my home page and not in the rest of the site...
Note: I'm running a Magento 1.4.0.1
In order to display it only at your home page you have to add your XML under <cms_index_index>.
To adjust positioning use <?php echo $this->getChildHtml('credits') ?> inside of your page/html/footer.phtml.

Java facelets dynamic loading and composite component attributes

Currently I'm trying to implement webpart technology with JavaServer Faces 2.0 with Facelets view technology for educational purposes. I have created facelet templates, facelet custom components and made a few facelet "template" clients. But in one thing I'm stuck. I can't dynamically load controls and put them cc:attributes.
If I have a page for example with static text or bind it with ManagedBean the property ui:include everything works well.
<ui:define name="right-column">
right-column asd
<h:link outcome="asdf" value="link_get">
<f:param name="aa" value="123" />
<f:param name="a" value="123 dd + 20" />
</h:link>
<h:commandLink action="asdf?faces-redirect=true" value="asdf">
<f:param name="aa" value="123" />
</h:commandLink><br />
<ui:include src="./resources/Controls/CategoryTree.xhtml"/><br />
This works even if I put src with MenageBean property.
<ui:include src="#{browseProducts.incudePath}"/>
</ui:define>
Here is my facelet control (data binding is inside this control within #{TreeBean.root}:
<!-- NO INTERFACE -->
<cc:interface>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<!-- This is a very simply scaffolding for Category Three Control.
-->
<p:tree value="#{TreeBean.root}" var="node"
expandAnim="FADE_IN" collapseAnim="FADE_OUT">
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
</cc:implementation>
But I have problem when ui:include points to a control with cc:attribute. I don't know how to initialize this attribute from backing bean and do "stuff".
For example I have this page:
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./resources/layout/Template.xhtml"
xmlns:sc="http://java.sun.com/jsf/composite/Controls">
<ui:define name="right-column">
<sc:dummy ItemCount="10" />
<ui:include src="./resources/Controls/dummy.xhtml" />
</ui:define>
</ui:composition>
Here goes the composite control:
<cc:interface>
<cc:attribute name="ItemCount" required="true"
shortDescription="This attribute is meaningful " />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<!-- How to pass ItemCount to my dummy bean to create so many items in
list as ItemCount value -->
<ui:repeat value="#{dummy.dummyList}" var="dummyItem">
<h:outputText value="#{dummyItem}" />
</ui:repeat>
</cc:implementation>
And backing bean code:
public ArrayList<String> getDummyList() {
//Here I try to get dummy list work.
dummyList = new ArrayList<String>(getDummyCount());
for (int i=0;i< getDummyCount();i++){
dummyList.add(i + "" + i);
}
return dummyList;
}
How can this be done?
I think you have two problems:
calling a method with parameter from a composite component
specifying some parameter to an included page
For 1., since jsf 2, you could call the method directly, specifying the parameter (which should be part of method signature):
<ui:repeat value="#{dummy.getDummyList(cc.attrs.dummyCode)}" var="dummyItem">
<h:outputText value="#{dummyItem}" />
</ui:repeat>
But I suspect you are trying to use a backing for something that it isn't designed for. Maybe you'll be interested in writing backing java code for your composite component, which is different. It's difficult to master if you are a beginner, though. I'd first try to design my pages and bean interactions differently. I don't know which problem you are trying to solve, but at first look, this solution looks too complicated.
For 2., you should have a look at ui:param. A quick google search gives me this: http://www.jsfcentral.com/articles/facelets_3.html

Resources