2015-01-08 1 views
0

Когда пользователь вводит что-то в панель поиска, я хотел бы, чтобы результаты ниже ссылались на страницу, когда вы нажимаете ее, а не заполняете панель поиска тем, что вы нажали. Я очень новичок в JQuery, и я нашел этот учебник онлайн, но он не делает именно то, что я хотел.Панель поиска с раскрывающимся списком jquery, показывающая результаты

Index.php (Просто показывая некоторые из головы и тела)

<script> 
$(document).ready(function(){ 
$("#tag").autocomplete("autocomplete.php", { 
     selectFirst: true 
    }); 
}); 
</script> 
</head> 

<body> 
    <label>Tag:</label> 
    <input name="tag" type="text" id="tag" size="20" style="width:541px; height:23px; font-size:16px; text-indent:5px;" placeholder="Search foods, shopping lists, meal plans and recipes" /> 
</body> 

autocomplete.php (Даже с тегами Мне не удалось добиться связывания на другой странице.)

<?php 
$q=$_GET['q']; 
$my_data=mysql_real_escape_string($q); 
include ("connect.php"); 
$sql="SELECT id, name, description, foodgroup FROM foods WHERE name LIKE '%$my_data%' ORDER BY name"; 
$result = mysql_query($sql); 

if($result) { 
    while($row=mysql_fetch_array($result)) { 
     print "<a href='food.php?foodGroup=" . $row['foodgroup'] . "&name=" . $row['name'] . "&desc=" . $row['description'] . "&foodID=" . $row['id'] . "'><div id='resultContainerDiv'><span id='resultText'>" . $row['name'] . " - " . $row['description'] . "</span></div></a>\n"; 
    } 
} 
?> 

наконец, jquery.autocomplete.js

/* * jQuery Autocomplete plugin 1.1 * * Copyright (c) 2009 Jörn Zaefferer * * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $ */ 

;(function($) {  $.fn.extend({ autocomplete: function(urlOrData, options) {  var isUrl = typeof urlOrData == "string";  options = $.extend({}, $.Autocompleter.defaults, {   url: isUrl ? urlOrData : null,   data: isUrl ? null : urlOrData,    delay: isUrl ? $.Autocompleter.defaults.delay : 10,    max: options && !options.scroll ? 10 : 150  }, options); 
       // if highlight is set to false, replace it with a do-nothing function  options.highlight = options.highlight || function(value) { return value; }; 
       // if the formatMatch option is not specified, then use formatItem for backwards compatibility  options.formatMatch = options.formatMatch || options.formatItem; 
       return this.each(function() {   new $.Autocompleter(this, options);   });  }, result: function(handler) {   return this.bind("result", handler); }, search: function(handler) {   return this.trigger("search", [handler]); }, flushCache: function() {  return this.trigger("flushCache"); }, setOptions: function(options){  return this.trigger("setOptions", [options]); }, unautocomplete: function() {  return this.trigger("unautocomplete"); } }); 

$.Autocompleter = function(input, options) { 

    var KEY = {   UP: 38,   DOWN: 40,  DEL: 46,  TAB: 9,   RETURN: 13,   ESC: 27,  COMMA: 188,   PAGEUP: 33,   PAGEDOWN: 34,  BACKSPACE: 8 }; 

    // Create $ object for input element var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass); 

    var timeout; var previousValue = "";  var cache = $.Autocompleter.Cache(options);  var hasFocus = 0; var lastKeyPressCode; var config = {  mouseDownOnSelect: false }; var select = $.Autocompleter.Select(options, input, selectCurrent, config);   var blockSubmit;  // prevent form submit in opera when selecting with return key $.browser.opera && $(input.form).bind("submit.autocomplete", function() {  if (blockSubmit) {   blockSubmit = false;   return false;  } });   // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {   // a keypress means the input has focus   // avoids issue where input had focus before the autocomplete was applied  hasFocus = 1;  // track last key pressed  lastKeyPressCode = event.keyCode;  switch(event.keyCode) { 
        case KEY.UP: 
       event.preventDefault(); 
       if (select.visible()) { 
        select.prev(); 
       } else { 
        onChange(0, true); 
       } 
       break; 
          case KEY.DOWN: 
       event.preventDefault(); 
       if (select.visible()) { 
        select.next(); 
       } else { 
        onChange(0, true); 
       } 
       break; 
          case KEY.PAGEUP: 
       event.preventDefault(); 
       if (select.visible()) { 
        select.pageUp(); 
       } else { 
        onChange(0, true); 
       } 
       break; 
          case KEY.PAGEDOWN: 
       event.preventDefault(); 
       if (select.visible()) { 
        select.pageDown(); 
       } else { 
        onChange(0, true); 
       } 
       break; 
         // matches also semicolon   case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:    case KEY.TAB:   case KEY.RETURN: 
       if(selectCurrent()) { 
        // stop default to prevent a form submit, Opera needs special handling 
        event.preventDefault(); 
        blockSubmit = true; 
        return false; 
       } 
       break; 
          case KEY.ESC: 
       select.hide(); 
       break; 
          default: 
       clearTimeout(timeout); 
       timeout = setTimeout(onChange, options.delay); 
       break;  } }).focus(function(){  // track whether the field has focus, we shouldn't process any  // results if the field no longer has focus   hasFocus++;  }).blur(function() {  hasFocus = 0;  if (!config.mouseDownOnSelect) {   hideResults();  } }).click(function() {  // show select when clicking in a focused field   if (hasFocus++ > 1 && !select.visible()) {   onChange(0, true);  } }).bind("search", function() {  // TODO why not just specifying both arguments?   var fn = (arguments.length > 1) ? arguments[1] : null;  function findValueCallback(q, data) {   var result;    if(data && data.length) { 
       for (var i=0; i < data.length; i++) { 
        if(data[i].result.toLowerCase() == q.toLowerCase()) { 
         result = data[i]; 
         break; 
        } 
       }   }   if(typeof fn == "function") fn(result);   else $input.trigger("result", result && [result.data, result.value]);  }  $.each(trimWords($input.val()), function(i, value) {   request(value, findValueCallback, findValueCallback);  });  }).bind("flushCache", function() {  cache.flush(); }).bind("setOptions", function() {  $.extend(options, arguments[1]);  // if we've updated the data, repopulate  if ("data" in arguments[1])   cache.populate(); }).bind("unautocomplete", function() {  select.unbind();  $input.unbind();  $(input.form).unbind(".autocomplete"); }); 
      function selectCurrent() {  var selected = select.selected();  if(!selected)    return false; 
       var v = selected.result;  previousValue = v; 
       if (options.multiple) {   var words = trimWords($input.val());   if (words.length > 1) { 
       var seperator = options.multipleSeparator.length; 
       var cursorAt = $(input).selection().start; 
       var wordAt, progress = 0; 
       $.each(words, function(i, word) { 
        progress += word.length; 
        if (cursorAt <= progress) { 
         wordAt = i; 
         return false; 
        } 
        progress += seperator; 
       }); 
       words[wordAt] = v; 
       // TODO this should set the cursor to the right position, but it gets overriden somewhere 
       //$.Autocompleter.Selection(input, progress + seperator, progress + seperator); 
       v = words.join(options.multipleSeparator);   }   v += options.multipleSeparator;   } 
       $input.val(v);  hideResultsNow();  $input.trigger("result", [selected.data, selected.value]);  return true; }  function onChange(crap, skipPrevCheck) {  if(lastKeyPressCode == KEY.DEL) {    select.hide();   return;   } 
       var currentValue = $input.val(); 
       if (!skipPrevCheck && currentValue == previousValue)   return; 
       previousValue = currentValue; 
       currentValue = lastWord(currentValue);  if (currentValue.length >= options.minChars) {    $input.addClass(options.loadingClass);   if (!options.matchCase) 
       currentValue = currentValue.toLowerCase();   request(currentValue, receiveData, hideResultsNow);   } else {   stopLoading();   select.hide();  } };  function trimWords(value) {   if (!value)    return [""];  if (!options.multiple)   return [$.trim(value)];   return $.map(value.split(options.multipleSeparator), function(word) {   return $.trim(value).length ? $.trim(word) : null;  });  }  function lastWord(value) {  if (!options.multiple)   return value;  var words = trimWords(value);  if (words.length == 1)    return words[0];  var cursorAt = $(input).selection().start;  if (cursorAt == value.length) {    words = trimWords(value)  } else {   words = trimWords(value.replace(value.substring(cursorAt), ""));  }  return words[words.length - 1];  }  // fills in the input box w/the first match (assumed to be the best match) // q: the term entered // sValue: the first matching result function autoFill(q, sValue){  // autofill in the complete box w/the first match as long as the user hasn't entered in more data  // if the last user key pressed was backspace, don't autofill  if(options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE) {   // fill in the value (keep the case the user has typed)    $input.val($input.val() + sValue.substring(lastWord(previousValue).length));   // select the portion of the value not typed by the user (so the next character will erase)    $(input).selection(previousValue.length, previousValue.length + sValue.length);   } }; 

    function hideResults() {  clearTimeout(timeout);  timeout = setTimeout(hideResultsNow, 200); }; 

    function hideResultsNow() {   var wasVisible = select.visible();  select.hide();  clearTimeout(timeout);  stopLoading();  if (options.mustMatch) {   // call search and run callback    $input.search(
       function (result){ 
        // if no value found, clear the input box 
        if(!result) { 
         if (options.multiple) { 
          var words = trimWords($input.val()).slice(0, -1); 
          $input.val(words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "")); 
         } 
         else { 
          $input.val(""); 
          $input.trigger("result", null); 
         } 
        } 
       }   );  } }; 

    function receiveData(q, data) {   if (data && data.length && hasFocus) {   stopLoading();   select.display(data, q);   autoFill(q, data[0].value);    select.show();  } else {   hideResultsNow();  } }; 

    function request(term, success, failure) {  if (!options.matchCase)    term = term.toLowerCase();  var data = cache.load(term);  // recieve the cached data  if (data && data.length) {   success(term, data);  // if an AJAX url has been supplied, try loading the data now  } else if((typeof options.url == "string") && (options.url.length > 0)){ 
         var extraParams = { 
       timestamp: +new Date()   };   $.each(options.extraParams, function(key, param) { 
       extraParams[key] = typeof param == "function" ? param() : param;   }); 
         $.ajax({ 
       // try to leverage ajaxQueue plugin to abort previous requests 
       mode: "abort", 
       // limit abortion to this input 
       port: "autocomplete" + input.name, 
       dataType: options.dataType, 
       url: options.url, 
       data: $.extend({ 
        q: lastWord(term), 
        limit: options.max 
       }, extraParams), 
       success: function(data) { 
        var parsed = options.parse && options.parse(data) || parse(data); 
        cache.add(term, parsed); 
        success(term, parsed); 
       }   });   } else {   // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match   select.emptyList();    failure(term);  } };  function parse(data) {  var parsed = [];  var rows = data.split("\n");  for (var i=0; i < rows.length; i++) {   var row = $.trim(rows[i]);   if (row) { 
       row = row.split("|"); 
       parsed[parsed.length] = { 
        data: row, 
        value: row[0], 
        result: options.formatResult && options.formatResult(row, row[0]) || row[0] 
       };   }  }  return parsed; }; 

    function stopLoading() {  $input.removeClass(options.loadingClass); }; 

}; 

$.Autocompleter.defaults = { inputClass: "ac_input",  resultsClass: "ac_results",  loadingClass: "ac_loading",  minChars: 1, delay: 400,  matchCase: false, matchSubset: true, matchContains: false, cacheLength: 10, max: 100, mustMatch: false, extraParams: {}, selectFirst: true, formatItem: function(row) { return row[0]; }, formatMatch: null, autoFill: false, width: 0, multiple: false, multipleSeparator: ", ", highlight: function(value, term) {  return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"); }, 
    scroll: true, 
    scrollHeight: 180 }; 

$.Autocompleter.Cache = function(options) { 

    var data = {}; var length = 0;   function matchSubset(s, sub) {  if (!options.matchCase)    s = s.toLowerCase();  var i = s.indexOf(sub);   if (options.matchContains == "word"){   i = s.toLowerCase().search("\\b" + sub.toLowerCase());  }  if (i == -1) return false;  return i == 0 || options.matchContains;  };  function add(q, value) {  if (length > options.cacheLength){   flush();  }  if (!data[q]){    length++;  }  data[q] = value; }  function populate(){  if(!options.data) return false;  // track the matches  var stMatchSets = {},   nullData = 0; 

     // no url was specified, we need to adjust the cache length to make sure it fits the local data store  if(!options.url) options.cacheLength = 1; 
       // track all options for minChars = 0  stMatchSets[""] = []; 
       // loop through the array and create a lookup structure   for (var i = 0, ol = options.data.length; i < ol; i++) {   var rawValue = options.data[i];    // if rawValue is a string, make an array otherwise just reference the array   rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue; 
         var value = options.formatMatch(rawValue, i+1, options.data.length);   if (value === false) 
       continue; 
          var firstChar = value.charAt(0).toLowerCase();   // if no lookup array for this character exists, look it up now    if(!stMatchSets[firstChar]) 
       stMatchSets[firstChar] = []; 

      // if the match is a string    var row = { 
       value: value, 
       data: rawValue, 
       result: options.formatResult && options.formatResult(rawValue) || value    }; 
         // push the current match into the set list    stMatchSets[firstChar].push(row); 

      // keep track of minChars zero items   if (nullData++ < options.max) { 
       stMatchSets[""].push(row);   }  }; 

     // add the data items to the cache  $.each(stMatchSets, function(i, value) {   // increase the cache size   options.cacheLength++;   // add to the cache    add(i, value);  });  }  // populate any existing data setTimeout(populate, 25);  function flush(){  data = {};  length = 0;  }  return {  flush: flush,  add: add,  populate: populate,   load: function(q) {    if (!options.cacheLength || !length) 
       return null;   /* 
      * if dealing w/local data and matchContains than we must make sure 
      * to loop through all the data collections looking for matches 
      */    if(!options.url && options.matchContains){ 
       // track all matches 
       var csub = []; 
       // loop through all the data grids for matches 
       for(var k in data){ 
        // don't search through the stMatchSets[""] (minChars: 0) cache 
        // this prevents duplicates 
        if(k.length > 0){ 
         var c = data[k]; 
         $.each(c, function(i, x) { 
          // if we've got a match, add it to the array 
          if (matchSubset(x.value, q)) { 
           csub.push(x); 
          } 
         }); 
        } 
       }    
       return csub;   } else    // if the exact item exists, use it    if (data[q]){ 
       return data[q];    } else   if (options.matchSubset) { 
       for (var i = q.length - 1; i >= options.minChars; i--) { 
        var c = data[q.substr(0, i)]; 
        if (c) { 
         var csub = []; 
         $.each(c, function(i, x) { 
          if (matchSubset(x.value, q)) { 
           csub[csub.length] = x; 
          } 
         }); 
         return csub; 
        } 
       }   }   return null;  } }; }; 

$.Autocompleter.Select = function (options, input, select, config) { var CLASSES = {   ACTIVE: "ac_over" };  var listItems,  active = 
-1,   data,  term = "",  needsInit = true,  element,  list;  // Create results function init() {  if (!needsInit)    return;   element = $("<div/>")  .hide()   .addClass(options.resultsClass)   .css("position", "absolute")  .appendTo(document.body); 
      list = $("<ul/>").appendTo(element).mouseover(function(event) {   if(target(event).nodeName && target(event).nodeName.toUpperCase() 
== 'LI') { 
       active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event)); 
       $(target(event)).addClass(CLASSES.ACTIVE);    
      }  }).click(function(event) {   $(target(event)).addClass(CLASSES.ACTIVE);   select();   // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus   input.focus();   return false;  }).mousedown(function() {   config.mouseDownOnSelect = true;  }).mouseup(function() {    config.mouseDownOnSelect = false;  }); 
       if(options.width > 0)    element.css("width", options.width); 
        needsInit = false; }  function target(event) {  var element = event.target;   while(element && element.tagName != "LI")   element = element.parentNode;  // more fun with IE, sometimes event.target is empty, just ignore it then  if(!element)   return [];  return element;  } 

    function moveSelect(step) {   listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);  movePosition(step); 
     var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE); 
     if(options.scroll) { 
      var offset = 0; 
      listItems.slice(0, active).each(function() { 
       offset += this.offsetHeight;   }); 
      if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) { 
       list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight()); 
      } else if(offset < list.scrollTop()) { 
       list.scrollTop(offset); 
      } 
     } };  function movePosition(step) {  active += step;   if (active < 0) {   active = listItems.size() - 1;  } else if (active 
>= listItems.size()) {   active = 0;   } }  function limitNumberOfItems(available) {  return options.max && options.max < available   ? options.max   : available; }  function fillList() {  list.empty();  var max = limitNumberOfItems(data.length);  for (var i=0; i < max; i++) {   if (!data[i]) 
       continue;   var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);   if (formatted === false) 
       continue;   var li = $("<li/>").html(options.highlight(formatted, term)).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];    $.data(li, "ac_data", data[i]);   }  listItems = list.find("li");  if (options.selectFirst) {   listItems.slice(0, 1).addClass(CLASSES.ACTIVE);    active = 0;   }  // apply bgiframe if available  if ($.fn.bgiframe)   list.bgiframe(); }  return {  display: function(d, q) {   init();    data = d;   term = q;   fillList();   },  next: function() {   moveSelect(1);  },  prev: function() {   moveSelect(-1);   },  pageUp: function() {   if (active != 0 && active - 8 < 0) { 
       moveSelect(-active);   } else { 
       moveSelect(-8);    }  },  pageDown: function() {   if (active != listItems.size() - 1 && active + 8 > listItems.size()) { 
       moveSelect(listItems.size() - 1 - active);   } else { 
       moveSelect(8);   }  },  hide: function() {   element && element.hide();   listItems && listItems.removeClass(CLASSES.ACTIVE);    active = -1;  },  visible : function() {   return element && element.is(":visible");  },  current: function() {   return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);  },  show: function() {   var offset = $(input).offset();    element.css({ 
       width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(), 
       top: offset.top + input.offsetHeight, 
       left: offset.left   }).show(); 
      if(options.scroll) { 
       list.scrollTop(0); 
       list.css({ 
        maxHeight: options.scrollHeight, 
        overflow: 'auto' 
       }); 

       if($.browser.msie && typeof document.body.style.maxHeight === "undefined") { 
        var listHeight = 0; 
        listItems.each(function() { 
         listHeight += this.offsetHeight; 
        }); 
        var scrollbarsVisible = listHeight > options.scrollHeight; 
        list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight); 
        if (!scrollbarsVisible) { 
         // IE doesn't recalculate width when scrollbar disappears 
         listItems.width(list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right"))); 
        } 
       } 

      }  },  selected: function() {   var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);    return selected && selected.length && $.data(selected[0], "ac_data");  },  emptyList: function(){    list && list.empty();  },  unbind: function() {   element && element.remove();  } }; }; 

$.fn.selection = function(start, end) {  if (start !== undefined) {  return this.each(function() {   if(this.createTextRange){ 
       var selRange = this.createTextRange(); 
       if (end === undefined || start == end) { 
        selRange.move("character", start); 
        selRange.select(); 
       } else { 
        selRange.collapse(true); 
        selRange.moveStart("character", start); 
        selRange.moveEnd("character", end); 
        selRange.select(); 
       }   } else if(this.setSelectionRange){ 
       this.setSelectionRange(start, end);    } else if(this.selectionStart){ 
       this.selectionStart = start; 
       this.selectionEnd = end;   }  });  } var field = this[0]; if (field.createTextRange) {  var range = document.selection.createRange(),   orig = field.value,    teststring 
= "<->",   textLength = range.text.length;   range.text = teststring;  var caretAt = field.value.indexOf(teststring);  field.value = orig;   this.selection(caretAt, caretAt + textLength);  return {   start: caretAt,    end: caretAt + textLength  } } else if(field.selectionStart !== undefined){  return {   start: field.selectionStart,   end: field.selectionEnd   } } }; 

})(jQuery); 

Спасибо,

Райан

+1

При использовании «в php строка оценивается так, что вы можете отказаться от нее». $ Хх. "и замените его просто $ xxx http://php.net/manual/en/language.types.string.php – ShiftyThomas

ответ

1

В поиске сценария у вас есть ошибка:

<?php 
$q=$_GET['q']; 
$my_data=mysql_real_escape_string($q); 
include ("connect.php"); 

mysql_real_escape_string вернет ложь (эквивалент пустой строки), если нет базы данных но тем не менее вы эффективно опустошаете свою строку поиска.

Вы должны переключиться, что вокруг:

<?php 
$q=$_GET['q']; 
include ("connect.php"); 
$my_data=mysql_real_escape_string($q); 

Вы должны также добавить обработку ошибок для вызовов базы данных и перейти к PDO или MySQLi, если это возможно, как mysql_* функции устарели.

+0

Спасибо, что указали это! Теперь я это измени буду! –

Смежные вопросы