diff --git a/Packages/design/styles/components/states.styl b/Packages/design/styles/components/states.styl
index e8fa37fa5..1915cdea8 100644
--- a/Packages/design/styles/components/states.styl
+++ b/Packages/design/styles/components/states.styl
@@ -22,3 +22,8 @@
theme('background-color', '$uiStateError')
theme('border-color', '$uiStateErrorBorder')
theme('color', '$uiStateErrorText')
+
+ .select2-selection
+ theme('background-color', '$uiStateError')
+ theme('border-color', '$uiStateErrorBorder')
+ theme('color', '$uiStateErrorText')
diff --git a/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html b/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html
index 6c50cc4de..dcd49b839 100644
--- a/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html
+++ b/Packages/lesiontracker/client/components/additionalFindings/additionalFindings.html
@@ -15,7 +15,7 @@
key='regionsOfMetastaticDisease'
multiple=true
options=(clone
- placeholder='Choose a region...'
+ placeholder='Choose a region'
allowClear=true
)
}}
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html b/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html
index 49db1b73c..8a2dc16be 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html
@@ -11,7 +11,7 @@
{{>inputSelect labelClass='form-group' key='imageRendering' hideSearch=true
- options=(clone placeholder='Select an option...')}}
+ options=(clone placeholder='Select an option')}}
{{>inputText labelClass='form-group' key='qidoRoot'}}
diff --git a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html
index 9101be616..132a6b5da 100644
--- a/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html
+++ b/Packages/lesiontracker/client/components/serverInformation/serverInformationForm/serverInformationForm.html
@@ -8,7 +8,7 @@
{{>inputSelect labelClass='form-group' key='type'
hideSearch=true disabled=(eq this.mode.get 'edit')
- options=(clone placeholder='Choose a server type...')}}
+ options=(clone placeholder='Choose a server type')}}
diff --git a/Packages/ohif-core/client/components/base/mixins/form.js b/Packages/ohif-core/client/components/base/mixins/form.js
index 9a6db08a6..ab9bfbeb0 100644
--- a/Packages/ohif-core/client/components/base/mixins/form.js
+++ b/Packages/ohif-core/client/components/base/mixins/form.js
@@ -27,6 +27,18 @@ OHIF.mixins.form = new OHIF.Mixin({
// Enable reactivity by changing a Tracker.Dependency observer
component.validationObserver.changed();
}, 200);
+
+ // Change the validation function to focus the fields with error
+ const validateSelf = component.validate;
+ component.validate = () => {
+ // Call the original validation function
+ validateSelf();
+
+ // Focus the first error field if some validation failed
+ if (component.schema && component.schema._invalidKeys.length) {
+ instance.$('.state-error :input:first').focus();
+ }
+ };
},
onRendered() {
@@ -35,16 +47,6 @@ OHIF.mixins.form = new OHIF.Mixin({
// Set the component main and style elements
component.$style = component.$element = instance.$('form:first');
-
- instance.autorun(() => {
- // Run this computation everytime the validation is triggered
- component.validationObserver.depend();
-
- // Focus the first error field if some validation failed
- if (component.schema && component.schema._invalidKeys.length) {
- instance.$('.state-error :input:first').focus();
- }
- });
},
events: {
diff --git a/Packages/ohif-core/client/components/base/mixins/formItem.js b/Packages/ohif-core/client/components/base/mixins/formItem.js
index 2842e1dab..88b7c4ae8 100644
--- a/Packages/ohif-core/client/components/base/mixins/formItem.js
+++ b/Packages/ohif-core/client/components/base/mixins/formItem.js
@@ -1,6 +1,7 @@
import { OHIF } from 'meteor/ohif:core';
import { Template } from 'meteor/templating';
import { Tracker } from 'meteor/tracker';
+import { Meteor } from 'meteor/meteor';
import { _ } from 'meteor/underscore';
import { $ } from 'meteor/jquery';
@@ -53,6 +54,19 @@ OHIF.mixins.formItem = new OHIF.Mixin({
component.$wrapper[method]();
};
+ // Check if the focus is inside this element
+ component.hasFocus = () => {
+ // Get the focused element
+ const focused = $(':focus')[0];
+
+ // Check if the focused element is inside the component
+ const contains = $.contains(component.$wrapper[0], focused);
+ const isEqual = component.$wrapper[0] === focused;
+
+ // Return true if he component has the focus
+ return contains || isEqual;
+ };
+
// Add or remove a state from the component
component.state = (state, flag) => {
component.$wrapper.toggleClass(`state-${state}`, !!flag);
@@ -71,19 +85,50 @@ OHIF.mixins.formItem = new OHIF.Mixin({
}
};
- // Toggle the state over the component
+ // Toggle the tooltip over the component
component.toggleTooltip = (isShow, message) => {
- if (isShow) {
- console.warn('>>>>message', message);
+ if (isShow && message) {
+ // Stop here if the tooltip is already created
+ if (component.$wrapper.next('.tooltip').length) {
+ return;
+ }
+
+ // Create the tooltip
component.$wrapper.tooltip({
trigger: 'manual',
title: message
}).tooltip('show');
} else {
+ // Destroy the tooltip
component.$wrapper.tooltip('destroy');
}
};
+ // Toggle a state message as a tooltip over the component
+ component.toggleMessage = isShow => {
+ // Check if the action is to hide
+ if (!isShow) {
+ Meteor.setTimeout(() => {
+ // Check if the component has the focus
+ if (component.hasFocus()) {
+ // Prevent the tooltip from being hidden
+ return;
+ }
+
+ // Hide the tooltip
+ component.toggleTooltip(false);
+ }, 100);
+ return;
+ }
+
+ // Check for error state and message
+ const errorMessage = component.$wrapper.attr('data-error');
+ if (errorMessage) {
+ // Show the tooltip with the error message
+ component.toggleTooltip(true, errorMessage);
+ }
+ },
+
// Search for the parent form component
component.getForm = () => {
let currentComponent = component;
@@ -198,25 +243,31 @@ OHIF.mixins.formItem = new OHIF.Mixin({
focus(event, instance) {
const component = instance.component;
+ // Stop here if it is an group
+ if (component.isGroup || component.isCustomFocus) {
+ return;
+ }
+
// Prevent event bubbling
event.stopPropagation();
- // Check for error state and message
- const errorMessage = component.$wrapper.attr('data-error');
- if (errorMessage) {
- // Show the tooltip with the error message
- component.toggleTooltip(true, errorMessage);
- }
+ // Check for state messages and show it
+ component.toggleMessage(true);
},
blur(event, instance) {
const component = instance.component;
+ // Stop here if it is an group
+ if (component.isGroup || component.isCustomFocus) {
+ return;
+ }
+
// Prevent event bubbling
event.stopPropagation();
- // Hide any tooltips
- component.toggleTooltip(false);
+ // Hide state messages
+ component.toggleMessage(false);
}
}
diff --git a/Packages/ohif-core/client/components/base/mixins/group.js b/Packages/ohif-core/client/components/base/mixins/group.js
index 3c5356831..c2e87a981 100644
--- a/Packages/ohif-core/client/components/base/mixins/group.js
+++ b/Packages/ohif-core/client/components/base/mixins/group.js
@@ -12,6 +12,9 @@ OHIF.mixins.group = new OHIF.Mixin({
const instance = Template.instance();
const component = instance.component;
+ // Set the group identifier flag
+ component.isGroup = true;
+
// Run this computation every time the schema property is changed
instance.autorun(() => {
let schema = instance.data.schema;
diff --git a/Packages/ohif-core/client/components/base/mixins/select2.js b/Packages/ohif-core/client/components/base/mixins/select2.js
index 68453b389..987495dd1 100644
--- a/Packages/ohif-core/client/components/base/mixins/select2.js
+++ b/Packages/ohif-core/client/components/base/mixins/select2.js
@@ -11,6 +11,9 @@ OHIF.mixins.select2 = new OHIF.Mixin({
onCreated() {
const instance = Template.instance();
+ // Set the custom focus flag
+ instance.component.isCustomFocus = true;
+
// Check if this select will include a placeholder
const placeholder = instance.data.options && instance.data.options.placeholder;
if (placeholder) {
@@ -54,6 +57,22 @@ OHIF.mixins.select2 = new OHIF.Mixin({
// Store the select2 instance to allow its further destruction
component.select2Instance = component.$element.data('select2');
+
+ // Get the focusable elements
+ const elements = [];
+ elements.push(component.$element[0]);
+ elements.push(component.$element.nextAll('.select2:first').find('.select2-selection')[0]);
+
+ // Attach focus and blur handlers to focusable elements
+ $(elements).on('focus', event => {
+ event.stopPropagation();
+ // Show the state message on elements focus
+ component.toggleMessage(true);
+ }).on('blur', event => {
+ event.stopPropagation();
+ // Hide the state message on elements blur
+ component.toggleMessage(false);
+ });
},
onDestroyed() {
@@ -62,16 +81,6 @@ OHIF.mixins.select2 = new OHIF.Mixin({
// Destroy the select2 instance to remove unwanted DOM elements
component.select2Instance.destroy();
- },
-
- events: {
- 'focusin .select2-hidden-accessible'(event, instance) {
- event.preventDefault();
-
- // Redirect the focus to select2 focus control in case of hidden
- // accessible being focused (e.g. clicking on outer label)
- $(event.currentTarget).nextAll('.select2:first').find('.select2-selection').focus();
- }
}
}
});
diff --git a/Packages/worklist/both/schema.js b/Packages/worklist/both/schema.js
index 1ce640523..4eec4cc74 100644
--- a/Packages/worklist/both/schema.js
+++ b/Packages/worklist/both/schema.js
@@ -59,8 +59,8 @@ export const DICOMWebServer = new SimpleSchema({
imageRendering: {
type: String,
label: 'Image rendering',
- allowedValues: ['wadouri', 'orthanc'],
- valuesLabels: ['WADO URI', 'ORTHANC']
+ allowedValues: ['', 'wadouri', 'orthanc'],
+ valuesLabels: ['', 'WADO URI', 'ORTHANC']
},
qidoRoot: {
type: String,