浏览代码

Canvas based Rx

Vijayakrishnan 4 年之前
父节点
当前提交
797e376feb

+ 2 - 2
resources/views/app/patient/canvas-sections/dx/form.blade.php

@@ -40,12 +40,12 @@ $formID = rand(0, 100000);
         <tr v-for="(item, index) in items">
             <td>
                 <input type="text" :data-index="index"
-                       class="form-control form-control-sm"
+                       class="form-control form-control-sm canvas-dx-title"
                        data-field="icd" v-model="item.icd">
             </td>
             <td>
                 <input type="text" :data-index="index"
-                       class="form-control form-control-sm canvas-dx-title"
+                       class="form-control form-control-sm"
                        data-field="title" v-model="item.title">
             </td>
             <td>

+ 221 - 0
resources/views/app/patient/canvas-sections/rx/form.blade.php

@@ -0,0 +1,221 @@
+<?php
+if(!$contentData) {
+    $contentData = [
+        "items" => [
+            [
+                "title" => "",
+                "strength" => "",
+                "frequency" => "",
+                "detail" => "",
+            ]
+        ]
+    ];
+}
+$formID = rand(0, 100000);
+?>
+<div id="rxSection">
+    <h3 class="stag-popup-title mb-2 border-bottom-0 pb-1">
+        <span>Current Medications</span>
+        <a href="#" onclick="return closeStagPopup()"
+           class="ml-auto text-secondary">
+            <i class="fa fa-times-circle"></i>
+        </a>
+    </h3>
+
+    <input type="hidden" name="data" value="{{json_encode($contentData)}}">
+
+    <table class="table table-sm table-bordered mb-2 table-edit-sheet">
+        <thead>
+        <tr class="bg-light">
+            <th class="px-2 text-secondary border-bottom-0">Medication</th>
+            <th class="px-2 text-secondary border-bottom-0">Strength/From</th>
+            <th class="px-2 text-secondary border-bottom-0">Frequency</th>
+            <th class="px-2 text-secondary border-bottom-0 w-35">Detail</th>
+            <th class="px-2 text-secondary border-bottom-0"></th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr v-for="(item, index) in items">
+            <td>
+                <input type="text" :data-index="index"
+                       class="form-control form-control-sm canvas-rx-title"
+                       data-field="title" v-model="item.title">
+            </td>
+            <td>
+                <input type="text" :data-index="index"
+                       class="form-control form-control-sm"
+                       data-field="strength" v-model="item.strength">
+            </td>
+            <td>
+                <input type="text" :data-index="index"
+                       class="form-control form-control-sm"
+                       data-field="frequency" v-model="item.frequency">
+            </td>
+            <td><textarea type="text" class="form-control form-control-sm"
+                          rx-rte :data-index="index" data-field="detail"
+                          v-model="item.detail"></textarea>
+            </td>
+            <td class="px-2">
+                <a href="#" v-on:click.prevent="removeItem(index)"
+                   class="on-hover-opaque text-danger mt-1 d-inline-block">
+                    <i class="fa fa-trash-alt"></i>
+                </a>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+
+    <div class="form-group my-2">
+    <button type="button" class="btn btn-sm btn-default text-primary border border-primary mr-2"
+            v-on:click.prevent="addItem()"
+    >+ New Entry</button>
+    </div>
+
+</div>
+<script>
+    (function() {
+        function init() {
+            window.clientRXApp = new Vue({
+                el: '#rxSection',
+                data: {
+                    items: <?= json_encode($contentData['items']) ?>
+                },
+                mounted: function() {
+                    this.initRTE();
+                    this.initRxAutoSuggest();
+                },
+                watch: {
+                    $data: {
+                        handler: function(val, oldVal) {
+                            $(this.$el).closest('#rxSection').find('[name="data"]').val(JSON.stringify({
+                                items: this.cleanArray(this.items)
+                            }));
+                        },
+                        deep: true
+                    }
+                },
+                methods: {
+                    addItem: function() {
+                        let self = this;
+                        this.items.push({
+                            title: '',
+                            strength: '',
+                            frequency: '',
+                            detail: '',
+                        });
+                        Vue.nextTick(function() {
+                            self.initRTE();
+                            self.initRxAutoSuggest();
+                            $('.canvas-rx-title').last().focus();
+                        });
+                    },
+                    removeItem: function(_index) {
+                        this.items.splice(_index, 1);
+                    },
+                    cleanArray: function(_source) {
+                        let plItems = [], plObject = {};
+                        for (let x=0; x<_source.length; x++) {
+                            plObject = {};
+                            for (let y in _source[x]) {
+                                if(_source[x].hasOwnProperty(y)) {
+                                    plObject[y] = _source[x][y];
+                                }
+                            }
+                            plItems.push(plObject);
+                        }
+                        return plItems;
+                    },
+                    initRTE: function() {
+                        let self = this;
+                        $('#rxSection textarea[rx-rte]').each(function() {
+
+                            $(this).wrap(
+                                $('<div class="rte-holder"/>')
+                                    .attr('data-shortcuts', '')
+                            );
+
+                            // give a unique id to this editor instance
+                            var editorID = Math.ceil(Math.random() * 99999);
+
+                            $('<div data-editor-id="' + editorID + '" data-field="' + this.name + '"/>')
+                                .html(this.value)
+                                .insertBefore(this);
+
+                            let vueField = $(this).attr('data-field'), vueIndex = +$(this).attr('data-index');
+
+                            $(this).remove();
+
+                            var qe = new Quill('[data-editor-id="' + editorID + '"]', {
+                                theme: 'snow',
+                                modules: {
+                                    keyboard: {
+                                        bindings: {
+                                            handleEnter: {
+                                                key: 13,
+                                                handler: function() {
+                                                    if(!$('.stag-shortcuts:visible').length) return true;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            });
+
+                            var toolbar = $(qe.container).prev('.ql-toolbar');
+
+                            // add button for new shortcut
+                            var newSCButton = $('<button type="button" tabindex="-1" ' +
+                                'class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
+                                'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
+                            toolbar.append(newSCButton);
+
+                            qe.on('text-change', function() {
+                                self.items[vueIndex][vueField] = qe.root.innerHTML;
+                            });
+
+                            $(qe.container)
+                                .find('.ql-editor[contenteditable]')
+                                .attr('data-editor-id', editorID)
+                                .attr('with-shortcuts', 1);
+
+                        });
+                    },
+                    initRxAutoSuggest: function() {
+                        let self = this;
+                        $('#rxSection input[type="text"][data-field="title"]:not([ac-initialized])').each(function() {
+                            let elem = this,
+                                randPart = Math.ceil(Math.random() * 1000000),
+                                dynID = 'rx-' + randPart,
+                                vueIndex = $(this).attr('data-index');
+                            $(elem).attr('id', dynID);
+                            var strengthElem = $(elem).closest('tr').find('[data-field="strength"]')[0],
+                                dynStrengthsID = 'rx-' + randPart + '-strengths';
+                            $(strengthElem).attr('id', dynStrengthsID);
+                            $(strengthElem).attr('rx-id', dynID);
+                            new window.Def.Autocompleter.Prefetch(dynStrengthsID, []);
+                            new window.Def.Autocompleter.Search(dynID,
+                                'https://clinicaltables.nlm.nih.gov/api/rxterms/v3/search?ef=STRENGTHS_AND_FORMS');
+                            window.Def.Autocompleter.Event.observeListSelections(dynID, function() {
+                                var autocomp = elem.autocomp, acData = autocomp.getSelectedItemData();
+                                // console.log('ALIX 1', acData);
+                                self.items[vueIndex].title = acData[0].code;
+                                var strengths = acData[0].data['STRENGTHS_AND_FORMS'];
+                                if (strengths) {
+                                    strengthElem.autocomp.setListAndField(strengths, '');
+                                }
+                            });
+                            window.Def.Autocompleter.Event.observeListSelections(dynStrengthsID, function() {
+                                var autocomp = elem.autocomp, acData = autocomp.getSelectedItemData();
+                                // console.log('ALIX 2', acData);
+                                self.items[vueIndex].strength = $(strengthElem).val();
+                            });
+                            $(elem).attr('ac-initialized', 1);
+                            $(strengthElem).attr('ac-initialized', 1);
+                        });
+                    }
+                }
+            });
+        }
+        addMCInitializer('client-rx-{{ $patient->uid }}', init);
+    })();
+</script>

+ 36 - 0
resources/views/app/patient/canvas-sections/rx/summary.php

@@ -0,0 +1,36 @@
+<?php
+
+$contentData = [
+    "items" => []
+];
+if($patient->canvas_data) {
+    $canvasData = json_decode($patient->canvas_data, true);
+    if(isset($canvasData["rx"])) {
+        $contentData = $canvasData["rx"];
+    }
+}
+
+if(count($contentData['items'])) {
+    for ($i = 0; $i < count($contentData['items']); $i++) {
+        $item = $contentData['items'][$i];
+?>
+        <div class="mb-2">
+            <div class="">
+                <b><?= $item["title"] ?></b>
+                <?= !!$item["strength"] ? '/&nbsp;' . $item["strength"] : '' ?>
+                <?= !!$item["frequency"] ? '/&nbsp;' . $item["frequency"] : '' ?>
+            </div>
+            <?php if(!!$item["detail"]): ?>
+                <div class="text-secondary font-weight-bold">Detail</div>
+                <div class="ml-2"><?= $item["detail"] ?></div>
+            <?php endif; ?>
+        </div>
+<?php
+    }
+}
+else {
+    ?>
+    <div class="text-secondary">Nothing here yet!</div>
+    <?php
+}
+?>

+ 13 - 1
resources/views/app/patient/dashboard.blade.php

@@ -36,6 +36,18 @@
                 {{-- rx --}}
                 @include('app/patient/partials/rx')
 
+                {{-- canvas based rx --}}
+                <div class="pt-2 mt-2 border-top">
+                    <div class="d-flex align-items-center pb-2">
+                        <h6 class="my-0 font-weight-bold text-secondary">Current Medications **</h6>
+                        <span class="mx-2 text-secondary">|</span>
+                        @include('app.patient.canvas-sections.canvas-editor-modal', ['key' => 'rx', 'class' => 'wide'])
+                    </div>
+                    <div class="bg-light border p-2 mb-3">
+                        @include('app.patient.canvas-sections.rx.summary')
+                    </div>
+                </div>
+
                 {{-- devices --}}
                 <?php $availableDevices = 0; ?>
                 @foreach($devices as $device)
@@ -312,7 +324,7 @@
                 {{-- canvas based dx --}}
                 <div class="pt-2 mt-2 border-top">
                     <div class="d-flex align-items-center pb-2">
-                        <h6 class="my-0 font-weight-bold text-secondary">Current Problems / Focus Areas</h6>
+                        <h6 class="my-0 font-weight-bold text-secondary">Current Problems / Focus Areas **</h6>
                         <span class="mx-2 text-secondary">|</span>
                         @include('app.patient.canvas-sections.canvas-editor-modal', ['key' => 'dx', 'class' => 'wide'])
                     </div>