diff --git a/README.md b/README.md index 73e5d18..3a52ad1 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ class SimplePathway(pathways.Pathway): You could access this pathway from e.g. `http:\\localhost:8000\pathway\#\simples\`. +### Steps with multiple isntances of records Sometimes we may want to add multiple instances of a subrecord at the same time, for example when we're recording multiple allergies. To add a multiple step simply use a MultiSaveStep, for example: @@ -74,6 +75,48 @@ class SimplePathway(pathways.Pathway): ) ``` +### Complex steps - more than one subrecord type + +If we want to save multiple types of subrecords at the same step, we can do that by simply including the +relevant form templates in a custom step template. + +```python +from pathway import pathways +from myapp import models + +class SimplePathway(pathways.Pathway): + display_name = 'A simple pathway' + slug = 'simples' + steps = ( + pathways.Step( + title='Demographics and Diagnosis', + icon='fa fa-clock', + template='pathways/demographics_and_diagnosis_step.html' + ), + ) +``` + +The title and icon are rendered in the header for this step in your pathway, which exist outside the scope of the step template itself. Then all we would need is the template itself: + +```html + +{% include models.Demographics.get_form_template %} +{% include models.Diagnosis.get_form_template %} +``` + +#### Complex steps with multiple instances per subrecord + +If we need to also save multiple types of the same subrecord e.g. `Treatment` in this step, +we simply use the `multisave` template tag. + +```html +{% load pathways %} + +{% include models.Demographics.get_form_template %} +{% include models.Diagnosis.get_form_template %} +{% multisave models.Treatment %} +``` + ### Success redirects Often, after successfully saving a pathway, we want to redirect the user to a different @@ -160,13 +203,3 @@ Redirect to the patient detail page for this patient. ## pathways.RedirectsToEpisodeMixin Redirect to the patient detail page, viewing the last episode for this patient. - -## Template tags - -Pathways allow you to do things that aren't usually trivial including saving multiple models -at the same time, to make this easy we have a template tag that you can add, this will add -forms for each of your existing models and allow the user to add new models dynamically - -```html -{% multisave models.Treatment %} -``` diff --git a/pathway/__init__.py b/pathway/__init__.py index e6739c3..bbc62f2 100644 --- a/pathway/__init__.py +++ b/pathway/__init__.py @@ -31,7 +31,6 @@ class PathwayPlugin(plugins.OpalPlugin): 'js/pathway/controllers/find_patient.js', 'js/pathway/controllers/line_controller.js', 'js/pathway/controllers/multi_stage_default.js', - 'js/pathway/controllers/multi_save.js', 'js/pathway/services/multi_stage_form.js', 'js/pathway/services/pathway_loader.js', 'js/pathway/directives.js', diff --git a/pathway/pathways.py b/pathway/pathways.py index 39964e4..be06786 100644 --- a/pathway/pathways.py +++ b/pathway/pathways.py @@ -1,17 +1,12 @@ import inspect -from copy import copy from functools import wraps from django.core.urlresolvers import reverse -from django.conf import settings from django.db import models, transaction from django.utils.text import slugify -from django.http import Http404 from opal.core import discoverable -from opal.models import Patient, Episode, EpisodeSubrecord -from opal.utils import stringport -from opal.utils import _itersubclasses +from opal.models import Patient, Episode def extract_pathway_field(some_fun): @@ -73,21 +68,8 @@ def pre_save(self, data, user): class MultSaveStep(Step): - def to_dict(self): - result = super(MultSaveStep, self).to_dict() - - if "template_url" not in self.other_args: - result["template_url"] = "/templates/pathway/multi_save.html" - - if "controller_class" not in self.other_args: - result["controller_class"] = "MultiSaveCtrl" - - result["model_form_url"] = self.model.get_form_url() - - result["record_url"] = reverse( - "record_view", kwargs=dict(model=self.model.get_api_name()) - ), - return result + def template_url(self): + return "/templates/pathway/multi_save.html" class RedirectsToPatientMixin(object): diff --git a/pathway/static/js/pathway/controllers/multi_save.js b/pathway/static/js/pathway/controllers/multi_save.js deleted file mode 100644 index 2edef3f..0000000 --- a/pathway/static/js/pathway/controllers/multi_save.js +++ /dev/null @@ -1,40 +0,0 @@ -angular.module('opal.controllers').controller('MultiSaveCtrl', - function(Options, $controller, step, scope, episode) { - "use strict"; - var key = step.api_name; - - scope.step = step; - - scope.addAnother = function(){ - scope.allEditing.push({key: undefined}); - }; - - scope.instanceName = step.title; - - scope.init = function(){ - scope.allEditing = _.map(episode[key], function(row){ - var editing = {} - editing[key] = row; - return editing; - }); - - // add a blank row to the bottom - scope.addAnother(); - }; - - scope.remove = function($index){ - scope.allEditing.splice($index, 1); - }; - - scope.preSave = function(editing){ - var all_models = angular.copy(scope.allEditing); - - var result = _.reduce(all_models, function(memo, row){ - return memo.concat(_.values(row)); - }, []) - - editing[step.api_name] = result; - }; - - scope.init(); -}); diff --git a/pathway/static/js/pathway/directives.js b/pathway/static/js/pathway/directives.js index 2f7dbfa..5e13afa 100644 --- a/pathway/static/js/pathway/directives.js +++ b/pathway/static/js/pathway/directives.js @@ -1,15 +1,19 @@ -var directives = angular.module('opal.directives', []); - directives.directive("saveMultiple", function($parse, $rootScope, Referencedata){ return { scope: { parentModel: "=saveMultiple", + form_url: "=?saveMultipleFormUrl", + display_name: "=?saveMultipleLabel", + model_name: "=?saveMultipleModelName" }, templateUrl: "/templates/pathway/save_multiple.html", link: function(scope, element, attrs){ var editingString = attrs.saveMultiple; - var model = editingString.substr(editingString.indexOf(".")+1); - var getModel = $parse(model); + + if(!scope.model_name){ + scope.model_name = editingString.substr(editingString.indexOf(".")+1); + } + var getModel = $parse(scope.model_name); // hopefully we can do this nicer in future Referencedata.then(function(referencedata){ @@ -22,19 +26,16 @@ directives.directive("saveMultiple", function($parse, $rootScope, Referencedata) if(!fields){ throw "fields not loaded"; } - return fields[model][name]; + return fields[scope.model_name][name]; } var requiredAttrs = { - "form_url": "saveMultipleformUrl", + "form_url": "saveMultipleFormUrl", "display_name": "saveMultipleLabel" }; _.each(requiredAttrs, function(jsName, schemaName){ - if(attrs[jsName]){ - scope[schemaName] = attrs[jsName]; - } - else{ + if(!scope[schemaName]){ scope[schemaName] = getSchemaField(schemaName); } }); @@ -50,7 +51,11 @@ directives.directive("saveMultiple", function($parse, $rootScope, Referencedata) // shallow copy not deep copy as angular copy can't // deal with moments - scope.model = {'allModels': _.clone(scope.parentModel)}; + scope.model = {'allModels': _.map(scope.parentModel, function(row){ + var result = {}; + result[scope.model_name] = row; + return result; + })}; scope.remove = function($index){ scope.model.allModels.splice($index, 1); diff --git a/pathway/static/js/pathway/services/multi_stage_form.js b/pathway/static/js/pathway/services/multi_stage_form.js index 799ce5f..f57b395 100644 --- a/pathway/static/js/pathway/services/multi_stage_form.js +++ b/pathway/static/js/pathway/services/multi_stage_form.js @@ -117,6 +117,8 @@ angular.module('opal.services').provider('multistage', function(){ } _.each(scope.steps, function(step){ var stepScope = scope.$new(); + // always put the step on the scope + stepScope.step = step; if(step.controller_class){ step.controller = $controller(step.controller_class, { step: step, diff --git a/pathway/templates/_helpers/multisave.html b/pathway/templates/_helpers/multisave.html index 1fca506..3408f63 100644 --- a/pathway/templates/_helpers/multisave.html +++ b/pathway/templates/_helpers/multisave.html @@ -1 +1 @@ -
+
diff --git a/pathway/templates/pathway/multi_save.html b/pathway/templates/pathway/multi_save.html index 83b1f66..94e3f6d 100644 --- a/pathway/templates/pathway/multi_save.html +++ b/pathway/templates/pathway/multi_save.html @@ -1,11 +1 @@ -
-
-

[[ instanceName ]] [[ $index + 1 ]]

-
- -
-
-
- Add Another -
-
+
diff --git a/pathway/tests/test_template_tags.py b/pathway/tests/test_template_tags.py index e52a571..67eeef0 100644 --- a/pathway/tests/test_template_tags.py +++ b/pathway/tests/test_template_tags.py @@ -13,8 +13,8 @@ def test_with_model(self, get_form_url): rendered = template.render(Context(models)) self.assertIn('save-multiple="editing.colour"', rendered) self.assertIn( - 'save-multiple-form-url="/templates/forms/colour.html"', rendered + 'save-multiple-form-url="\'/templates/forms/colour.html\'"', rendered ) self.assertIn( - 'save-multiple-label="Colour"', rendered + 'save-multiple-label="\'Colour\'"', rendered )