Просмотр исходного кода

Global patients search feature

Vijayakrishnan Krishnan 4 лет назад
Родитель
Сommit
76afae2a89

+ 10 - 0
app/Http/Controllers/HomeController.php

@@ -270,6 +270,16 @@ class HomeController extends Controller
         return view('app/patients', compact('patients', 'filter'));
     }
 
+    public function patientsSuggest(Request $request) {
+        $term = $request->input('term') ? trim($request->input('term')) : '';
+        if(empty($term)) return '';
+        $clients = Client::where(function ($q) use($term) {
+            $q->where('name_first', 'ILIKE', '%' . $term . '%')
+                ->orWhere('name_last', 'ILIKE', '%' . $term . '%');
+        })->get();
+        return view('app/patient-suggest', compact('clients'));
+    }
+
     public function unmappedSMS(Request $request, $filter = '') {
         $proID = $this->performer()->pro->id;
         if($this->performer()->pro->pro_type === 'ADMIN') {

+ 30 - 0
public/css/style.css

@@ -366,3 +366,33 @@ input.search_field, textarea.search_field {
 .navbar-dark .nav-item .nav-link {
     font-size: 13px;
 }
+.suggestions-outer {
+    top: calc(100% + 2px);
+    background: #fff;
+    width: calc(100% - 1rem);
+    border-radius: 3px;
+    border: 1px solid #ccc;
+    z-index: 9999;
+}
+.suggestions-outer {
+    top: calc(100% + 2px);
+    background: #fff;
+    width: calc(100% - 1rem);
+    border-radius: 3px;
+    border: 1px solid #ccc;
+    z-index: 9999;
+}
+.suggestions-outer .suggest-item, .suggestions-outer .no-suggest-items {
+    padding: 0.25rem 0.5rem;
+    text-decoration: none;
+    font-size: 12px;
+}
+.suggestions-outer .no-suggest-items {
+    color: #888;
+}
+.suggestions-outer .suggest-item.active {
+    background: #ccc;
+}
+.suggestions-outer .suggest-item:hover {
+    background: aliceblue;
+}

+ 8 - 0
resources/views/app/patient-suggest.blade.php

@@ -0,0 +1,8 @@
+@if(!count($clients))
+    <span class="d-block no-suggest-items">No matching patients!</span>
+@endif
+<?php $activeSet = false; ?>
+@foreach($clients as $client)
+    <a class="d-block suggest-item {{ $activeSet ? '' : 'active'  }}" href="" data-target-uid="{{$client->uid}}">{{$client->displayName()}}</a>
+    <?php $activeSet = true; ?>
+@endforeach

+ 12 - 12
resources/views/app/patient/dx-and-focus-areas.blade.php

@@ -48,12 +48,12 @@
             @foreach($infoLines as $line)
                 <tr>
                     <td class="px-2">{{$line->content_text}}</td>
-                    <td class="px-2">{{ $line->contentDetail()->{"ICD"} }}</td>
-                    <td class="px-2">{{ $line->contentDetail()->{"Chronic or Acute"} }}</td>
-                    <td class="px-2">{{ $line->contentDetail()->{"Prognosis"} }}</td>
-                    <td class="px-2">{{ $line->contentDetail()->{"Treatment Goal"} }}</td>
-                    <td class="px-2">{{ $line->contentDetail()->{"Treatment Plan"} }}</td>
-                    <td class="px-2">{{$line->createdBySession && $line->createdBySession->pro ? $line->createdBySession->pro->displayName() : '-'}}</td>
+                    <td class="px-2">{{ @$line->contentDetail()->{"ICD"} }}</td>
+                    <td class="px-2">{{ @$line->contentDetail()->{"Chronic or Acute"} }}</td>
+                    <td class="px-2">{{ @$line->contentDetail()->{"Prognosis"} }}</td>
+                    <td class="px-2">{{ @$line->contentDetail()->{"Treatment Goal"} }}</td>
+                    <td class="px-2">{{ @$line->contentDetail()->{"Treatment Plan"} }}</td>
+                    <td class="px-2">{{ $line->createdBySession && $line->createdBySession->pro ? $line->createdBySession->pro->displayName() : '-'}}</td>
                     <td class="px-2">{{ friendly_date_time($line->created_at) }}</td>
                     <td class="px-2 text-center delete-column">
                         <span moe relative class="mr-2">
@@ -65,7 +65,7 @@
                                 <input type="hidden" name="clientUid" value="{{ $patient->uid }}">
                                 <input type="hidden" name="category" value="dx">
                                 <div class="mb-2">
-                                    <input type="text" class="form-control form-control-sm" name="ICD" value="{{ $line->contentDetail()->{"ICD"} }}" placeholder="ICD">
+                                    <input type="text" class="form-control form-control-sm" name="ICD" value="{{ @$line->contentDetail()->{"ICD"} }}" placeholder="ICD">
                                 </div>
                                 <div class="mb-2">
                                     <input type="text" class="form-control form-control-sm" name="contentText" value="{{$line->content_text}}" placeholder="Title">
@@ -73,18 +73,18 @@
                                 <div class="mb-2">
                                     <select name="Chronic or Acute" class="form-control form-control-sm pl-1">
                                         <option value="">Chronic or Acute (select one)</option>
-                                        <option {{ $line->contentDetail()->{"Chronic or Acute"} === 'Chronic' ? 'selected' : '' }} value="Chronic">Chronic</option>
-                                        <option {{ $line->contentDetail()->{"Chronic or Acute"} === 'Acute' ? 'selected' : '' }} value="Acute">Acute</option>
+                                        <option {{ @$line->contentDetail()->{"Chronic or Acute"} === 'Chronic' ? 'selected' : '' }} value="Chronic">Chronic</option>
+                                        <option {{ @$line->contentDetail()->{"Chronic or Acute"} === 'Acute' ? 'selected' : '' }} value="Acute">Acute</option>
                                     </select>
                                 </div>
                                 <div class="mb-2">
-                                    <input type="text" class="form-control form-control-sm" name="Prognosis" value="{{ $line->contentDetail()->{"Prognosis"} }}" placeholder="Prognosis">
+                                    <input type="text" class="form-control form-control-sm" name="Prognosis" value="{{ @$line->contentDetail()->{"Prognosis"} }}" placeholder="Prognosis">
                                 </div>
                                 <div class="mb-2">
-                                    <textarea type="text" class="form-control form-control-sm" name="Treatment Goal" placeholder="Treatment Goal">{{ $line->contentDetail()->{"Treatment Goal"} }}</textarea>
+                                    <textarea type="text" class="form-control form-control-sm" name="Treatment Goal" placeholder="Treatment Goal">{{ @$line->contentDetail()->{"Treatment Goal"} }}</textarea>
                                 </div>
                                 <div class="mb-2">
-                                    <textarea type="text" class="form-control form-control-sm" name="Treatment Plan" placeholder="Treatment Plan">{{ $line->contentDetail()->{"Treatment Plan"} }}</textarea>
+                                    <textarea type="text" class="form-control form-control-sm" name="Treatment Plan" placeholder="Treatment Plan">{{ @$line->contentDetail()->{"Treatment Plan"} }}</textarea>
                                 </div>
                                 <div class="d-flex align-items-center">
                                     <button class="btn btn-sm btn-primary mr-2" type="button" submit>Save</button>

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

@@ -455,7 +455,7 @@
 @section('left-nav-content')
     <div class="left-nav-content" id="note-sections-app">
         <div class="note-widget-title px-2 py-1">Note Sections</div>
-        <input type="text" class="d-block w-100 border-0 outline-0 px-2 py-1"
+        <input type="search" class="d-block w-100 border-0 outline-0 px-2 py-1"
                v-model="q" placeholder="Filter">
         <div class="border-top py-1">
             <div v-for="section in sections"

+ 96 - 0
resources/views/layouts/template.blade.php

@@ -87,6 +87,15 @@
                     </div>
                 </li>
             </ul>
+            <div class="d-inline-flex pr-3 mcp-theme-1 position-relative">
+                <input id="patient-search" type="search"
+                       class="form-control form-control-sm outline-0"
+                       autocomplete="off"
+                       placeholder="Search Patients">
+                <div class="suggestions-outer position-absolute d-none">
+
+                </div>
+            </div>
             <div class="d-flex align-items-center">
                 <p class="text-white my-0 mr-2 small">Hello, <b title="Cell# {{$pro->cell_number}}">{{ $pro->name_first }}!</b></p>
                 <form action="{{ route('logout') }}" method="post" target="_top">
@@ -135,6 +144,93 @@
         </div>
     </form>
 
+<script>
+    $(document).ready(function() {
+        const debounce = (func, wait) => {
+            let timeout;
+            return function executedFunction(...args) {
+                const later = () => {
+                    clearTimeout(timeout);
+                    func(...args);
+                };
+                clearTimeout(timeout);
+                timeout = setTimeout(later, wait);
+            };
+        };
+        var lastTerm = '';
+        var returnedFunction = debounce(function() {
+            var term = $.trim($('#patient-search').val());
+            if(!!term && lastTerm !== term) {
+                $.get('/patients-suggest?term=' + term, function(_data) {
+                    $('.suggestions-outer').html(_data).removeClass('d-none');
+                });
+                lastTerm = term;
+            }
+            else {
+                $('.suggestions-outer').addClass('d-none');
+            }
+        }, 250);
+        $('#patient-search')
+            .on('keydown', function(e) {
+                var term = $.trim($('#patient-search').val());
+                var activeItem = $('.suggestions-outer .suggest-item.active');
+                switch(e.which) {
+                    case 27:
+                        $('.suggestions-outer').addClass('d-none');
+                        return false;
+                    case 38:
+                        if(activeItem.prev().length) {
+                            activeItem.prev()
+                                .addClass('active')
+                                .siblings().removeClass('active');
+                        }
+                        return false;
+                    case 40:
+                        if(activeItem.next().length) {
+                            activeItem.next()
+                                .addClass('active')
+                                .siblings().removeClass('active');
+                        }
+                        return false;
+                    case 13:
+                        if(activeItem.length) {
+                            activeItem.first().click();
+                        }
+                        return false;
+                    default:
+                        if(!!term) {
+                            $('.suggestions-outer')
+                                .html('<span class="d-block no-suggest-items">Searching...</span>')
+                                .removeClass('d-none');
+                            returnedFunction();
+                        }
+                        else {
+                            $('.suggestions-outer').addClass('d-none');
+                        }
+                        break;
+                }
+            })
+            .on('keypress', function(e) {
+                var term = $.trim($('#patient-search').val());
+                if(!!term) {
+                    $('.suggestions-outer')
+                        .html('<span class="d-block no-suggest-items">Searching...</span>')
+                        .removeClass('d-none');
+                    returnedFunction();
+                }
+                else {
+                    $('.suggestions-outer').addClass('d-none');
+                }
+            });
+        $(document).on('click', '.suggest-item[data-target-uid]', function() {
+            $('#patient-search').val('');
+            $('.suggestions-outer').addClass('d-none');
+            fastLoad('/patients/view/' + $(this).attr('data-target-uid'), true, false, false);
+            return false;
+        });
+    });
+</script>
+
 </body>
 
 </html>

+ 3 - 0
routes/web.php

@@ -103,6 +103,9 @@ Route::middleware('pro.auth')->group(function () {
         });
     });
 
+    // Patient suggest
+    Route::get('/patients-suggest', 'HomeController@patientsSuggest');
+
     // AJAX presence poll
     Route::get('/patients/{patient}/presence', 'PatientController@presence');