Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development mdform required and completeness issues #226

Merged
85 changes: 58 additions & 27 deletions deposit/metadata-form/src/AffiliationIdentifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class AffiliationIdentifier extends React.Component {

// Placeholder for the vocabulary options to be collected externally
this.options = [{ value: 'https://ror.org/04pp8hn57', label: 'Utrecht University' }]
this.is_new_affilation = false

const url = props.uiSchema['ui:data']

Expand All @@ -35,8 +36,11 @@ class AffiliationIdentifier extends React.Component {

handleChange = (event) => {
this.setFormData('Affiliation_Name', event.label)
this.is_new_affilation = false
if (event.__isNew__ === undefined || event.__isNew__ === false) {
this.setFormData('Affiliation_Identifier', event.value)
} else if (event.__isNew__) {
this.is_new_affilation = true
}
}

Expand Down Expand Up @@ -95,19 +99,26 @@ class AffiliationIdentifier extends React.Component {
const namePresent = !(typeof Affiliation_Name === 'undefined' || Affiliation_Name.length === 0)
const idfPresent = !(typeof Affiliation_Identifier === 'undefined' || Affiliation_Identifier.length === 0)

// Specific class handling for both elements Name/Identifier
if (namePresent) {
// Identifier is present but Name is not.
if (idfPresent && !namePresent) {
reqName = '*'
classesName += ' is-invalid'
}

// Both Name and Identifier are required.
if (bothRequired) {
reqName = '*'
reqIdf = '*'

if (!namePresent) {
classesName += ' is-invalid'
}
if (!idfPresent) {
classesIdf += ' is-invalid'
}
} else if (idfPresent) { // als naam wel is ingeuvuld
classesName += ' is-invalid'
} else if (bothRequired) {
classesName += ' is-invalid'
classesIdf += ' is-invalid'
}

// set the customStyle for the select if invalid
// Set the customStyle for the select if invalid.
if (classesName.search('is-invalid') > -1) {
customStyles = {
control: styles => ({
Expand All @@ -121,25 +132,28 @@ class AffiliationIdentifier extends React.Component {
}
}

// Handling of '*' in the label of both fields
if (bothRequired) {
reqName = '*'
reqIdf = '*'
} else {
if (!(typeof Affiliation_Name === 'undefined' || Affiliation_Name.length === 0)) {
reqIdf = '*'
}
if (!(typeof Affiliation_Identifier === 'undefined' || Affiliation_Identifier.length === 0)) {
reqName = '*'
// Handling of new Affiliation: this overrules all for the identifier field
// - Identifier is no longer required
// -a is-invalid indication must be removed.
if (this.is_new_affilation) {
reqIdf = ''
classesIdf = 'form-control'
}

let labelClasses = 'form-label'
if (reqName === '*') {
labelClasses += ' select-required'
if (namePresent) {
// select-filled only has meaning when in combination with select-required (for totalisation of completeness purposes)
labelClasses += ' select-filled'
}
}

return (
<div className='d-flex'>
<div className='col compound-field'>
<label className='form-label select-required select-filled'>{titleAffiliationName}{reqName}</label>
<label className={labelClasses}>{titleAffiliationName}{reqName}</label>
<CreatableSelect
className='select-box is-invalid'
options={this.options}
required={reqName === '*'}
isDisabled={this.props.readonly}
Expand All @@ -157,13 +171,30 @@ class AffiliationIdentifier extends React.Component {
<div className='col compound-field'>
<div className='mb-0 form-group'>
<label className='form-label'>{titleAffiliationIdentifier}{reqIdf}</label>
<input
type='text'
className={classesIdf} // 'form-control is-invalid'
readOnly={this.props.readonly}
onChange={this.handleChangeIdentifier}
value={Affiliation_Identifier}
/>

{reqIdf === '*' && (
<input
type='text'
required
className={classesIdf} // 'form-control is-invalid'
readOnly={this.props.readonly}
onChange={this.handleChangeIdentifier}
value={Affiliation_Identifier}
/>)}

{reqIdf === '' && (
<input
type='text'
className={classesIdf} // 'form-control is-invalid'
readOnly={this.props.readonly}
onChange={this.handleChangeIdentifier}
value={Affiliation_Identifier}
/>)}

<a className='btn btn-sm btn-primary float-end' href='https://ror.org/search' target='_blank' rel='noreferrer'>
<i className='fa-solid fa-magnifying-glass' aria-hidden='true' /> Lookup ROR
</a>

{helpAffiliationIdentifier && (
<small className='text-muted form-text'>
<p className='help-block'>{helpAffiliationIdentifier}</p>
Expand Down
51 changes: 37 additions & 14 deletions deposit/metadata-form/src/PersonIdentifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ class PersonIdentifier extends React.Component {

// Check whether combination of 2 fields is a required 'field'
let bothRequired = false
// Make sure required is actually present.
if (this.props.registry.rootSchema.properties[parentContext].items.required) {
try {
bothRequired = this.props.registry.rootSchema.properties[parentContext].items.required.includes('Person_Identifier')
} catch (err) {
bothRequired = false
}

// If either one holds a value, the other becomes a required element - hoe dit te testen!!
Expand Down Expand Up @@ -164,10 +165,19 @@ class PersonIdentifier extends React.Component {
searchLink = <a class='btn btn-sm btn-primary float-end' href={searchUrl} target='_blank' rel='noreferrer'><i class='fa-solid fa-magnifying-glass' aria-hidden='true' /> Lookup {Name_Identifier_Scheme}</a>
}

let labelClasses = 'form-label'
if (requiredScheme === '*') {
labelClasses += ' select-required'
if ((typeof Name_Identifier_Scheme !== 'undefined') && Name_Identifier_Scheme.length > 0) {
// select-filled only has meaning when in combination with select-required (for totalisation of completeness purposes)
labelClasses += ' select-filled'
}
}

return (
<div className='d-flex'>
<div className='col compound-field'>
<label className='form-label'>{titleScheme}{requiredScheme}</label>
<label className={labelClasses}>{titleScheme}{requiredScheme}</label>
<Select
className='select-box'
options={options}
Expand All @@ -182,20 +192,33 @@ class PersonIdentifier extends React.Component {
</small>
)}
</div>

<div className='col compound-field'>
<div className='mb-0 form-group'>
<label className='form-label'>{titleIdentifier}{requiredIdentifier}</label>
<InputMask
className={classesIdentifierField}
readOnly={this.props.readonly}
isDisabled={this.props.readonly}
value={Name_Identifier}
placeholder={placeholder}
onChange={this.handleIdentifierChange}
mask={mask}
formatChars={formatChars}
/>
{requiredIdentifier === '*' && (
<InputMask
className={classesIdentifierField}
required
readOnly={this.props.readonly}
isDisabled={this.props.readonly}
value={Name_Identifier}
placeholder={placeholder}
onChange={this.handleIdentifierChange}
mask={mask}
formatChars={formatChars}
/>)}

{requiredIdentifier === '' && (
<InputMask
className={classesIdentifierField}
readOnly={this.props.readonly}
isDisabled={this.props.readonly}
value={Name_Identifier}
placeholder={placeholder}
onChange={this.handleIdentifierChange}
mask={mask}
formatChars={formatChars}
/>)}

{searchLink}

Expand Down
14 changes: 9 additions & 5 deletions deposit/metadata-form/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ const enumWidget = (props) => {
let i = enumArray.indexOf(props['value']);
let placeholder = enumNames[i] == null ? ' ' : enumNames[i];

let title = props.label || props.uiSchema["ui:title"]
let label = <label className="form-label">{title}</label>
let customStyles = {
control: styles => ({
...styles,
Expand Down Expand Up @@ -82,8 +80,13 @@ const enumWidget = (props) => {
required = formProperties.data.schema.required.includes(name_hierarchy[0]);
}

// will hold classes (select-required, select-filled) as indications for totalization purposes.
// For that purpose element <selectTotals> will be added.
let selectCompletenessClasses = '';

if((props.rawErrors !== undefined && props.rawErrors.indexOf(error) >= 0) || (required && props.value == null)) {
label = <label className="text-danger form-label select-required">{title}*</label>
// Indicate that this element is required and should be counted as total
selectCompletenessClasses = 'select-required';
customStyles = {
control: styles => ({
...styles,
Expand All @@ -95,12 +98,13 @@ const enumWidget = (props) => {
})
};
} else if (required) {
label = <label className="form-label select-required select-filled">{title}*</label>
// Indicate that this element is required and holds a value
selectCompletenessClasses = 'select-required select-filled';
}

return (
<div>

<selectTotals class={selectCompletenessClasses}></selectTotals>
<Select className={'select-box'}
placeholder={placeholder}
required={required}
Expand Down
2 changes: 1 addition & 1 deletion deposit/static/deposit/js/metadata-form.js

Large diffs are not rendered by default.

85 changes: 58 additions & 27 deletions research/metadata-form/src/AffiliationIdentifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class AffiliationIdentifier extends React.Component {

// Placeholder for the vocabulary options to be collected externally
this.options = [{ value: 'https://ror.org/04pp8hn57', label: 'Utrecht University' }]
this.is_new_affilation = false

const url = props.uiSchema['ui:data']

Expand All @@ -35,8 +36,11 @@ class AffiliationIdentifier extends React.Component {

handleChange = (event) => {
this.setFormData('Affiliation_Name', event.label)
this.is_new_affilation = false
if (event.__isNew__ === undefined || event.__isNew__ === false) {
this.setFormData('Affiliation_Identifier', event.value)
} else if (event.__isNew__) {
this.is_new_affilation = true
}
}

Expand Down Expand Up @@ -95,19 +99,26 @@ class AffiliationIdentifier extends React.Component {
const namePresent = !(typeof Affiliation_Name === 'undefined' || Affiliation_Name.length === 0)
const idfPresent = !(typeof Affiliation_Identifier === 'undefined' || Affiliation_Identifier.length === 0)

// Specific class handling for both elements Name/Identifier
if (namePresent) {
// Identifier is present but Name is not.
if (idfPresent && !namePresent) {
reqName = '*'
classesName += ' is-invalid'
}

// Both Name and Identifier are required.
if (bothRequired) {
reqName = '*'
reqIdf = '*'

if (!namePresent) {
classesName += ' is-invalid'
}
if (!idfPresent) {
classesIdf += ' is-invalid'
}
} else if (idfPresent) { // als naam wel is ingeuvuld
classesName += ' is-invalid'
} else if (bothRequired) {
classesName += ' is-invalid'
classesIdf += ' is-invalid'
}

// set the customStyle for the select if invalid
// Set the customStyle for the select if invalid.
if (classesName.search('is-invalid') > -1) {
customStyles = {
control: styles => ({
Expand All @@ -121,25 +132,28 @@ class AffiliationIdentifier extends React.Component {
}
}

// Handling of '*' in the label of both fields
if (bothRequired) {
reqName = '*'
reqIdf = '*'
} else {
if (!(typeof Affiliation_Name === 'undefined' || Affiliation_Name.length === 0)) {
reqIdf = '*'
}
if (!(typeof Affiliation_Identifier === 'undefined' || Affiliation_Identifier.length === 0)) {
reqName = '*'
// Handling of new Affiliation: this overrules all for the identifier field
// - Identifier is no longer required
// -a is-invalid indication must be removed.
if (this.is_new_affilation) {
reqIdf = ''
classesIdf = 'form-control'
}

let labelClasses = 'form-label'
if (reqName === '*') {
labelClasses += ' select-required'
if (namePresent) {
// select-filled only has meaning when in combination with select-required (for totalisation of completeness purposes)
labelClasses += ' select-filled'
}
}

return (
<div className='d-flex'>
<div className='col compound-field'>
<label className='form-label select-required select-filled'>{titleAffiliationName}{reqName}</label>
<label className={labelClasses}>{titleAffiliationName}{reqName}</label>
<CreatableSelect
className='select-box is-invalid'
options={this.options}
required={reqName === '*'}
isDisabled={this.props.readonly}
Expand All @@ -157,13 +171,30 @@ class AffiliationIdentifier extends React.Component {
<div className='col compound-field'>
<div className='mb-0 form-group'>
<label className='form-label'>{titleAffiliationIdentifier}{reqIdf}</label>
<input
type='text'
className={classesIdf} // 'form-control is-invalid'
readOnly={this.props.readonly}
onChange={this.handleChangeIdentifier}
value={Affiliation_Identifier}
/>

{reqIdf === '*' && (
<input
type='text'
required
className={classesIdf} // 'form-control is-invalid'
readOnly={this.props.readonly}
onChange={this.handleChangeIdentifier}
value={Affiliation_Identifier}
/>)}

{reqIdf === '' && (
<input
type='text'
className={classesIdf} // 'form-control is-invalid'
readOnly={this.props.readonly}
onChange={this.handleChangeIdentifier}
value={Affiliation_Identifier}
/>)}

<a className='btn btn-sm btn-primary float-end' href='https://ror.org/search' target='_blank' rel='noreferrer'>
<i className='fa-solid fa-magnifying-glass' aria-hidden='true' /> Lookup ROR
</a>

{helpAffiliationIdentifier && (
<small className='text-muted form-text'>
<p className='help-block'>{helpAffiliationIdentifier}</p>
Expand Down
Loading
Loading