2 * View logic for OnsiteActivityViews
4 * application logic specific to the OnsiteActivityView listing page
6 * Copyright (C) 2016-2018 Jerry Padgett <sjpadgett@gmail.com>
8 * LICENSE: This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * @author Jerry Padgett <sjpadgett@gmail.com>
23 * @link http://www.open-emr.org
27 onsiteActivityViews: new model.OnsiteActivityViewCollection(),
29 onsiteActivityView: null,
32 isInitializing: false,
33 fetchParams: { filter: '', orderBy: 'patientId', orderDesc: 'DESC', page: 1, status: 'waiting' },
34 fetchInProgress: false,
38 // ensure initialization only occurs once
39 if (actpage.isInitialized || actpage.isInitializing) return;
40 actpage.isInitializing = true;
42 if (!$.isReady && console) console.warn('page was initialized before dom is ready. views may not render properly.');
44 // make the return button clickable
45 $("#returnHome").click(function(e) {
47 window.location.href = './provider';
49 function showPaymentModal(cpid,recid){
50 var title = 'Patient Online Payment';
53 { text: 'Help', close: false, style: 'info btn-sm',id: 'formHelp'},
54 { text: 'Cancel', close: true, style: 'default btn-sm'},
55 //{ text: 'Download', close: false, style: 'success btn-sm',id:'downloadTemplate'},
56 { text: 'Done', style: 'danger btn-sm', close:true}],
58 subtitle: 'Provider Audit.',
61 url: './../portal_payment.php?pid='+cpid+'&user='+cuser+'&recid='+recid
63 return eModal.ajax(params)
64 .then(function () { });
66 function showDocumentModal(cpid,recid){
67 var title = 'Patient Documents';
70 { text: 'Help', close: false, style: 'info btn-sm',id: 'formHelp'},
71 { text: 'Cancel', close: true, style: 'default btn-sm'},
72 //{ text: 'Download', close: false, style: 'success btn-sm',id:'downloadTemplate'},
73 { text: 'Done', style: 'danger btn-sm', close:true}],
75 subtitle: 'Provider Audit.',
78 url: './onsitedocuments?pid='+cpid+'&user='+cuser+'&recid='+recid
80 return eModal.iframe(params)
81 .then(function () { });
83 function showProfileModal(cpid){
84 var title = 'Demographics Legend Red: Chart Values. Blue: Patient Edits.';
87 { text: 'Help', close: false, style: 'info btn-sm',id: 'formHelp'},
88 { text: 'Cancel', close: true, style: 'default btn-sm'},
89 { text: 'Revert Edits', close: false, style: 'success btn-sm',id:'replaceAllButton'},
90 { text: 'Commit to Chart', style: 'danger btn-sm', close: false,id:'savePatientButton'}],
92 subtitle: 'Provider Audit.',
95 url: './patientdata?pid='+cpid+'&user='+cuser
97 return eModal.ajax(params)
98 .then(function () { });
100 // @todo below for emodal refactor
101 /*function showProfileModal(cpid) {
102 var title = 'Demographics Legend Red: Charted Values. Blue: Patient Edits Provider Audit.';
106 { text: 'Help', close: false, style: 'info btn-sm',id: 'formHelp'},
107 { text: 'Cancel', close: true, style: 'default btn-sm'},
108 { text: 'Revert Edits', close: false, style: 'success btn-sm',id:'replaceAllButton'},
109 { text: 'Commit to Chart', style: 'danger btn-sm', close: false,id:'savePatientButton'}],
110 //onClosed: 'reload',
112 url: './patientdata?pid='+cpid+'&user='+cuser
114 dlgopen('','','modal-xl', 500, '', title, params);
117 $(document.body).on('hidden.bs.modal', function () {
118 window.location.href = './onsiteactivityviews';
121 // initialize the collection view
122 this.collectionView = new view.CollectionView({
123 el: $("#onsiteActivityViewCollectionContainer"),
124 templateEl: $("#onsiteActivityViewCollectionTemplate"),
125 collection: actpage.onsiteActivityViews
128 // initialize the search filter
129 $('#filter').change(function(obj) {
130 actpage.fetchParams.filter = $('#filter').val();
131 actpage.fetchParams.page = 1;
132 actpage.fetchOnsiteActivityViews(actpage.fetchParams);
135 // make the rows clickable ('rendered' is a custom event, not a standard backbone event)
136 this.collectionView.on('rendered',function(){
137 // attach click handler to the table rows for selection
138 $('table.collection tbody tr').click(function(e) {
140 var m = actpage.onsiteActivityViews.get(this.id);
141 var cpid = m.get('patientId');
142 var activity = m.get('activity');
143 if(activity == 'document') {
144 let recid = m.get('tableArgs');
145 showDocumentModal(cpid, recid);
147 else if(activity == 'profile') {
148 showProfileModal(cpid);
150 else if(activity == 'payment') {
151 let recid = m.get('id');
152 showPaymentModal(cpid, recid);
156 // make the headers clickable for sorting
157 $('table.collection thead tr th').click(function(e) {
159 var prop = this.id.replace('header_','');
161 // toggle the ascending/descending before we change the sort prop
162 actpage.fetchParams.orderDesc = (prop == actpage.fetchParams.orderBy && !actpage.fetchParams.orderDesc) ? '1' : '';
163 actpage.fetchParams.orderBy = prop;
164 actpage.fetchParams.page = 1;
165 actpage.fetchOnsiteActivityViews(actpage.fetchParams);
168 // attach click handlers to the pagination controls
169 $('.pageButton').click(function(e) {
171 actpage.fetchParams.page = this.id.substr(5);
172 actpage.fetchOnsiteActivityViews(actpage.fetchParams);
175 actpage.isInitialized = true;
176 actpage.isInitializing = false;
179 this.fetchOnsiteActivityViews({ filter: '', orderBy: 'Date', orderDesc: 'DESC', page: 1, status: 'waiting' });
181 // initialize the model view
182 this.modelView = new view.ModelView({
183 el: $("#onsiteActivityViewModelContainer")
186 this.modelView.templateEl = $("#onsiteActivityViewModelTemplate");
188 if (model.longPollDuration > 0) {
189 setInterval(function () {
191 if (!actpage.dialogIsOpen) {
192 actpage.fetchOnsiteActivityViews(actpage.fetchParams,true);
195 }, model.longPollDuration);
200 * Fetch the collection data from the server
201 * @param object params passed through to collection.fetch
202 * @param bool true to hide the loading animation
204 fetchOnsiteActivityViews: function(params, hideLoader) {
205 // persist the params so that paging/sorting/filtering will play together nicely
206 //params.status = 'waiting';
207 actpage.fetchParams = params;
209 if (actpage.fetchInProgress) {
210 if (console) console.log('supressing fetch because it is already in progress');
213 actpage.fetchInProgress = true;
215 if (!hideLoader) app.showProgress('loader');
217 actpage.onsiteActivityViews.fetch({
221 success: function() {
222 if (actpage.onsiteActivityViews.collectionHasChanged) {
223 // TODO: add any logic necessary if the collection has changed
224 // the sync event will trigger the view to re-render
226 app.hideProgress('loader');
227 actpage.fetchInProgress = false;
229 error: function(m, r) {
230 app.appendAlert(app.getErrorMessage(r), 'alert-error',0,'collectionAlert');
231 app.hideProgress('loader');
232 actpage.fetchInProgress = false;
238 * show the dialog for editing a model
241 showDetailDialog: function(m) {
243 // show the modal dialog
244 $('#onsiteActivityViewDetailDialog').modal({ show: true });
246 // if a model was specified then that means a user is editing an existing record
247 // if not, then the user is creating a new record
248 actpage.onsiteActivityView = m ? m : new model.OnsiteActivityViewModel();
250 actpage.modelView.model = actpage.onsiteActivityView;
252 if (actpage.onsiteActivityView.id == null || actpage.onsiteActivityView.id == '') {
253 // this is a new record, there is no need to contact the server
254 actpage.renderModelView(false);
256 app.showProgress('modelLoader');
258 // fetch the model from the server so we are not updating stale data
259 actpage.onsiteActivityView.fetch({
261 success: function() {
262 // data returned from the server. render the model view
263 actpage.renderModelView(true);
266 error: function(m, r) {
267 app.appendAlert(app.getErrorMessage(r), 'alert-error',0,'modelAlert');
268 app.hideProgress('modelLoader');
276 * Render the model template in the popup
277 * @param bool show the delete button
279 renderModelView: function(showDeleteButton) {
280 actpage.modelView.render();
282 app.hideProgress('modelLoader');
283 // initialize any special controls
287 .on('changeDate', function(ev){
288 $('.date-picker').datepicker('hide');
291 // this happens if the datepicker input.value isn't a valid date
292 if (console) console.log('datepicker error: '+error.message);
294 if (showDeleteButton) {
295 // attach click handlers to the delete buttons
296 $('#deleteOnsiteActivityViewButton').click(function(e) {
298 $('#confirmDeleteOnsiteActivityViewContainer').show('fast');
301 $('#cancelDeleteOnsiteActivityViewButton').click(function(e) {
303 $('#confirmDeleteOnsiteActivityViewContainer').hide('fast');
306 $('#confirmDeleteOnsiteActivityViewButton').click(function(e) {
308 actpage.deleteModel();
312 // no point in initializing the click handlers if we don't show the button
313 $('#deleteOnsiteActivityViewButtonContainer').hide();