Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
public class NumberConverters implements ConverterLoader {

private static Number fromString(String str, Locale locale) throws ConversionException {
NumberFormat nf = NumberFormat.getNumberInstance(locale);
NumberFormat nf = NumberFormat.getNumberInstance(Locale.getDefault());
if (nf instanceof DecimalFormat) {
// CHECKSTYLE_OFF: ALMOST_ALL
((DecimalFormat) nf).setParseBigDecimal(true);
Expand Down
5 changes: 5 additions & 0 deletions framework/widget/dtd/widget-form.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,11 @@ under the License.
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="step" type="xs:string">
<xs:annotation>
<xs:documentation>Controls the "step" attribute of the input element. Ignored if the "type" attribute of the field is not "number". See https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/step</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="pattern" type="xs:string">
<xs:annotation>
<xs:documentation>Controls the pattern attribute of the input element. See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern</xs:documentation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ public String getEntry(Map<String, ? extends Object> context, String defaultValu
if (retVal != null) {
// format string based on the user's locale and time zone
if (retVal instanceof Double || retVal instanceof Float || retVal instanceof BigDecimal) {
NumberFormat nf = NumberFormat.getInstance(locale);
NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
nf.setMaximumFractionDigits(10);
return nf.format(retVal);
} else if (retVal instanceof java.sql.Date) {
Expand Down Expand Up @@ -5918,13 +5918,15 @@ public static class TextField extends FieldInfo {
private final SubHyperlink subHyperlink;
private final String type;
private final String pattern;
private final String step;

public TextField(Element element, ModelFormField modelFormField) {
super(element, modelFormField);
this.clientAutocompleteField = !"false".equals(element.getAttribute("client-autocomplete-field"));
this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
this.mask = element.getAttribute("mask");
this.type = element.getAttribute("type");
this.step = element.getAttribute("step");
this.pattern = element.getAttribute("pattern");
Integer maxlength = null;
String maxlengthStr = element.getAttribute("maxlength");
Expand Down Expand Up @@ -5964,6 +5966,7 @@ protected TextField(int fieldSource, int size, Integer maxlength, ModelFormField
this.defaultValue = FlexibleStringExpander.getInstance("");
this.mask = "";
this.type = "";
this.step = "";
this.pattern = "";
this.maxlength = maxlength;
this.placeholder = FlexibleStringExpander.getInstance("");
Expand All @@ -5978,6 +5981,7 @@ protected TextField(int fieldSource, int size, Integer maxlength, String type, M
this.defaultValue = FlexibleStringExpander.getInstance("");
this.mask = "";
this.type = type;
this.step = "";
this.pattern = "";
this.maxlength = maxlength;
this.placeholder = FlexibleStringExpander.getInstance("");
Expand All @@ -5992,6 +5996,7 @@ private TextField(int fieldSource, int fieldType, ModelFormField modelFormField)
this.defaultValue = FlexibleStringExpander.getInstance("");
this.mask = "";
this.type = "";
this.step = "";
this.pattern = "";
this.maxlength = null;
this.placeholder = FlexibleStringExpander.getInstance("");
Expand All @@ -6014,6 +6019,7 @@ protected TextField(TextField original, ModelFormField modelFormField) {
this.defaultValue = original.defaultValue;
this.mask = original.mask;
this.type = original.type;
this.step = original.step;
this.pattern = original.pattern;
this.placeholder = original.placeholder;
this.size = original.size;
Expand Down Expand Up @@ -6135,6 +6141,14 @@ public String getType() {
return this.type;
}

/**
* Gets step.
* @return the step
*/
public String getStep() {
return this.step;
}

/**
* Gets pattern.
* @return the pattern
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ public RenderableFtl textField(final Map<String, Object> context, final ModelFor
if (UtilValidate.isEmpty(type)) {
type = "text";
}
String step = "";
if (type.equals("number")) {
step = textField.getStep();
if (UtilValidate.isEmpty(step)) {
step = "any";
}
}
String pattern = "";
if (List.of("text", "email", "url", "tel").contains(type)) {
pattern = textField.getPattern();
Expand Down Expand Up @@ -308,6 +315,7 @@ public RenderableFtl textField(final Map<String, Object> context, final ModelFor
.stringParameter("name", name)
.stringParameter("className", String.join(" ", classes))
.stringParameter("type", type)
.stringParameter("step", step)
.stringParameter("pattern", pattern)
.stringParameter("alert", alert)
.stringParameter("value", value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ public void textFieldDefaultTypeIsText(@Mocked final ModelFormField.TextField te
final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.textField(Map.of("session", httpSession), textField, true);
assertThat(renderableFtl, MacroCallMatcher.hasName("renderTextField"));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("type", "text")));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("step", "")));
}

@Test
Expand All @@ -266,6 +267,23 @@ public void textFieldTypeNumber(@Mocked final ModelFormField.TextField textField
final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.textField(Map.of("session", httpSession), textField, true);
assertThat(renderableFtl, MacroCallMatcher.hasName("renderTextField"));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("type", "number")));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("step", "any")));
}

@Test
public void textFieldTypeNumberCustomStep(@Mocked final ModelFormField.TextField textField) {
new Expectations() {
{
textField.getType(); result = "number";
textField.getStep(); result = "0.1";
httpSession.getAttribute("delegatorName"); result = "DelegatorName";
}
};

final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.textField(Map.of("session", httpSession), textField, true);
assertThat(renderableFtl, MacroCallMatcher.hasName("renderTextField"));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("type", "number")));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("step", "0.1")));
}

@Test
Expand All @@ -280,6 +298,7 @@ public void textFieldTypeEmail(@Mocked final ModelFormField.TextField textField)
final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.textField(Map.of("session", httpSession), textField, true);
assertThat(renderableFtl, MacroCallMatcher.hasName("renderTextField"));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("type", "email")));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("step", "")));
}

@Test
Expand All @@ -294,6 +313,7 @@ public void textFieldTypeUrl(@Mocked final ModelFormField.TextField textField) {
final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.textField(Map.of("session", httpSession), textField, true);
assertThat(renderableFtl, MacroCallMatcher.hasName("renderTextField"));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("type", "url")));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("step", "")));
}

@Test
Expand All @@ -308,6 +328,7 @@ public void textFieldTypeTel(@Mocked final ModelFormField.TextField textField) {
final RenderableFtl renderableFtl = renderableFtlFormElementsBuilder.textField(Map.of("session", httpSession), textField, true);
assertThat(renderableFtl, MacroCallMatcher.hasName("renderTextField"));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("type", "tel")));
assertThat(renderableFtl, MacroCallMatcher.hasParameters(MacroCallParameterMatcher.hasNameAndStringValue("step", "")));
}

@Test
Expand Down
3 changes: 2 additions & 1 deletion themes/common-theme/template/macro/HtmlFormMacroLibrary.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ under the License.
</#macro>
<#macro renderHyperlinkField></#macro>

<#macro renderTextField type pattern name className alert value="" textSize="" maxlength="" id="" event="" action=""
<#macro renderTextField type step pattern name className alert value="" textSize="" maxlength="" id="" event="" action=""
disabled=false clientAutocomplete="" ajaxUrl="" ajaxEnabled="" mask="" tabindex="" readonly="" required=false
placeholder="" delegatorName="default">
<input type="${type}" name="${name?default("")?html}"<#t/>
Expand All @@ -69,6 +69,7 @@ under the License.
<#if tabindex?has_content> tabindex="${tabindex}"</#if><#rt/>
<#if required?has_content && required> required</#if>
<#if pattern?has_content> pattern="${pattern}"</#if>
<#if step?has_content> step="${step}"</#if>
/><#t/>
</#macro>

Expand Down
Loading