2012-06-06 57 views
5

以下jQuery我在我的jsp页面中使用,用于向具有id mytextfield的文本字段添加自动完成选项。如何从使用jQuery添加的项目中删除属性

在同一页面中,有些情况下我必须从此文本字段中删除此自动补全功能。 (这是相同的字段将不得不作为一个文本字段没有自动完成的基础上,基于用户的输入到以前的领域和选项)

有什么办法,以便我可以从特定项目中删除这个新添加的'自动完成'属性,即从$(“#mytextfield”)。

什么其实我想知道的是有没有去除添加的属性

柜面有人要指的是自动完成的代码,我重视它下面..

;(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); 

回答

2

您可以使用任何.removeAttr()选项

$(target).removeAttr('propertyName'); 

这将完全删除该属性。

但是,如果你想改变任何属性,然后使用.prop().attr()

+0

这里自动完成是一个manualy定义的属性,所以阉它是否行得通呢? –

+0

@SarinJacobSunny是的,我想。 – thecodeparadox

+0

感谢它的工作...... :-) –

3

看起来你正在寻找自动完成的destroydisable方法..

检查文档...

destroy

disable

$("#mytextfield").autocomplete("destroy") 
$("#mytextfield").autocomplete("disable") 

不同的是灭绝之后,您将无法启用它回来...但经过使用enable禁用,你可以启用它回来..

相关问题