Permalink
Fetching contributors…
Cannot retrieve contributors at this time
233 lines (206 sloc) 11.6 KB
<!--
Copyright (C) 2010 Orbeon, Inc.
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU Lesser General Public License as published by the Free Software Foundation; either version
2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
-->
<xbl:xbl xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:oxf="http://www.orbeon.com/oxf/processors"
xmlns:NumberSupport="java:org.orbeon.xbl.NumberSupportJava">
<xbl:binding
id="fr-number"
element="
fr|number,
xf|input:xxf-type('xs:decimal'),
xf|input:xxf-type('xs:integer')"
xxbl:mode="lhha binding value focus javascript-lifecycle"
xxf:external-events="fr-set-client-value"
xxbl:label-for="html-input">
<metadata xmlns="http://orbeon.org/oxf/xml/form-builder">
<display-name lang="en">Number</display-name>
<display-name lang="es">Número</display-name>
<display-name lang="fi">Numero</display-name>
<display-name lang="fr">Nombre</display-name>
<display-name lang="ru" todo="true">[Number]</display-name>
<display-name lang="de">Zahlenwert</display-name>
<display-name lang="it">Valore numerico</display-name>
<display-name lang="sv">Numeriskt värde</display-name>
<display-name lang="nl">Getal</display-name>
<display-name lang="pt">Número</display-name>
<icon>
<small-icon>/apps/fr/style/images/other/number123-16.png</small-icon>
<large-icon>/apps/fr/style/images/other/number123-16.png</large-icon>
</icon>
<templates>
<bind type="xf:decimal"/>
<view>
<fr:number xmlns:xf="http://www.w3.org/2002/xforms">
<xf:label ref=""/>
<xf:hint ref=""/>
<xf:help ref=""/>
<xf:alert ref=""/>
</fr:number>
</view>
</templates>
</metadata>
<xbl:resources>
<xbl:style src="/xbl/orbeon/number/number.css"/>
</xbl:resources>
<xbl:handlers>
<xbl:handler event="fr-set-client-value">
<xf:setvalue
ref="xxf:binding('fr-number')"
value="
NumberSupport:getStorageValueJava(
event('value'),
xxf:binding('fr-number'),
xxf:component-param-value('decimal-separator'),
xxf:component-param-value('grouping-separator'),
xxf:component-param-value('prefix'),
xxf:component-param-value('digits-after-decimal'),
string(xxf:component-param-value('round-when-formatting')) = 'true',
string(xxf:component-param-value('round-when-storing')) = 'true'
)"/>
</xbl:handler>
<!-- Update field when formatted value changes or iteration moves. Do this here so client has valid observer id. -->
<xbl:handler
phase="target"
event="xxforms-visible xforms-value-changed fr-iteration-moved">
<xf:var
name="display-and-edit-values"
value="
NumberSupport:getDisplayAndEditValueJava(
xxf:binding('fr-number'),
xxf:component-param-value('decimal-separator'),
xxf:component-param-value('grouping-separator'),
xxf:component-param-value('prefix'),
xxf:component-param-value('digits-after-decimal'),
string(xxf:component-param-value('round-when-formatting')) = 'true',
string(xxf:component-param-value('round-when-storing')) = 'true'
)"/>
<xf:action type="javascript">
<xf:param name="displayValue" value="$display-and-edit-values[1]"/>
<xf:param name="editValue" value="$display-and-edit-values[2]"/>
<xf:param name="decimalSeparator" value="xxf:component-param-value('decimal-separator')"/>
<xf:body>var i = ORBEON.xforms.XBL.instanceForControl(this); if (i) i.updateWithServerValues(displayValue, editValue, decimalSeparator);</xf:body>
</xf:action>
</xbl:handler>
<xbl:handler
phase="target"
event="DOMFocusOut">
<xf:var
name="display-and-edit-values"
value="
NumberSupport:getDisplayAndEditValueJava(
xxf:binding('fr-number'),
xxf:component-param-value('decimal-separator'),
xxf:component-param-value('grouping-separator'),
xxf:component-param-value('prefix'),
xxf:component-param-value('digits-after-decimal'),
string(xxf:component-param-value('round-when-formatting')) = 'true',
string(xxf:component-param-value('round-when-storing')) = 'true'
)"/>
<xf:action type="javascript">
<xf:param name="displayValue" value="$display-and-edit-values[1]"/>
<xf:param name="editValue" value="$display-and-edit-values[2]"/>
<xf:param name="decimalSeparator" value="xxf:component-param-value('decimal-separator')"/>
<xf:body>var i = ORBEON.xforms.XBL.instanceForControl(this); if (i) i.updateWithServerValues(displayValue, editValue, decimalSeparator);</xf:body>
</xf:action>
</xbl:handler>
</xbl:handlers>
<xbl:template>
<xf:var
name="binding"
value="xxf:binding('fr-number')"/>
<xf:var
name="view"
value="
xxf:is-control-readonly('fr-number') and
property('xxf:readonly-appearance') = 'static'"/>
<!--<xf:dispatch event="xxforms-iteration-moved" name="fr-iteration-moved" targetid="formatted-value"/>-->
<!-- Readwrite mode -->
<xf:group ref="$binding[not($view)]">
<xf:var name="prefix" value="xxf:component-param-value('prefix')"/>
<xf:var name="suffix" value="xxf:component-param-value('suffix')"/>
<!-- See also https://github.com/orbeon/orbeon-forms/issues/2495 -->
<!--
Visible HTML input
- `.xforms-input-input`: so the border gets highlighted when the container gets `.xforms-invalid.xforms-visited`
- `step="any"`: so that even for numbers with decimal digits, increments/decrements are by 1
- `pattern`:
- triggers the numeric keypad on iOS when needed
- use `fraction-digits` common constraint instead of `$digits-after-decimal`, because what matters to select
the keypad is that the *expected* format be a non-negative integer, while `$digits-after-decimal` is used
for formatting only
- also tests on the `integer` datatype, which is the same as `fraction-digits = 0`
- `maxlength`:
- not natively supported for `type="number"`, but when JavaScript support is enabled, the attribute can be read to enforce
a maximum number of allowed characters to type (https://github.com/orbeon/orbeon-forms/issues/2486)
- if a `maxlength` or `xxf:maxlength` is placed on the bound element, that takes precedence
- `min`: makes control natively invalid as the user types, if the value cannot be negative
-->
<xh:span
class="fr-width-max-10em {
(
'input-prepend'[xxf:non-blank($prefix)],
'input-append' [xxf:non-blank($suffix)]
)
}">
<xf:group xxbl:use-if-attr="prefix" class="add-on" ref=".[xxf:non-blank($prefix)]"><xf:output value="$prefix"/></xf:group>
<xh:input
id="html-input"
class="xbl-fr-number-visible-input xbl-html-input xforms-input-input"
type="text"
step="any"
pattern="{
if (NumberSupport:isZeroValidationFractionDigitsJava($binding) and
xxf:custom-mip($binding, 'non-negative') = 'true'
) then
'[0-9]*'
else
'.*'
}"
min="{
if (xxf:custom-mip($binding, 'non-negative') = 'true') then
'0'
else
''
}"
maxlength="{xs:integer(xxf:custom-mip($binding, 'max-length')[. castable as xs:integer])}"
xbl:attr="tabindex tabindex=navindex maxlength=xxf:maxlength maxlength pattern=xxf:pattern"/>
<xf:group xxbl:use-if-attr="suffix" class="add-on" ref=".[xxf:non-blank($suffix)]"><xf:output value="$suffix"/></xf:group>
</xh:span>
</xf:group>
<!-- Static readonly mode -->
<xf:input
ref="$binding[$view]"
xxf:format="
string-join(
(
xxf:component-param-value('prefix'),
NumberSupport:getDisplayAndEditValueJava(
xxf:binding('fr-number'),
xxf:component-param-value('decimal-separator'),
xxf:component-param-value('grouping-separator'),
xxf:component-param-value('prefix'),
xxf:component-param-value('digits-after-decimal'),
string(xxf:component-param-value('round-when-formatting')) = 'true',
string(xxf:component-param-value('round-when-storing')) = 'true'
)[1],
xxf:component-param-value('suffix')
),
' '
)"/>
</xbl:template>
</xbl:binding>
</xbl:xbl>