PVW-2: Creating form modals mechanism
This commit is contained in:
parent
5c5c2afb42
commit
7bbd380983
1
.jscsrc
1
.jscsrc
@ -11,7 +11,6 @@
|
|||||||
"disallowKeywordsOnNewLine": ["else"],
|
"disallowKeywordsOnNewLine": ["else"],
|
||||||
"disallowNewlineBeforeBlockStatements": true,
|
"disallowNewlineBeforeBlockStatements": true,
|
||||||
"requirePaddingNewLinesAfterUseStrict": true,
|
"requirePaddingNewLinesAfterUseStrict": true,
|
||||||
"requirePaddingNewLinesInObjects": true,
|
|
||||||
"requirePaddingNewLinesAfterBlocks": {
|
"requirePaddingNewLinesAfterBlocks": {
|
||||||
"allExcept": ["inCallExpressions", "inArrayExpressions", "inProperties"]
|
"allExcept": ["inCallExpressions", "inArrayExpressions", "inProperties"]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Blaze } from 'meteor/blaze';
|
||||||
import { _ } from 'meteor/underscore';
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
// Create a new custom template for the base component
|
// Create a new custom template for the base component
|
||||||
Template.baseComponent = new Template('baseComponent', () => {});
|
Template.baseComponent = new Template('baseComponent', () => {});
|
||||||
@ -30,9 +32,6 @@ Template.baseComponent.constructView = function(contentFunc, elseFunc) {
|
|||||||
// Extract the render function from the base template
|
// Extract the render function from the base template
|
||||||
template.renderFunction = baseTemplate.renderFunction;
|
template.renderFunction = baseTemplate.renderFunction;
|
||||||
|
|
||||||
// Check for the mixins. If it's not informed set the lowest level mixin
|
|
||||||
const mixins = data.mixins || 'component';
|
|
||||||
|
|
||||||
// Init the data manipulation mixins
|
// Init the data manipulation mixins
|
||||||
OHIF.Mixin.initData(data);
|
OHIF.Mixin.initData(data);
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
target="{{this.target}}"
|
target="{{this.target}}"
|
||||||
{{this.tagAttributes}}
|
{{this.tagAttributes}}
|
||||||
>
|
>
|
||||||
{{#if validationErrors}}
|
{{#if (and validationErrors (not this.hideValidationBox))}}
|
||||||
<div class="validation-error-container alert alert-danger" role="alert">
|
<div class="validation-error-container alert alert-danger" role="alert">
|
||||||
{{#each error in validationErrors}}
|
{{#each error in validationErrors}}
|
||||||
<p><a href="#" class="text-danger" data-target="{{error.key}}">{{error.message}}</a></p>
|
<p><a href="#" class="text-danger" data-target="{{error.key}}">{{error.message}}</a></p>
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
<template name="dialogForm">
|
||||||
|
<div id="{{this.id}}" class="modal fade" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog {{this.dialogClass}}" role="document">
|
||||||
|
{{#form class='modal-content' schema=this.schema hideValidationBox=true api=instance.api}}
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title">{{this.title}}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
{{>UI.contentBlock}}
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
{{#button class='btn-default' action='cancel'}}Cancel{{/button}}
|
||||||
|
{{#button class='btn-primary' action='confirm'}}Confirm{{/button}}
|
||||||
|
</div>
|
||||||
|
{{/form}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
|
||||||
|
Template.dialogForm.onCreated(() => {
|
||||||
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
instance.api = {
|
||||||
|
confirm() {
|
||||||
|
// Check if the form has valid data
|
||||||
|
const form = instance.$('form').data('component');
|
||||||
|
if (!form.validate()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the form value and call the confirm callback or resolve the promise
|
||||||
|
const formData = form.value();
|
||||||
|
if (_.isFunction(instance.data.confirmCallback)) {
|
||||||
|
instance.data.confirmCallback(formData, instance.data.promiseResolve);
|
||||||
|
} else {
|
||||||
|
instance.data.promiseResolve(formData);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
// Call the cancel callback or resolve the promise
|
||||||
|
if (_.isFunction(instance.data.cancelCallback)) {
|
||||||
|
instance.data.cancelCallback(instance.data.promiseReject);
|
||||||
|
} else {
|
||||||
|
instance.data.promiseReject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.dialogForm.onRendered(() => {
|
||||||
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
// Create the bootstrap modal
|
||||||
|
const $modal = instance.$('.modal');
|
||||||
|
$modal.modal();
|
||||||
|
|
||||||
|
// Remove the created modal backdrop from DOM after promise is done
|
||||||
|
const $backdrop = $modal.next('.modal-backdrop');
|
||||||
|
const dismissDialogBackdrop = () => $backdrop.remove();
|
||||||
|
instance.data.promise.then(dismissDialogBackdrop).catch(dismissDialogBackdrop);
|
||||||
|
});
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
<template name="dialogLogin">
|
||||||
|
{{#dialogForm (extend this dialogClass='modal-sm' schema=(choose this.schema instance.schema))}}
|
||||||
|
{{>inputText labelClass='form-group' key='username'}}
|
||||||
|
{{>inputPassword labelClass='form-group' key='password'}}
|
||||||
|
{{/dialogForm}}
|
||||||
|
</template>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||||
|
|
||||||
|
Template.dialogLogin.onCreated(() => {
|
||||||
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
instance.schema = new SimpleSchema({
|
||||||
|
username: {
|
||||||
|
type: String,
|
||||||
|
label: 'Username'
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: String,
|
||||||
|
label: 'Password'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,3 +1,8 @@
|
|||||||
|
import './dialog/form.html';
|
||||||
|
import './dialog/form.js';
|
||||||
|
import './dialog/login.html';
|
||||||
|
import './dialog/login.js';
|
||||||
|
|
||||||
import './form/button.html';
|
import './form/button.html';
|
||||||
import './form/form.html';
|
import './form/form.html';
|
||||||
import './form/group.html';
|
import './form/group.html';
|
||||||
@ -5,6 +10,7 @@ import './form/group.html';
|
|||||||
import './input/checkbox.html';
|
import './input/checkbox.html';
|
||||||
import './input/hidden.html';
|
import './input/hidden.html';
|
||||||
import './input/groupRadio.html';
|
import './input/groupRadio.html';
|
||||||
|
import './input/password.html';
|
||||||
import './input/radio.html';
|
import './input/radio.html';
|
||||||
import './input/range.html';
|
import './input/range.html';
|
||||||
import './input/select.html';
|
import './input/select.html';
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
<template name="inputPassword">
|
||||||
|
{{#inputText (extend this
|
||||||
|
type='password'
|
||||||
|
)}}
|
||||||
|
{{>UI.contentBlock}}
|
||||||
|
{{/inputText}}
|
||||||
|
</template>
|
||||||
@ -158,4 +158,4 @@ class Bounded {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OHIF.Bounded = Bounded;
|
OHIF.ui.Bounded = Bounded;
|
||||||
|
|||||||
38
Packages/ohif-core/client/ui/dialog/form.js
Normal file
38
Packages/ohif-core/client/ui/dialog/form.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Blaze } from 'meteor/blaze';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
|
OHIF.ui.showFormDialog = (templateName, dialogData) => {
|
||||||
|
// Check if the given template exists
|
||||||
|
const template = Template[templateName];
|
||||||
|
if (!template) {
|
||||||
|
throw {
|
||||||
|
name: 'TEMPLATE_NOT_FOUND',
|
||||||
|
message: `Template ${templateName} not found.`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new promise to control the modal and store its resolve and reject callbacks
|
||||||
|
let promiseResolve;
|
||||||
|
let promiseReject;
|
||||||
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
promiseResolve = resolve;
|
||||||
|
promiseReject = reject;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Render the dialog with the given template passing the promise object and callbacks
|
||||||
|
const templateData = _.extend({}, dialogData, {
|
||||||
|
promise,
|
||||||
|
promiseResolve,
|
||||||
|
promiseReject
|
||||||
|
});
|
||||||
|
const view = Blaze.renderWithData(template, templateData, document.body);
|
||||||
|
|
||||||
|
// Destroy the created dialog view when the promise is either resolved or rejected
|
||||||
|
const dismissModal = () => Blaze.remove(view);
|
||||||
|
promise.then(dismissModal).catch(dismissModal);
|
||||||
|
|
||||||
|
// Return the promise to allow callbacks stacking from outside
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
@ -1,6 +1,8 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
// Allow attaching to jQuery selectors
|
// Allow attaching to jQuery selectors
|
||||||
$.fn.draggable = function(options) {
|
$.fn.draggable = function() {
|
||||||
makeDraggable(this, options);
|
OHIF.ui.makeDraggable(this);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -11,7 +13,7 @@ $.fn.draggable = function(options) {
|
|||||||
*
|
*
|
||||||
* @param element
|
* @param element
|
||||||
*/
|
*/
|
||||||
makeDraggable = function(element, options) {
|
OHIF.ui.makeDraggable = function(element) {
|
||||||
var container = $(window);
|
var container = $(window);
|
||||||
var diffX,
|
var diffX,
|
||||||
diffY,
|
diffY,
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
import './bounded/bounded.js';
|
import './bounded/bounded.js';
|
||||||
|
import './dialog/form.js';
|
||||||
import './draggable/draggable.js';
|
import './draggable/draggable.js';
|
||||||
import './resizable/resizable.js';
|
import './resizable/resizable.js';
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
// Allow attaching to jQuery selectors
|
// Allow attaching to jQuery selectors
|
||||||
$.fn.resizable = function(options) {
|
$.fn.resizable = function(options) {
|
||||||
_.each(this, element => {
|
_.each(this, element => {
|
||||||
@ -174,3 +176,5 @@ class Resizable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OHIF.ui.Resizable = Resizable;
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines the base OHIF object
|
* Defines the base OHIF object
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const OHIF = {
|
const OHIF = {
|
||||||
log: {},
|
log: {},
|
||||||
|
ui: {},
|
||||||
viewer: {},
|
viewer: {},
|
||||||
measurements: {}
|
measurements: {}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
// TODO: stop exposing the libraries below and start using imports
|
|
||||||
|
|
||||||
import { cornerstone } from './client/cornerstone.js';
|
|
||||||
import { dicomParser } from './client/dicomParser.js';
|
|
||||||
import { cornerstoneMath } from './client/cornerstoneMath.js';
|
|
||||||
import { cornerstoneTools } from './client/cornerstoneTools.js';
|
|
||||||
import { cornerstoneWADOImageLoader } from './client/cornerstoneWADOImageLoader.js';
|
|
||||||
|
|
||||||
// Expose the cornerstone objects to the client if it is on development mode
|
|
||||||
if (Meteor.isDevelopment) {
|
|
||||||
window.cornerstone = cornerstone;
|
|
||||||
window.cornerstoneMath = cornerstoneMath;
|
|
||||||
window.cornerstoneTools = cornerstoneTools;
|
|
||||||
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
|
|
||||||
window.dicomParser = dicomParser;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
cornerstone,
|
|
||||||
cornerstoneMath,
|
|
||||||
cornerstoneTools,
|
|
||||||
cornerstoneWADOImageLoader,
|
|
||||||
dicomParser
|
|
||||||
};
|
|
||||||
Loading…
Reference in New Issue
Block a user