Bladeren bron

新增 進階搜尋初版

oransheep 3 jaren geleden
bovenliggende
commit
c88524bde3

+ 169 - 0
assets/vendor/jquery-hoverIntent/jquery.hoverIntent.js

@@ -0,0 +1,169 @@
+/*!
+ * hoverIntent v1.10.2 // 2020.04.28 // jQuery v1.7.0+
+ * http://briancherne.github.io/jquery-hoverIntent/
+ *
+ * You may use hoverIntent under the terms of the MIT license. Basically that
+ * means you are free to use hoverIntent as long as this header is left intact.
+ * Copyright 2007-2019 Brian Cherne
+ */
+
+/**
+ * hoverIntent is similar to jQuery's built-in "hover" method except that
+ * instead of firing the handlerIn function immediately, hoverIntent checks
+ * to see if the user's mouse has slowed down (beneath the sensitivity
+ * threshold) before firing the event. The handlerOut function is only
+ * called after a matching handlerIn.
+ *
+ * // basic usage ... just like .hover()
+ * .hoverIntent( handlerIn, handlerOut )
+ * .hoverIntent( handlerInOut )
+ *
+ * // basic usage ... with event delegation!
+ * .hoverIntent( handlerIn, handlerOut, selector )
+ * .hoverIntent( handlerInOut, selector )
+ *
+ * // using a basic configuration object
+ * .hoverIntent( config )
+ *
+ * @param  handlerIn   function OR configuration object
+ * @param  handlerOut  function OR selector for delegation OR undefined
+ * @param  selector    selector OR undefined
+ * @author Brian Cherne <brian(at)cherne(dot)net>
+ */
+
+;(function(factory) {
+    'use strict';
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery'], factory);
+    } else if (typeof module === 'object' && module.exports) {
+        module.exports = factory(require('jquery'));
+    } else if (jQuery && !jQuery.fn.hoverIntent) {
+        factory(jQuery);
+    }
+})(function($) {
+    'use strict';
+
+    // default configuration values
+    var _cfg = {
+        interval: 100,
+        sensitivity: 6,
+        timeout: 0
+    };
+
+    // counter used to generate an ID for each instance
+    var INSTANCE_COUNT = 0;
+
+    // current X and Y position of mouse, updated during mousemove tracking (shared across instances)
+    var cX, cY;
+
+    // saves the current pointer position coordinates based on the given mousemove event
+    var track = function(ev) {
+        cX = ev.pageX;
+        cY = ev.pageY;
+    };
+
+    // compares current and previous mouse positions
+    var compare = function(ev,$el,s,cfg) {
+        // compare mouse positions to see if pointer has slowed enough to trigger `over` function
+        if ( Math.sqrt( (s.pX-cX)*(s.pX-cX) + (s.pY-cY)*(s.pY-cY) ) < cfg.sensitivity ) {
+            $el.off(s.event,track);
+            delete s.timeoutId;
+            // set hoverIntent state as active for this element (permits `out` handler to trigger)
+            s.isActive = true;
+            // overwrite old mouseenter event coordinates with most recent pointer position
+            ev.pageX = cX; ev.pageY = cY;
+            // clear coordinate data from state object
+            delete s.pX; delete s.pY;
+            return cfg.over.apply($el[0],[ev]);
+        } else {
+            // set previous coordinates for next comparison
+            s.pX = cX; s.pY = cY;
+            // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
+            s.timeoutId = setTimeout( function(){compare(ev, $el, s, cfg);} , cfg.interval );
+        }
+    };
+
+    // triggers given `out` function at configured `timeout` after a mouseleave and clears state
+    var delay = function(ev,$el,s,out) {
+        var data = $el.data('hoverIntent');
+        if (data) {
+            delete data[s.id];
+        }
+        return out.apply($el[0],[ev]);
+    };
+
+    // checks if `value` is a function
+    var isFunction = function(value) {
+        return typeof value === 'function';
+    };
+
+    $.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
+        // instance ID, used as a key to store and retrieve state information on an element
+        var instanceId = INSTANCE_COUNT++;
+
+        // extend the default configuration and parse parameters
+        var cfg = $.extend({}, _cfg);
+        if ( $.isPlainObject(handlerIn) ) {
+            cfg = $.extend(cfg, handlerIn);
+            if ( !isFunction(cfg.out) ) {
+                cfg.out = cfg.over;
+            }
+        } else if ( isFunction(handlerOut) ) {
+            cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
+        } else {
+            cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
+        }
+
+        // A private function for handling mouse 'hovering'
+        var handleHover = function(e) {
+            // cloned event to pass to handlers (copy required for event object to be passed in IE)
+            var ev = $.extend({},e);
+
+            // the current target of the mouse event, wrapped in a jQuery object
+            var $el = $(this);
+
+            // read hoverIntent data from element (or initialize if not present)
+            var hoverIntentData = $el.data('hoverIntent');
+            if (!hoverIntentData) { $el.data('hoverIntent', (hoverIntentData = {})); }
+
+            // read per-instance state from element (or initialize if not present)
+            var state = hoverIntentData[instanceId];
+            if (!state) { hoverIntentData[instanceId] = state = { id: instanceId }; }
+
+            // state properties:
+            // id = instance ID, used to clean up data
+            // timeoutId = timeout ID, reused for tracking mouse position and delaying "out" handler
+            // isActive = plugin state, true after `over` is called just until `out` is called
+            // pX, pY = previously-measured pointer coordinates, updated at each polling interval
+            // event = string representing the namespaced event used for mouse tracking
+
+            // clear any existing timeout
+            if (state.timeoutId) { state.timeoutId = clearTimeout(state.timeoutId); }
+
+            // namespaced event used to register and unregister mousemove tracking
+            var mousemove = state.event = 'mousemove.hoverIntent.hoverIntent'+instanceId;
+
+            // handle the event, based on its type
+            if (e.type === 'mouseenter') {
+                // do nothing if already active
+                if (state.isActive) { return; }
+                // set "previous" X and Y position based on initial entry point
+                state.pX = ev.pageX; state.pY = ev.pageY;
+                // update "current" X and Y position based on mousemove
+                $el.off(mousemove,track).on(mousemove,track);
+                // start polling interval (self-calling timeout) to compare mouse coordinates over time
+                state.timeoutId = setTimeout( function(){compare(ev,$el,state,cfg);} , cfg.interval );
+            } else { // "mouseleave"
+                // do nothing if not already active
+                if (!state.isActive) { return; }
+                // unbind expensive mousemove event
+                $el.off(mousemove,track);
+                // if hoverIntent state is true, then call the mouseOut function after the specified delay
+                state.timeoutId = setTimeout( function(){delay(ev,$el,state,cfg.out);} , cfg.timeout );
+            }
+        };
+
+        // listen for mouseenter and mouseleave
+        return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
+    };
+});

File diff suppressed because it is too large
+ 8 - 0
assets/vendor/jquery-hoverIntent/jquery.hoverIntent.min.js


+ 150 - 24
index.php

@@ -64,8 +64,6 @@ if (!isset($_SESSION['loggedin'])) {
 	<script src="https://unpkg.com/vue@next"></script>
 	<script src="./script/js/vue-search-block.js"></script>
 
-	<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
-
 	<style>
 		.row {
 			margin-top: -15px;
@@ -753,32 +751,160 @@ if (!isset($_SESSION['loggedin'])) {
 	<script>vm.mount('.body');</script>
 
 	<script>
-		var $isotope_project = $('.project_button').isotope({
-			itemSelector: '.project'
-		});
+		var search_info = {
+			"search_category_list": [],
+			"search_project_list": [],
+			"search_type_list": [],
+			"search_notes_list": []
+		}
+		var search_project = [];
+		var search_type = [];
+		var search_notes = [];
+		var output;
+
+		update_serch_list("category_button", search_info["search_category_list"]);
+		update_serch_list("project_button", search_info["search_project_list"]);
+		update_serch_list("type_button", search_info["search_type_list"]);
+		update_serch_list("notes_button", search_info["search_notes_list"]);
+
+		function update_serch_list(button_group, list_to_update){
+			$("." + button_group + " .button").click(function() {
+				if($(this).text() == "any"){
+					list_to_update.splice(0,list_to_update.length)
+				} else {
+					data_filter = this.getAttribute("data-filter");
 
-		var filters = {};
-
-		$('.filter_for_project').on( 'click', '.button', function() {
-			var $this = $(this);
-			// get group key
-			var $buttonGroup = $this.parents('.button-group');
-			var filterGroup = $buttonGroup.attr('data-filter-group');
-			// set filter for group
-			filters[ filterGroup ] = $this.attr('data-filter');
-			// combine filters
-			var filterValue = concatValues( filters );
-			// set filter for Isotope
-			$isotope_project.isotope({ filter: filterValue });
-		});
+					if(!$(this).closest('li').hasClass("active")){
+						list_to_update.push(data_filter);
+					} else {
+						list_to_update.splice(list_to_update.indexOf(data_filter), 1);
+					}
+				}
+				hide_button(search_info);
+			});
+		}
+
+		function hide_button(obj) {
+			if(search_info["search_category_list"].length <= 0){
+				$(".category_button").find("li").removeClass("active");
+				$(".category_button .any").addClass("active");
+
+				$(".project_button .button").show();
+			} else {
+				$(".category_button").find("li").removeClass("active");
+				$(".project_button .button").hide();
+				$(".project_button .any").find(".button").show();
+				search_info["search_category_list"].forEach(function(c) {
+					$("[data-filter=" + c + "]").closest("li").addClass("active");
+					$(".project_button ." + c).show();
+				});
+			}
+
+			if(search_info["search_project_list"].length <= 0){
+				$(".project_button").find("li").removeClass("active");
+				$(".project_button .any").addClass("active");
+				
+				$(".notes_button .button").show();
+			} else {
+				$(".project_button").find("li").removeClass("active");
+				$(".notes_button .button").hide();
+				$(".notes_button .any").find(".button").show();
+				search_info["search_project_list"].forEach(function(p) {
+					$("[data-filter=" + p + "]").closest("li").addClass("active");
+					if(notes_list[p] != undefined) {
+						notes_list[p].forEach(function(n) {
+							$(".notes_button ." + n).show();
+						});
+					}
+				});
+			}
+
+			if(search_info["search_type_list"].length <= 0){
+				$(".type_button").find("li").removeClass("active");
+				$(".type_button .any").addClass("active");
+				$(".notes_button").hide();
+				search_info["search_notes_list"].splice(0,search_info["search_notes_list"].length);
+			} else {
+				$(".type_button").find("li").removeClass("active");
+
+				if(search_info["search_type_list"].includes("設計圖")) {
+					$(".notes_button").show();
+				} else {
+					$(".notes_button").hide();
+				}
+				search_info["search_type_list"].forEach(function(t) {
+					$("[data-filter=" + t + "]").closest("li").addClass("active");
+				});
+			}
 
-		function concatValues( obj ) {
-			var value = '';
-			for ( var prop in obj ) {
-				value += obj[ prop ];
+			if(search_info["search_notes_list"].length <= 0){
+				$(".notes_button").find("li").removeClass("active");
+				$(".notes_button .any").addClass("active");
+			} else {
+				$(".notes_button").find("li").removeClass("active");
+				search_info["search_notes_list"].forEach(function(n) {
+					$("[data-filter=" + n + "]").closest("li").addClass("active");
+				});
 			}
-			return value;
 		}
+
+		$(".search-by-filter").click(function() {
+			search_project = [];
+			search_type = [];
+			search_notes = [];
+
+			if(search_info["search_project_list"].length <= 0) {
+				if(search_info["search_category_list"].length <= 0) {
+					search_project = get_object_value_to_list(project_list, "project_id");
+				} else {
+					search_project = get_list_by_given_value(search_info["search_category_list"], project_list, "category_name", "project_id");
+				}
+			} else {
+				search_project = get_list_by_given_value(search_info["search_category_list"], project_list, "category_name", "project_id").filter(function(v){ return search_info["search_project_list"].indexOf(v) > -1 });
+			}
+
+			if(search_info["search_type_list"].length <=0) {
+				search_type = get_object_value_to_list(type_list, "type_name");
+				search_type = get_list_by_given_value(search_type, type_list, "type_name", "type_id");
+			} else {
+				search_type = search_info["search_type_list"];
+			}
+
+			if(search_info["search_notes_list"].length <=0) {
+				search_project.forEach(function(p) {
+					if(notes_list[p] != undefined) {
+						notes_list[p].forEach(function(n) {
+							search_notes.push(n)
+						});
+					}
+				});
+				search_notes = [...new Set(search_notes)];
+			} else {
+				search_notes = search_info["search_notes_list"];
+			}
+
+			
+			
+			$.ajax({
+				url: "./script/php/get_search_list.php",
+				data: {
+					project_id: search_project,
+					type_id: search_type,
+					notes_name: search_notes
+				},
+				type: "GET",
+				async: false,
+				contentType: "application/json",
+				dataType: "json"
+			}).done(function(data) {
+				output = data;
+			}).error(function(error) {
+				console.log(error);
+			});
+
+
+
+		});
 	</script>
 
 </body>

+ 100 - 34
script/js/vue-search-block.js

@@ -1,6 +1,7 @@
 var category_list = [];
 var project_list = [];
 var type_list = [];
+var notes_list = [];
 
 $.ajax({
     url: "./script/php/get_category_list.php",
@@ -14,10 +15,12 @@ $.ajax({
     console.log(error);
 });
 
+var category_id_list = get_object_value_to_list(category_list, 'category_id');
+
 $.ajax({
     url: "./script/php/get_project_list.php",
     data: {
-        category_id: get_object_value_to_list(category_list, 'category_id'),
+        category_id: category_id_list,
     },
     type: "GET",
     async: false,
@@ -41,7 +44,20 @@ $.ajax({
     console.log(error);
 });
 
-project_list = project_list_add_category_name(project_list, category_list);
+$.ajax({
+    url: "./script/php/get_notes_list.php",
+    type: "GET",
+    async: false,
+    contentType: "application/json",
+    dataType: "json"
+}).done(function(data) {
+    notes_list = data;
+}).error(function(error) {
+    console.log(error);
+});
+
+notes_list = merge_object_by_key(notes_list, "project_id", "notes");
+var notes_button_list = new Set([].concat(...Object.values(notes_list)));
 
 const vm = Vue.createApp({});
 
@@ -50,23 +66,23 @@ vm.component('search-block', {
         return {
             category_list: category_list,
             project_list: project_list,
-            type_list: type_list
+            type_list: type_list,
+            notes_button_list: notes_button_list
         }
     },
     template: `<section class="panel">
             <div class="panel-body">
-                <div class="filter_for_project">
-                    <div class="ui-group">
-                        <ul class="button-group nav nav-pills nav-pills-primary" data-filter-group="category">
-                            <li style="padding: 10px 15px;">
-                                <label>工程類別:</label>
-                            </li>
-                            <li class="active">
-                                <a class="button" data-filter="">any</a>
-                            </li>
-                            <filter-button v-for="item in category_list" v-bind:object="item.category_name"></filter-button>
-                        </ul>
-                    </div>
+                <div class="ui-group category_button">
+                    <ul class="button-group nav nav-pills nav-pills-primary" data-filter-group="category">
+                        <li style="padding: 10px 15px;">
+                            <label>工程類別:</label>
+                        </li>
+                        <li class="any active">
+                            <a class="button" data-filter="">any</a>
+                        </li>
+                        <filter-button v-for="item in category_list" v-bind:object="item.category_name"></filter-button>
+                    </ul>
+                   
                 </div>
 
                 <div class="ui-group project_button">
@@ -74,55 +90,88 @@ vm.component('search-block', {
                         <li style="padding: 10px 15px;">
                             <label>專案類別:</label>
                         </li>
-                        <li class="active">
+                        <li class="any active">
                             <a class="button" data-filter="">any</a>
                         </li>
-                        <filter-project-button v-for="item in project_list" v-bind:category_id="item.category_id" v-bind:object="item"></filter-project-button>
+                        <filter-project-button v-for="item in project_list" v-bind:object="item"></filter-project-button>
                     </ul>
                 </div>
 
-                <div class="ui-group">
+                <div class="ui-group type_button">
                     <ul class="button-group nav nav-pills nav-pills-primary" data-filter-group="type">
                         <li style="padding: 10px 15px;">
                             <label>文件類別:</label>
                         </li>
-                        <li class="active">
-                            <a class="button" data-filter="">any</a>               
+                        <li class="any active">
+                            <a class="button" data-filter="">any</a>
                         </li>
                         <filter-button v-for="item in type_list" v-bind:object="item.type_name"></filter-button>
                     </ul>
                 </div>
+
+                <div class="ui-group notes_button" hidden>
+                    <ul class="button-group nav nav-pills nav-pills-primary" data-filter-group="notes">
+                        <li style="padding: 10px 15px;">
+                            <label>設計圖類別:</label>
+                        </li>
+                        <li class="any active">
+                            <a class="button" data-filter="">any</a>
+                        </li>
+                        <filter-notes-button v-for="item in notes_button_list" v-bind:object="item"></filter-notes-button>
+                    </ul>
+                </div>
+                <div class="filter-search-bar">
+                    <hr class="solid short">
+                    <button class="search-by-filter" style="float:right">search</button>
+                </div>
             </div>
+            
         </section>`
 });
 
+
+
 vm.component('filter-button', {
-    template: `<li><a class="button" v-bind:data-filter="addDot">{{object}}</a></li>`,
+    template: `<li><a v-bind:class="addClass" v-bind:data-filter=this.object>{{object}}</a></li>`,
     props: {
-        object: String,
+        object: String
     },
     computed: {
-        addDot() {
-            return "." + this.object;
+        addClass() {
+            if(this.object=="設計圖"){
+                return "button blueprint";
+            } else {
+                return "button";
+            }
         }
     },
 
 });
 
 vm.component('filter-project-button', {
-    template: `<li><a v-bind:class="addClass" v-bind:data-filter="addDot">{{object.project_name}}</a></li>`,
+    template: `<li><a v-bind:class="addClass" v-bind:data-filter=this.object.project_id>{{object.project_name}}</a></li>`,
     props: {
         object: {
-            project_name: String,
-            category_name: String
+            category_name: String,
+            project_id: String,
+            project_name: String
         },
     },
     computed: {
         addClass() {
             return "button project " + this.object.category_name;
-        },
-        addDot() {
-            return "." + this.object;
+        }
+    }
+});
+
+vm.component('filter-notes-button', {
+    template: `<li><a v-bind:class="addClass" v-bind:data-filter=this.object>{{object}}</a></li>`,
+    props: {
+        object: String
+    },
+    computed: {
+        addClass() {
+            return "button notes " + this.object;
         }
     }
 });
@@ -135,9 +184,26 @@ function get_object_value_to_list(obj, key) {
     return value_list
 }
 
-function project_list_add_category_name(p_list, c_list) {
-    for(i=0; i<p_list.length; i++) {
-        Object.assign(p_list[i], c_list[p_list[i]['category_id']-1]);
+function merge_object_by_key(obj, key, value) {
+    output_object = {};
+    while(obj.length > 0){
+        pop_out = obj.pop();
+        if(output_object[pop_out[key]] == undefined){
+            output_object[pop_out[key]] = [pop_out[value]];
+        } else {
+            output_object[pop_out[key]].push(pop_out[value]);
+        }
     }
-    return p_list;
+    return output_object
+}
+
+function get_list_by_given_value(given_value_list, detail_list, given_attribute, search_attribute) {
+    search_list = [];
+    given_value_list.forEach(function(given_value) {
+        target = detail_list.filter(object => object[given_attribute] == given_value);
+        target.forEach(function(x) {
+            search_list.push(x[search_attribute]);
+        });
+    });
+    return search_list;
 }

+ 21 - 0
script/php/get_notes_list.php

@@ -0,0 +1,21 @@
+<?php
+
+include("sql.php");
+$array = [];
+
+$connectionInfo = array("Database" => "$dbname", "UID" => "$username", "PWD" => "$password", "CharacterSet" => "UTF-8");
+$conn = sqlsrv_connect($hostname, $connectionInfo);
+if ($conn === false) {
+    die(print_r(sqlsrv_errors(), true));
+}
+
+$sql = "SELECT DISTINCT [Project_Table].[project_id], [notes] FROM [21000X].[dbo].[Project_Table]
+    RIGHT JOIN [Blueprint] ON [Project_Table].[project_id] = [Blueprint].[project_id];";
+
+$fetchResult = sqlsrv_query($conn, $sql);
+while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {
+    array_push($array ,$row);
+}
+echo json_encode($array,JSON_UNESCAPED_UNICODE);
+
+?>

+ 3 - 1
script/php/get_project_list.php

@@ -12,7 +12,9 @@ if (isset($_GET['category_id'])) {
         die(print_r(sqlsrv_errors(), true));
     }
     
-    $sql = "SELECT DISTINCT [project_id], [project_name],[category_id] FROM [21000X].[dbo].[Project_Table] WHERE [category_id] IN (".$category_id.");";
+    $sql = "SELECT DISTINCT [project_id],[project_name],[Project_Table].[category_id],[category_name] FROM [21000X].[dbo].[Project_Table]
+        INNER JOIN [Construction_Category] ON [Project_Table].[category_id] = [Construction_Category].[category_id]
+        WHERE [Project_Table].[category_id] IN (".$category_id.");";
     
     $fetchResult = sqlsrv_query($conn, $sql);
     while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {

+ 20 - 8
script/php/get_search_list.php

@@ -3,8 +3,9 @@
 if (isset($_GET['project_id'])) {
 
     include("sql.php");
-    $project_id = $_GET['project_id'];
-    $type_id = $_GET['type_id'];
+    $project_id = implode(", ", $_GET['project_id']);
+    $type_id = implode(", ", $_GET['type_id']);
+    $notes_name = implode("', '", $_GET['notes_name']);
     // $search = $_GET['search'];
     $array = [];
 
@@ -13,12 +14,23 @@ if (isset($_GET['project_id'])) {
     if ($conn === false) {
         die(print_r(sqlsrv_errors(), true));
     }
-    
-    $sql = "SELECT DISTINCT [id], [original_name] FROM [21000X].[dbo].[File_Table]
-        WHERE [project_id] IN ($project_id) AND [type_id] IN ($type_id)
-        UNION
-        SELECT DISTINCT [id], [original_name] FROM [21000X].[dbo].[Blueprint]
-        WHERE [project_id] IN ($project_id) AND [type_id] IN ($type_id);";
+
+    if(str_contains($type_id, '3')) {
+        $sql = "SELECT DISTINCT [Blueprint].[project_id],[SN],[original_name],[filename],[project_name],[type_id],[category_name],[notes],[keyword] FROM [21000X].[dbo].[Blueprint]
+            INNER JOIN [Project_Table] ON [Blueprint].[project_id] = [Project_Table].[project_id] 
+            INNER JOIN [Construction_Category] ON [Project_Table].[category_id] = [Construction_Category].[category_id]
+            WHERE [Blueprint].[project_id] IN ($project_id) AND [type_id] IN ($type_id) AND [notes] IN ('$notes_name')
+            UNION
+            SELECT DISTINCT [File_Table].[project_id],[SN],[original_name],[filename],[project_name],[type_id],[category_name],null,[keyword] FROM [21000X].[dbo].[File_Table]
+            INNER JOIN [Project_Table] ON [File_Table].[project_id] = [Project_Table].[project_id]
+            INNER JOIN [Construction_Category] ON [Project_Table].[category_id] = [Construction_Category].[category_id]
+            WHERE [File_Table].[project_id] IN ($project_id) AND [type_id] IN ($type_id);";
+    } else {
+        $sql = "SELECT DISTINCT [File_Table].[project_id],[SN],[original_name],[filename],[project_name],[type_id],[category_name],null,[keyword] FROM [21000X].[dbo].[File_Table]
+            INNER JOIN [Project_Table] ON [File_Table].[project_id] = [Project_Table].[project_id]
+            INNER JOIN [Construction_Category] ON [Project_Table].[category_id] = [Construction_Category].[category_id]
+            WHERE [File_Table].[project_id] IN ($project_id) AND [type_id] IN ($type_id);";
+    }
     
     $fetchResult = sqlsrv_query($conn, $sql);
     while ($row = sqlsrv_fetch_array($fetchResult, SQLSRV_FETCH_ASSOC)) {

Some files were not shown because too many files changed in this diff