Skip to content

Commit

Permalink
Feature #130: Required and constraint validations
Browse files Browse the repository at this point in the history
  • Loading branch information
sadiqkhoja committed Jul 12, 2024
1 parent 250a228 commit 7a29948
Show file tree
Hide file tree
Showing 15 changed files with 382 additions and 64 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@
"js/ts.implicitProjectConfig.target": "ES2022",
"[xml]": {
"editor.defaultFormatter": "redhat.vscode-xml"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
}
}
94 changes: 94 additions & 0 deletions packages/ui-solid/fixtures/xforms/validation/1-validation.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jr="http://openrosa.org/javarosa" xmlns:orx="http://openrosa.org/xforms"
xmlns:odk="http://www.opendatakit.org/xforms">
<h:head>
<h:title>Validation Form - with a very very very very very very very very very very very long
title</h:title>
<model odk:xforms-version="1.0.0">
<itext>
<translation lang="default" default="true()">
<text id="/data/profession:jr:requiredMsg">
<value>Please enter your profession</value>
</text>
<text id="/data/citizen:jr:constraintMsg">
<value>It has to be two</value>
</text>
</translation>
<translation lang="Urdu (ur)">
<text id="/data/profession:jr:requiredMsg">
<value>اپنا پروفیشن بتائیں</value>
</text>
<text id="/data/citizen:jr:constraintMsg">
<value>صرف دو ہی ہوسکتی ہیں</value>
</text>
</translation>
</itext>
<instance>
<data id="validation" version="20240708154514">
<first_name />
<last_name />
<profession />
<favourite_color />
<citizen />
<age />
<meta>
<instanceID />
</meta>
</data>
</instance>
<instance id="country">
<root>
<item>
<name>pk</name>
<label>Pakistan</label>
</item>
<item>
<name>ca</name>
<label>Canada</label>
</item>
<item>
<name>us</name>
<label>USA</label>
</item>
</root>
</instance>
<bind nodeset="/data/first_name" type="string" required="true()" />
<bind nodeset="/data/last_name" type="string" required="true()"
jr:requiredMsg="Please enter the Last Name" />
<bind nodeset="/data/profession" type="string" required="true()"
jr:requiredMsg="jr:itext('/data/profession:jr:requiredMsg')" />
<bind nodeset="/data/favourite_color" type="string" constraint=". = &quot;red&quot;" />
<bind nodeset="/data/citizen" type="string" constraint="count-selected(.) = 2"
jr:constraintMsg="jr:itext('/data/citizen:jr:constraintMsg')" />
<bind nodeset="/data/age" type="string" required="true()"
constraint=". &gt; 18 and . &lt; 100" jr:constraintMsg="Age has to be between 18 and 100" />
<bind nodeset="/data/meta/instanceID" type="string" readonly="true()" jr:preload="uid" />
</model>
</h:head>
<h:body>
<input ref="/data/first_name">
<label>First Name</label>
</input>
<input ref="/data/last_name">
<label>Last Name</label>
</input>
<input ref="/data/profession">
<label>Profession</label>
</input>
<input ref="/data/favourite_color">
<label>Favourite Color</label>
</input>
<select ref="/data/citizen">
<label>Citizenships</label>
<itemset nodeset="instance('country')/root/item">
<value ref="name" />
<label ref="label" />
</itemset>
</select>
<input ref="/data/age">
<label>Age</label>
</input>
</h:body>
</h:html>
48 changes: 48 additions & 0 deletions packages/web-forms/icomoon.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,54 @@
"setIdx": 0,
"setId": 0,
"iconIdx": 22
},
{
"icon": {
"paths": [
"M554 554v-256h-84v256h84zM554 726v-86h-84v86h84zM512 86q176 0 301 125t125 301-125 301-301 125-301-125-125-301 125-301 301-125z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": ["error"],
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "error",
"id": 46,
"order": 347,
"prevSize": 48,
"code": 59671,
"name": "error"
},
"setIdx": 0,
"setId": 0,
"iconIdx": 23
},
{
"icon": {
"paths": [
"M512 854q140 0 241-101t101-241-101-241-241-101-241 101-101 241 101 241 241 101zM512 86q176 0 301 125t125 301-125 301-301 125-301-125-125-301 125-301 301-125zM470 298h84v256h-84v-256zM470 640h84v86h-84v-86z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": ["error_outline"],
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "error_outline",
"id": 71,
"order": 373,
"prevSize": 48,
"code": 59672,
"name": "error_outline"
},
"setIdx": 0,
"setId": 0,
"iconIdx": 24
}
],
"height": 1024,
Expand Down
5 changes: 5 additions & 0 deletions packages/web-forms/src/OdkWebFormDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@ const handleSubmit = () => {
const showForm = (form: [string, string]) => {
selectForm.value = form;
history.pushState({form: form }, "", "/" + form[0]);
window.scrollTo(0,0);
}
interface PopStateEventWithForm extends PopStateEvent {
state: {form: [string, string]};
}
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
window.addEventListener("popstate", (event:PopStateEventWithForm) => {
if(!event.state) {
selectForm.value = null;
Expand Down
6 changes: 6 additions & 0 deletions packages/web-forms/src/assets/css/icomoon.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,9 @@
.icon-check:before {
content: '\e916';
}
.icon-error:before {
content: '\e917';
}
.icon-error_outline:before {
content: '\e918';
}
2 changes: 2 additions & 0 deletions packages/web-forms/src/assets/fonts/icomoon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/web-forms/src/assets/fonts/icomoon.ttf
Binary file not shown.
Binary file modified packages/web-forms/src/assets/fonts/icomoon.woff
Binary file not shown.
Loading

0 comments on commit 7a29948

Please sign in to comment.