samrtselect——将 下拉列表控件 转变成可以智能提示、带下拉的文本框
2012-08-12 22:18
946 查看
1. jquery.autocomplete.js [ 有改动 ]
2. jquery.autocomplete.css
3. jq.smallTools.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 : 1, 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 bodyObj = document.body ? document.body : document.documentElement; $(bodyObj).click(function(event){ var target = event.target ? event.target : event.srcElement; if(options.usedForSmartSelect){ if(!$(target).hasClass("smartselect")){ select.hide(); if($(input).val()==""){ $(input).val( options.usedForSmartSelectBtn.data("txtStartValue") ); } } } event.stopPropagation(); //阻止事件冒泡 return false; }); 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()) || ( !select.visible() && options.usedForSmartSelect && options.usedForSmartSelectBtn.data("btnClick")=="1" ) ) { 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"); }).bind("dblclick",function(){ $input.select(); }); 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); } } } ); } //专用于 smartselect 的部分. yenange if(options.usedForSmartSelect && options.usedForSmartSelectBtn!=null && options.usedForSmartSelectBtn.data("btnClick")=="1" ){ if( options.usedForSmartSelectBtn.data("activeElementIsTxt")=="1" ){ // options.usedForSmartSelectBtn.data("activeElementIsTxt","-1"); // }else if( options.usedForSmartSelectBtn.data("activeElementIsTxt")=="-1" ){ options.usedForSmartSelectBtn.data("activeElementIsTxt","0"); }else{ options.usedForSmartSelectBtn.data("btnClick","0"); var txtStartValue = options.usedForSmartSelectBtn.data("txtStartValue"); var txtEndValue = $input.val(); if(txtStartValue!="" && txtEndValue==""){ $input.val(txtStartValue); options.usedForSmartSelectSel.val( options.usedForSmartSelectBtn.data("selStartValue") ); } } } }; 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: ", ", highlightColor: "#ffffff", highlight: function(value, term) { var keyWord = "<strong style='color:"+this.highlightColor+"' >$1</strong>"; return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), keyWord ); }, scroll: true, scrollHeight: 180, usedForSmartSelect:false, usedForSmartSelectBtn: null, usedForSmartSelectBtnClear: null, usedForSmartSelectSel: null }; $.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) .addClass("smartselect") .css({"position":"absolute"}) .appendTo(document.body); list = $("<ul/>").css({ "overflow-x" : "hidden" }).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 ); //element.css('height', scrollbarsVisible ? options.scrollHeight : listHeight+5 ); if (!scrollbarsVisible) { // IE doesn't recalculate width when scrollbar disappears listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right"))+10 ); } //} } }, 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. jquery.autocomplete.css
.ac_results { padding: 0px; border: 1px solid black; background-color: white; overflow: hidden; z-index: 99999;text-align:left; } .ac_results ul { width: 100%; list-style-position: outside; list-style: none; padding: 0; margin: 0;text-align:left; } .ac_results li { margin: 0px; padding: 2px 5px; cursor: default; display: block; /* if width will be 100% horizontal scrollbar will apear when scroll mode will be used */ /*width: 100%;*/ font: menu; font-size: 12px; /* it is very important, if line-height not setted or setted in relative units scroll will be broken in firefox */ line-height: 16px; overflow: hidden;text-align:left; } .ac_loading { background: white url('indicator.gif') right center no-repeat; } .ac_odd { background-color: #eee;text-align:left; } .ac_over { background-color: #0A246A; color: white; text-align:left; }
3. jq.smallTools.js
//===================================================================== //插件名称: smartselect //作 者: yenange //功能说明: 将 下拉列表控件 转变成可以智能提示、带下拉的文本框 //输入参数: 无 //调用示例: .net控件: $(function(){ $("#<%=ddlTest.ClientID %>").smartselect(); }); // html控件: $(function(){ $("#ddlTest").smartselect(); }); //输出参数: select的jquery对象 //注 : 1. 基本功能在IE可用; // 2. 如果是联动效果, 如: 另一 DropDownList( A_Prev ) 在onchange 时改变此 DropDownList(A), 建议在onchange事件最后加上重新绑定插件 // function onchange{ ......... $ddl.smartselect(); } // 3. 如果此 DropDownList(A) 的改变,会联动到下一 DropDownList ( A_Next ),设置了 AutoPostBack="true" // 或者 后台 A.Attributes.Add("onchange","??") 均可以。 //创建日期: 2012-08-11 ;(function($) { $.fn.extend({ "smartselect": function () { var $sel=this; //this已是jquery对象 $( "#txt_SS_"+$sel.attr("id")+",#btn_SS_"+$sel.attr("id")+",#btn_SS_Close_"+$sel.attr("id") ).remove(); var inputHtml="<input type='text' id='txt_SS_"+$sel.attr("id")+"' class='fslTextBox smartselect' style=\"height:20px;cursor:pointer;\">"; var imgPath="/rms/CmInClude/jqPulgin/smallTools/smartselect.gif"; //"autoComplete/smartselect.gif" var btnHtml="<input type='button' class='CmButton smartselect' value='...' id='btn_SS_"+$sel.attr("id")+"' style=\"cursor:pointer;\">";//background: url('"+imgPath+"') no-repeat scroll right center #FFFFFF; var btnClearHtml="<img id='btn_SS_Close_"+$sel.attr("id")+"' class='smartselect' title='清空' src='/rms/CmImg/X.gif' border='0' style='cursor:pointer;' />"; var $txt = $(inputHtml); var $btn = $(btnHtml); var $btnClear = $(btnClearHtml); $txt.width($sel.width()); $sel.before( $txt ).before($btn).before($btnClear); $btn.mousedown(function(){ //重要的一步, 判断焦点是否在 文本框 上 var act = document.activeElement.id; $btn.data("activeElementIsTxt", (act == $txt.attr("id") || act== $sel.attr("id") ) ?"1":"0" ) }).click(function(){ $btn.data("btnClick", "1"); $btn.data("txtStartValue",$txt.val()); $btn.data("selStartValue",$sel.val()); $txt.val(""); $txt.focus(); setTimeout(function(){ $txt.click(); },200); var $divEmpty=$("<div style='position: absolute;' class='ac_results>"); $divEmpty.width($txt.width()); $divEmpty.css({"top":$txt.css("top")+$txt.height()}); }); $btnClear.click(function(){ $txt.val($sel.find("option:first").text()); //初始化为第一项 txtSyncToSel($txt.val()); //联动到下拉列表 }); selSyncToTxt(false); $sel.hide(); $sel.bind("change",function(){ selSyncToTxt(true); }); $sel.unbind("propertychange").bind("propertychange", function(e) { e.preventDefault(); selSyncToTxt(true); }); $txt.autocomplete(getSelTextArr().txtArr, { minChars: 0, max: 100, autoFill: false, matchContains: true, scroll: true, scrollHeight: 300, highlightColor: "red", usedForSmartSelect: true, usedForSmartSelectBtn: $btn, usedForSmartSelectBtnClear: $btnClear, usedForSmartSelectSel: $sel }).result(function(event,data,formatted){ txtSyncToSel(data); }).blur(function(){ //如果是点击按钮触发,而且文本框为空,而且下拉列表最初的值没有产生变化, 不作处理 if($btn.data("btnClick")=="1" && $txt.val()=="" && $btn.data("selStartValue")==$sel.val()){ return; } //如果两者本身已能对应,就不需要同步了 if( $txt.val()==$sel.find("option:selected").text() ){ return; } txtSyncToSel($txt.val()); }); //将文本框的显示文本同步到下拉列表 function txtSyncToSel(txtVal){ var isEqual=false; var data = getSelTextArr(); var selTextArr = data.txtArr; var selValArr = data.valArr; for(var i in selTextArr){ if(txtVal==selTextArr[i]){ $sel.val(selValArr[i]); isEqual=true; break; } } if(!isEqual){ $txt.val($sel.find("option:first").text()); } _selfOnChange(); } //将下拉同步文本框 function selSyncToTxt( triggerOnChange ){ if(typeof(triggerOnChange)=="undefined"){ triggerOnChange=false; } //如果两者本身已能对应,就不需要同步了 if( ($txt.val()==$sel.find("option:selected").text()) ){ return; } $txt.val($sel.find(":selected").text()); if(triggerOnChange){ _selfOnChange(); } } function _selfOnChange(){ var strEvent=$sel.attr("onchange"); if( strEvent==null || strEvent==undefined || typeof(strEvent)!="function"){ return; } var funcName = strEvent.toString(); if(funcName.indexOf("__doPostBack")!=-1){ setTimeout(function(){ $sel[0].onchange(); },800); } else{ $sel[0].onchange(); } } //取得下拉列表的文本的数组 function getSelTextArr(){ var selTextArr=[]; var selValArr=[]; $sel.find("option").each(function(){ selTextArr.push($(this).text()); selValArr.push(this.value); }); var data={ txtArr:selTextArr, valArr:selValArr }; return data; } return this; }//end of "smartselect" //解除插件封装, 显示出原来的控件 ,"unsmartselect": function () { var $sel=this; //this已是jquery对象 $( "#txt_SS_"+$sel.attr("id")+",#btn_SS_"+$sel.attr("id") ).remove(); $sel.show(); return this; } }); })(jQuery);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>无标题页</title> <script type="text/javascript"> function sayValue(){ alert("值:" + document.getElementById('ddlTest').value); } </script> </head> <body> <div style="width:100%;text-align:center;" > <select id="ddlTest" onchange="alert('发生了onchange事件')" onpropertychange="alert('发生了onpropertychange事件')" > <option value="" ><--全部--></option> <option value="1" >湖南</option> <option value="2" >湖北</option> <option value="3" >广东</option> <option value="4" >广西</option> </select> <input id="Button2" type="button" value="改变下拉列表的值为广东" onclick="document.getElementById('ddlTest').value='3'" /> <input id="Button1" type="button" value="选中了:" onclick="sayValue()" /> </div> </body> </html>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PostBack.aspx.cs" Inherits="examples_PostBack" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>无标题页</title> <script src="flexselect/jquery.min.js" type="text/javascript"></script> <link href="autoComplete/jquery.autocomplete.css" rel="stylesheet" type="text/css" /> <script src="autoComplete/jquery.autocomplete.min.js" type="text/javascript"></script> <script src="autoComplete/jq.smallTools.js" type="text/javascript"></script> <script type="text/javascript"> $(function(){ $("#<%=ddlTest.ClientID %>").smartselect(); }); </script> </head> <body> <form id="form1" runat="server"> <span> <asp:DropDownList ID="ddlTest" runat="server" Width="150px" AutoPostBack="true" > <asp:ListItem Value="" Text="<--全部-->"></asp:ListItem> <asp:ListItem Value="1" Text="湖南"></asp:ListItem> <asp:ListItem Value="2" Text="湖北"></asp:ListItem> <asp:ListItem Value="3" Text="广东"></asp:ListItem> <asp:ListItem Value="4" Text="广西"></asp:ListItem> </asp:DropDownList> </span> <asp:Button ID="Button1" runat="server" Text="Button" /> </form> </body> </html>
相关文章推荐
- altas(ajax)控件(十):DropDown让文本框拥有下拉列表
- VB.Net自己写的一个控件:ComboBox下拉列表中显示多列数据(可以绑定数据表)
- 不错的下拉列表.HTML控件和服务器控件都可以使用
- html 中可以自定义输入的 select 下拉列表
- 自动文本框,下拉列表,信息提示
- 下拉列表选择控件, 用于替换原生的 select 控件
- altas(ajax)控件(十):DropDown让文本框拥有下拉列表
- select下拉列表提示title添加
- altas(ajax)控件(十):DropDown让文本框拥有下拉列表
- web开发(脚本和动态语言) 编辑 下拉列表 select控件 可编辑
- Android 控件 -------- AutoCompleteTextView 动态匹配内容,例如 百度搜索提示下拉列表功能
- Android -- 对话框 Dialog: 确定取消,单选多选,进度显示, 常用控件示例:单选多选框,下拉列表,进度条,自动完成文本框, 菜单显示
- 用原生HTML5控件实现输入框自动提示(下拉列表)
- 实现类似google搜索效果,文本框输入智能提示,没有用ajax控件和第三方控件,完全手写代码
- 下拉列表选择控件, 用于替换原生的 select 控件
- ASP.NET自定义Web服务器控件-DropDownList/Select下拉列表控件
- select下拉列表 和 radio单选按钮控件开关---- 根据值选择选项 & change事件
- 文本框输入下拉智能提示---sql
- Android—高级控件(一)自动完成文本框,下拉列表
- Qt5.10 用基础控件实现下拉列表菜单,可以展开多级菜单