Date/Time placeholder localization - orbeon

I am coping with the localization of the Date/Time placeholders in form-runner of Orbeon 2018 (albeit it seems this has not been changed in 2019 and 2020 neither).
What I am looking for is defined in orbeon-form-runner.jar\xbl\orbeon\date\date.xbl (and time/time.xbl, but for now, I think it is enough to discuss the first one) file, more specifically here:
<xf:var
name="placeholder"
value="
let $format := xxf:property('oxf.xforms.format.input.date'),
$cleaned := translate($format, '[01]', ''),
$duplicate := replace(replace(replace($cleaned,
'M', 'MM'),
'D', 'DD'),
'Y', 'YYYY'),
$format-en := instance('orbeon-resources')/resource[#xml:lang = 'en']/format,
$format-lang := xxf:r('format'),
$translated := translate($duplicate, $format-en, $format-lang)
return
$translated
"/>
<xh:input type="text" placeholder="{$placeholder}" id="input"/>
The placeholder variable is assembled over the html input, this is clear.
In my language, the YYYY, MM, DD is not the right placeholder for date parts, so my requirement is to change them depending on the current request locale.
At first I tried to extend the labels in the apps/fr/18n/resource.xml, and I replaced the static 'MM', 'DD', etc. constants with xxf:r('components.labels.MM', '|fr-fr-resources|')) and similar things without any success (okay, the placeholder has been displayed, but the same default placeholder that was visible before my modification).
My second approach was to put these labels to the same file, and refer them on the same way: xxf:r('MM'), no success (the same result as in the first case).
My third approach, and I am here now, was to trying to hardcode these static things and only fix these labels for my locale (using an xsl:choose) and here I am: I can't find how on earth could I grab the request locale here (in the context of xbl files).
Neither the <xf:var name="lang" value="xxf.instance('fr-language-instance')"/>, nor the <xf:var name="fr-lang" value="xxf.instance('fr-fr-language-instance')"/> variables pointed to the right current request locale (they showed as "en").
Do you have any idea how to solve this properly?

You define the input format through the oxf.xforms.format.input.date property. And there can be only one input format, which can't depend on the current language.
In the placeholder, the component shows the format you defined through in oxf.xforms.format.input.date, but changing the letter M (month), D (day), and Y (year) to match the current language, and that is done by adding a resource to orbeon-resources, which has currently:
<resource xml:lang="en"><format>MDY</format></resource>
<resource xml:lang="fr"><format>MJA</format></resource>
<resource xml:lang="de"><format>MTJ</format></resource>
<resource xml:lang="pl"><format>YMD</format></resource>

Related

SPParameters Not Matching Stored Procedure

I have posted this question in the Logi Analytics DevNet but it is a graveyard there and I am hoping I can get an answer here. I am using Logi Info v12.2.116.
I am using a stored procedure to get data to fill my reports. The stored procedure calls an RPG program. I have done this many times, but today when I created a new stored procedure, a new report, the parameters for some reason do not match up. I have restarted Logi as well... Sometimes it doesn't pick up new stored procedures until it reboots but that didn't work either. I have never seen this error before:
The number of parameter values set or registered does not match the number of parameters
Here is the code for my parameters:
<DataLayer Type="SP" Command="myStoredProcedure">
<SPParameters NullValue="'">
<SPParameter SPParamDirection="Input" ID="GAct" SPParamSize="2" SPParamType="dt-129" Value="RE" />
<SPParameter SPParamDirection="Input" ID="rsDetail" SPParamType="dt-129" Value="N" SPParamSize="1" />
<SPParameter SPParamDirection="Input" ID="rsFromDate" SPParamSize="10" SPParamType="dt-7" Value="# Request.paramFromDate~" />
<SPParameter SPParamDirection="Input" ID="rsToDate" SPParamSize="10" SPParamType="dt-7" Value="# Request.paramToDate~" />
<SPParameter SPParamDirection="Input" ID="rsDepts" SPParamSize="256" SPParamType="dt-129" Value="# Request.paramAllDepartments~" />
</SPParameters>
Here is the stored procedure definition:
1 IN GACT CHARACTER 2 No default
2 IN RSDETAIL CHARACTER 1 No default
3 IN RSFROMDATE DATE No default
4 IN RSTODATE DATE No default
5 IN RSDEPTS CHARACTER 256 No default
What in the world is causing this problem? Yes I am connecting to the same partition/library. Yes the program and stored procedure work perfectly fine when being called outside of Logi. Yes I am calling the right stored procedure.
Change:
<SPParameter SPParamDirection="Input" ID="GAct" SPParamSize="2" SPParamType="dt-129" Value="RE" />
To:
<SPParameter SPParamDirection="Input" ID="GAct" SPParamSize="2" SPParamType="dt-200" Value="RE" />
Char is generally considered to be a single character and is likely what is causing your issue. Also, unrelated, but I typically just use size 0 on all my SPParams to avoid truncation issues.

Can MSXML XPath select attributes? ( UPD: real issue was with default no-prefix namespace )

I want to try parsing Excel XML Spreadsheet file with MSXML and XPath.
https://technet.microsoft.com/en-us/magazine/2006.01.blogtales
https://msdn.microsoft.com/en-us/library/aa140066.aspx
It has a root element of <Workbook xmlns.... xmlns....> and a bunch of next-level nodes <Worksheet ss:Name="xxxx">.
<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
....
<Worksheet ss:Name="Карточка">
....
</Worksheet>
<Worksheet ss:Name="Баланс">
...
...
...
</Worksheet>
</Workbook>
At a certain step I want to use XPath to get the very names of the worksheets.
NOTE: I do not want the get the names indirectly, that is to select those Worksheet nodes first and then enumerating them manually read their ss:Name child attribute nodes. That I can do, and it is not the topic here.
What I want is to utilize XPath flexibility: to directly fetch those ss:Name nodes without extra indirection layers.
procedure DoParseSheets( FileName: string );
var
rd: IXMLDocument;
ns: IDOMNodeList;
n: IDOMNode;
sel: IDOMNodeSelect;
ms: IXMLDOMDocument2;
ms1: IXMLDOMDocument;
i: integer;
s: string;
begin
rd := TXMLDocument.Create(nil);
rd.LoadFromFile( FileName );
if Supports(rd.DocumentElement.DOMNode,
IDOMNodeSelect, sel) then
begin
ms1 := (rd.DOMDocument as TMSDOMDocument).MSDocument;
if Supports( ms1, IXMLDOMDocument2, ms) then begin
ms.setProperty('SelectionNamespaces',
'xmlns="urn:schemas-microsoft-com:office:spreadsheet" '+
'xmlns:o="urn:schemas-microsoft-com:office:office" '+
'xmlns:x="urn:schemas-microsoft-com:office:excel" '+
'xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"');
ms.setProperty('SelectionLanguage', 'XPath');
end;
// ns := sel.selectNodes('/Workbook/Worksheet/#ss:Name/text()');
// ns := sel.selectNodes('/Workbook/Worksheet/#Name/text()');
ns := sel.selectNodes('/Workbook/Worksheet/#ss:Name');
// ns := sel.selectNodes('/Workbook/Worksheet/#Name');
// ns := sel.selectNodes('/Workbook/Worksheet');
for i := 0 to ns.length - 1 do
begin
n := ns.item[i];
s := n.nodeValue;
ShowMessage(s);
end;
end;
end;
When I use the dumbed down '/Workbook/Worksheet' query MSXML correctly return the nodes. But as soon as I add the attribute to the query - MSXML returns empty set.
Other XPath implementations like XMLPad Pro or http://www.freeformatter.com/xpath-tester.html correctly return the list of ss:Name attribute nodes. But MSXML does not.
What would be the XPath query text to help MSXML return the attribute nodes with given names ?
UPD. #koblik suggested a link to MS.Net selector (not MSXML one) and there are two examples there
https://msdn.microsoft.com/en-us/library/ms256086(v=vs.110).aspx
Example 1: book[#style] - All elements with style attributes, of the current context.
Example 2: book/#style - The style attribute for all elements of the current context.
That is the difference I told in the "NOTE" above: I don't need those books, I need the styles. I need attribute-nodes, not element-nodes!
And that Example 2 syntax is what MSXML seems to fail at.
UPD.2: One tester shows an interesting error claim:
The default (no prefix) Namespace URI for XPath queries is always '' and it cannot be redefined to 'urn:schemas-microsoft-com:office:spreadsheet'
I wonder if that claim about no default namespaces in XPath is really part of standard or just MSXML implementation limitation.
Then if to delete the default NS the results are how they should be:
Variant 1:
Variant 2:
I wonder if that claim about no default namespaces in XPath is really part of standard or just MSXML implementation limitation.
UPD.3: Martin Honnen in comments explains that line: See w3.org/TR/xpath/#node-tests for XPath 1.0 (as supported by Microsoft MSXML), it clearly states "A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end-tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null". So in XPath 1.0 a path like "/Workbook/Worksheet" selects elements of that name in no namespace.
UPD.4: So the selection works with '/ss:Workbook/ss:Worksheet/#ss:Name' XPath query, returning "ss:Name" attributes nodes directy. In the source XML document both default (no-prefix) and "ss:" namespaces are bound to the same URI. This URI is acknowledged by the XPath engine. But not the default namespace, which can not be redefined in MSXML XPath engine ( implementing 1.0 specs ). So to make it work, the default namespace should be mapped to another explicit prefix ( either already existing one or a newly created ) via URI and then that substitute prefix would be used in the XPath selection string. Since namespaces matching goes via URI not via prefixes it would not matter if prefixes used in the document and in the query match or not, they would be compared via their URIs.
ms.setProperty('SelectionLanguage', 'XPath');
ms.setProperty('SelectionNamespaces',
'xmlns:AnyPrefix="urn:schemas-microsoft-com:office:spreadsheet"');
and then
ns := sel.selectNodes(
'/AnyPrefix:Workbook/AnyPrefix:Worksheet/#AnyPrefix:Name' );
Thanks to Asbjørn and Martin Honnen for explaining those trivial after-the-fact but not obvious a priori relations.
The issue is that MSXML doesn't support default namespaces when using XPath. To overcome this, you must give the default namespace an explicit prefix, and use this:
ms.setProperty('SelectionNamespaces',
'xmlns:d="urn:schemas-microsoft-com:office:spreadsheet" '+
'xmlns:o="urn:schemas-microsoft-com:office:office" '+
'xmlns:x="urn:schemas-microsoft-com:office:excel" '+
'xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"');
Note how I added the d prefix to the default namespace. Then you can do the selection like this:
ns := sel.selectNodes('/d:Workbook/d:Worksheet/#ss:Name');
The reason this works is that when parsing the XML data, MSXML associates the namespace to each node. At this stage it does handle the default namespace, so the Workbook elements get associated with the urn:schemas-microsoft-com:office:spreadsheet namespace.
However, note that it does not store the namespace prefixes! Thus you can use your own prefixes for the namespaces when you set SelectionNamespaces.
Now, when doing the XPath selection, if the nodes have a namespace you have to specify namespaces for all elements in the XPath, like my example above. And then you use your own prefixes which you set with SelectionNamespaces.

Strange behaviour with xxf:format attribute in my Xforms form (using Orbeon Form Runner)

I have a numeric input field in my form. I just add some format on it with xxf:format :
<xf:input
id="input-control"
bind="input-bind"
class="question nombre"
xxf:format="if (. castable as xs:integer)
then replace(format-number(xs:integer(.),'###,###,###,###,###,###,###,###,###,##0'),',',' ')
else ''">
This may look a bit wild but it's just a format where number 123456 will be presented as 123 456. This works great for me, but not for users...
So now, I added a script to cancel formatting when input is focused (aka : go back to 123456 when editing the field) with a simple js :
<xf:action ev:event="DOMFocusIn">
<xxf:script>
var input = this.getElementsByTagName('input')[0];
var valeur = input.value.replace(' ','');
input.value = valeur;
</xxf:script>
</xf:action>
Behaviour looks ok at first sight, I mean, I entered 123456, focus out and got 123 456 (format ok), focus in and got 123456 (script behaviour ok). But if I don't make any changes on the field and focus out, I don't have the format back (still 123456 instead of 123 456).
I understand that the format is only applied when "needed" and "needed" means here, when the value of the input changes. But if I force an xforms-value-change event I still don't have the format back.
Anyone has an idea on how to achieve this ?
(anyone has understood anything ? :-s)
This can be tricky to get right. I would recommend using instead the fr:number control, which does all of this for you.

Find child of child which attribute code is equal to the parameter passed on the url - XSL

On this dynamic website,
The url looks something like this : departments/CHEM.html
CHEM is a parameter.
<xsl:param name="dep" select="'CHEM'" />
a piece of the xml is below
<course acad_year="2012" cat_num="5085" offered="Y">
<term term_pattern_code="1" fall_term="Y" spring_term="N">fall term</term>
<department code="CHEM">
<dept_long_name>Department of Chemistry and Chemical Biology</dept_long_name>
<dept_short_name>Chemistry and Chemical Biology</dept_short_name>
</department>
</course> ....
I am trying to get the dept_short_name to use on my H1 tag, but I have not been successful.So far I tried
<h2><xsl:value-of select="course/department/[code={#$dep}]"/></h2>
Any suggestions??? Thanks!
Just use:
<xsl:value-of select="course/department[#code eq $dep]/dept_short_name"/>
Remember:
In XPath 2.0 (XSLT 2.0) use the eq operator for value comparissons -- it is more efficient than the general comparisson operator = which really, only, needs to be used when at least one of its operands is a sequence.
I would try this:
<xsl:value-of select="course/department[#code=$dep]/dept_short_name/text()"/>
That says: find the department element (inside a course element) whose code attribute is the value of parameter "dep", then find the dept_short_name child element, then get the text inside that element.
You have to use the # to say that "code" is an attribute, but "dep" should not have it. I think the {} notation is for use inside attributes of the non-XSLT elements of your stylesheet, so I wouldn't use it inside a value-of expression.

How to use locale entity in js-code

is it possible to get the value of an entity
<!ENTITY gatwayError "Gateway error">
using javascript? For now I reference them in my xul file using
&gatewayError;
UPDATE: In my ff-sidebar.xul within the <page> I have
<stringbundleset id="stringbundleset">
<stringbundle id="strings"
src="chrome://myaddon/locale/de/sidebar.properties"/>
</stringbundleset>
In my ff-sidebar.js I do on click:
var strbundle = document.getElementById("strings");
var localizedString = strbundle.getString("test");
This gives me following error
Should it not be
var strbundle = document.getElementById("stringbundleset");
This gives me no error but no result too.
Basically what Neil posted there is what you need to do (minus first paragraph rant :P )
Here's an example (basically digest from Neil's links):
Your XUL file:
<stringbundleset id="strbundles">
<stringbundle id="strings" src="chrome://yourextension/locale/something.properties"/>
</stringbundleset>
Your something.properties (there you define your localized strings key=value). Of course you can have as many files as you want/need:
something=Some text for localization
something2=Some more text
Your js file:
var strbundle = document.getElementById("strings");
var localizedString = strbundle.getString("something");
Hope this helps.
This works for small numbers of entities. For instance, menuitems sometimes have two entities with slightly different text depending on what the menuitem will be used for, and the correct entity is then copied to the label. The worst abuse of this was for the Delete menuitem in Thunderbird and SeaMonkey's mail windows, which had labels for unsubscribing from newsgroups, deleting folders, cancelling news posts, deleting single or multiple messages, or undeleting single or multiple messages from folders using the IMAP mark as delete model. Phew!
If you have lots of locale data then the best thing is to put it in its own .properties file and read it using a <stringbundle>. If your script doesn't have access to a <stringbundle> element it is also possible to manually retrieve an nsIStringBundle from the nsIStringBundleService.

Resources