Skip to content

Commit

Permalink
Implement composite question
Browse files Browse the repository at this point in the history
  • Loading branch information
holubv committed Jan 9, 2021
1 parent 6489957 commit cf0f579
Show file tree
Hide file tree
Showing 3 changed files with 325 additions and 2 deletions.
101 changes: 99 additions & 2 deletions src/components/Question.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Card, Accordion } from 'react-bootstrap';
import { Accordion, Card } from 'react-bootstrap';
import JsonLdUtils from 'jsonld-utils';
import PropTypes from 'prop-types';
import Answer from './Answer';
Expand All @@ -12,7 +12,7 @@ import ValidatorFactory from '../model/ValidatorFactory';
import JsonLdObjectUtils from '../util/JsonLdObjectUtils';
import PrefixIcon from './PrefixIcon';
import MediaContent from './MediaContent';
import { CaretSquareUp, CaretSquareDown, InfoCircle } from '../styles/icons';
import { CaretSquareDown, CaretSquareUp, InfoCircle } from '../styles/icons';
import { ConfigurationContext } from '../contexts/ConfigurationContext';
import classNames from 'classnames';

Expand All @@ -35,12 +35,93 @@ export default class Question extends React.Component {

onAnswerChange = (answerIndex, change) => {
this._onChange(Constants.HAS_ANSWER, answerIndex, change);

const question = this.props.question;
if (JsonLdUtils.getJsonAttValue(question, Constants.COMPOSITE_PATTERN)) {
this._updateExpandedParts(change);
}
};

onSubQuestionChange = (subQuestionIndex, change) => {
this._onChange(Constants.HAS_SUBQUESTION, subQuestionIndex, change);

const question = this.props.question;
if (JsonLdUtils.getJsonAttValue(question, Constants.COMPOSITE_PATTERN)) {
this._updateCollapsedComposite();
}
};

_updateExpandedParts() {
const question = this.props.question;
const subQuestions = this._getSubQuestions();

const patternVariables = question[Constants.COMPOSITE_VARIABLES];

let regex = new RegExp(question[Constants.PATTERN]);
/**
* @var {string} value
*/
let value = question[Constants.HAS_ANSWER][0][Constants.HAS_DATA_VALUE]['@value'];
let match = value.match(regex);

if (match) {

for (let i = 1; i < match.length; i++) {
let subValue = match[i];
if (!subValue) {
subValue = '';
}

let id = patternVariables[i - 1];
let subQuestion = this._findById(subQuestions, id);

subQuestion[Constants.HAS_ANSWER][0][Constants.HAS_DATA_VALUE] = {
'@value': subValue.trim()
}
}

} else {
subQuestions.forEach(subQuestion => {
subQuestion[Constants.HAS_ANSWER][0][Constants.HAS_DATA_VALUE] = {
'@value': ''
}
});
}

}

_findById(arr, id) {
return arr.find(el => el['@id'] === id);
}

_updateCollapsedComposite() {
const question = this.props.question;
const subQuestions = this._getSubQuestions();

/**
* @var {string} compositePattern
*/
let compositePattern = question[Constants.COMPOSITE_PATTERN];
const patternVariables = question[Constants.COMPOSITE_VARIABLES];

for (let i = patternVariables.length; i >= 1; i--) {

let id = patternVariables[i - 1];
let subQuestion = this._findById(subQuestions, id);

let val = subQuestion[Constants.HAS_ANSWER][0][Constants.HAS_DATA_VALUE]['@value'];
if (!val) {
val = '';
}

compositePattern = compositePattern.replace('?' + i, val.trim());
}

let change = {};
change[Constants.HAS_DATA_VALUE] = {'@value': compositePattern.trim()}
this._onChange(Constants.HAS_ANSWER, 0, change);
}

_onChange(att, valueIndex, newValue) {
let newState = { ...this.props.question };
newState[att][valueIndex] = newValue;
Expand Down Expand Up @@ -84,6 +165,20 @@ export default class Question extends React.Component {
);
}
}

if (JsonLdUtils.getJsonAttValue(question, Constants.COMPOSITE_PATTERN)) {
return (
<Card className="mb-3">
<div className="p-3">
{this.renderAnswers()}
<div className="p-3">
{this.renderSubQuestions()}
</div>
</div>
</Card>
);
}

if (FormUtils.isSection(question)) {
const { collapsible, withoutCard } = this.props;
const categoryClass = Question._getQuestionCategoryClass(question);
Expand Down Expand Up @@ -146,6 +241,8 @@ export default class Question extends React.Component {
FormUtils.isSparqlInput(question) ||
FormUtils.isTurtleInput(question);
cls = classNames(Question._getAnswerClass(isTextarea), Question._getQuestionCategoryClass(question));


row.push(
<div key={'row-item-' + i} className={cls} id={question['@id']}>
<div className="row">
Expand Down
3 changes: 3 additions & 0 deletions src/constants/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export default class Constants {
static IS_DISABLED = 'http://onto.fel.cvut.cz/ontologies/aviation/form-376/is-disabled';
static INPUT_MASK = 'http://onto.fel.cvut.cz/ontologies/form/has-input-mask';
static LAYOUT_CLASS = 'http://onto.fel.cvut.cz/ontologies/form-layout/has-layout-class';
static COMPOSITE_PATTERN = 'http://onto.fel.cvut.cz/ontologies/form/has-composite-pattern';
static PATTERN = 'http://onto.fel.cvut.cz/ontologies/form/has-pattern';
static COMPOSITE_VARIABLES = 'http://onto.fel.cvut.cz/ontologies/form/has-composite-variables';
static LAYOUT = {
FORM: 'form',
QUESTION_SECTION: 'section',
Expand Down
223 changes: 223 additions & 0 deletions test/rendering/form3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
{
"@context": {
"doc": "http://onto.fel.cvut.cz/ontologies/documentation/",
"x": "https://x.com/x/",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"form": "http://onto.fel.cvut.cz/ontologies/form/",
"owl": "http://www.w3.org/2002/07/owl#",
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"xml": "http://www.w3.org/XML/1998/namespace",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"label": {
"@id": "http://www.w3.org/2000/01/rdf-schema#label"
},
"has_data_value": {
"@id": "http://onto.fel.cvut.cz/ontologies/documentation/has_data_value"
},
"has_answer": {
"@id": "http://onto.fel.cvut.cz/ontologies/documentation/has_answer"
},
"has-answer-origin": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-answer-origin"
},
"has-possible-values-query": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-possible-values-query"
},
"has-possible-value": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-possible-value"
},
"has-layout-class": {
"@id": "http://onto.fel.cvut.cz/ontologies/form-layout/has-layout-class"
},
"has_related_question": {
"@id": "http://onto.fel.cvut.cz/ontologies/documentation/has_related_question",
"@type": "@id"
},
"has-question-origin": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-question-origin",
"@type": "@id"
},
"is-relevant-if": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/is-relevant-if",
"@type": "@id"
},
"has-tested-question": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-tested-question",
"@type": "@id"
},
"accepts-answer-value": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/accepts-answer-value",
"@type": "http://www.w3.org/2001/XMLSchema#boolean"
},
"minInclusive": {
"@id": "http://www.w3.org/2001/XMLSchema#minInclusive"
},
"maxInclusive": {
"@id": "http://www.w3.org/2001/XMLSchema#maxInclusive"
},
"has-datatype": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-datatype",
"@type": "@id"
},
"has-preceding-question": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-preceding-question",
"@type": "@id"
},
"comment": {
"@id": "http://www.w3.org/2000/01/rdf-schema#comment"
},
"has-unit": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-unit"
},
"has-input-mask": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-input-mask"
},
"description": {
"@id": "http://purl.org/dc/elements/1.1/description"
},
"is-relevant-if_removed": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/is-relevant-if_removed",
"@type": "@id"
},
"requires-answer": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/requires-answer",
"@type": "http://www.w3.org/2001/XMLSchema#boolean"
},
"accepts-validation-value": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/accepts-validation-value"
},
"imports": {
"@id": "http://www.w3.org/2002/07/owl#imports",
"@type": "@id"
},
"requires-answer-if": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/requires-answer-if",
"@type": "@id"
},
"has-media-content": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-media-content"
},
"has-composite-pattern": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-composite-pattern"
},
"has-pattern": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-pattern"
},
"has-composite-variables": {
"@id": "http://onto.fel.cvut.cz/ontologies/form/has-composite-variables"
}
},
"@graph": [
{
"@id": "age-1063",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"has-datatype": "xsd:int",
"has-preceding-question": "last-name-1495",
"has-unit": "years",
"label": "Age"
},
{
"@id": "first-name-6663",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"has-datatype": "foaf:givenName",
"requires-answer": true,
"label": "First name"
},
{
"@id": "first-name-9402",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"has-datatype": "foaf:givenName",
"has-pattern": "([A-Za-z]+)",
"has-preceding-question": "title-7183",
"label": "Jméno"
},
{
"@id": "x:form-root",
"@type": "doc:question",
"has_related_question": [
"first-name-6663",
"middle-name-4161",
"last-name-1495",
"age-1063",
"sectionfoo-1592",
"test-section-666"
],
"has-layout-class": "form"
},
{
"@id": "last-name-1495",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"has-datatype": "foaf:familyName",
"has-preceding-question": "middle-name-4161",
"requires-answer": true,
"label": "Příjmení"
},
{
"@id": "last-name-6610",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"has-datatype": "foaf:familyName",
"has-pattern": "([A-Za-z]+)",
"label": "Příjmení"
},
{
"@id": "middle-name-4161",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"has-preceding-question": "first-name-6663",
"label": "Middle name"
},
{
"@id": "sectionfoo-1592",
"@type": "doc:question",
"has_related_question": [
"title-7183",
"first-name-9402",
"last-name-6610"
],
"has-composite-variables": [
"title-7183",
"first-name-9402",
"last-name-6610"
],
"has-layout-class": "name",
"has-datatype": "foaf:name",
"has-composite-pattern": "?1 ?2 ?3",
"--has-pattern": "^(?:([A-Za-z]{1,3}) )?([A-Za-z ]+) ([A-Za-z]+)$",
"has-pattern": "^(?:([A-Za-z]{1,4}\\.) )?(.+) (.+)$",
"requires-answer": true,
"label": "Celé jméno"
},
{
"@id": "test-5278",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"label": "test"
},
{
"@id": "test-section-666",
"@type": "doc:question",
"has_related_question": "test-5278",
"has-layout-class": "section",
"label": "testSection"
},
{
"@id": "title-7183",
"@type": "doc:question",
"has_related_question": [],
"has-layout-class": "text",
"label": "Titul"
}
]
}

0 comments on commit cf0f579

Please sign in to comment.