2012-09-21 32 views
3

短版:Ajax AutoCompleteExtender - 样式单个项目?

我想知道我怎么可以改变由autocompleteextender产生的个别项目的css样式,但控制只允许我设置的所有项目组的造型。

龙版本:

我有利用的AutoCompleteExtender一个搜索框。在您输入内容时,搜索框会弹出搜索框。

<asp:TextBox ID="txtSearch" OnChange="javascript: Changed(this);" runat="server" style="width:360px;" /> 
<cc1:AutoCompleteExtender ID="Search_AutoCompleteExtender" runat="server" 
        BehaviorID="Search_AutoCompleteExtender" 
        MinimumPrefixLength="3" 
        DelimiterCharacters="" 
        Enabled="True" 
        ServicePath="~/Services/Search.asmx" 
        ServiceMethod="GetResults" 
        TargetControlID="txtSearch" 
        FirstRowSelected="true" 
        CompletionListItemCssClass="AutoExtenderList" 
        CompletionListHighlightedItemCssClass="AutoExtenderHighlight" 
        CompletionInterval="1" 
        EnableCaching="false" 
        CompletionSetCount="20" 
        CompletionListElementID="autocompleteDropDownPanel1" /> 

<asp:Panel ID="autocompleteDropDownPanel1" runat="server" ScrollBars="Vertical" Height="250" style="overflow-y:scroll;position:absolute;left:0;top:0"/

的AutoCompleteExtender有一个CSS类分配给每一个项目,CompletionListItemCssClassCompletionListHighlightedItemCssClass突出显示的项目的属性。我想知道的是我如何根据特定标准单独设计特定项目。

在我的服务中,我正在运行一个存储过程,稍微操纵结果,然后将字符串数组返回给autocompleteextender。我有存储过程设置为包含每个记录的特定标志..我想使用该标志来突出显示搜索结果的某些行(例如,将文本转为红色)。

我该怎么做?我似乎无法找到任何方式访问个别项目来改变他们的造型。

我一直在寻找各种帮助,并且空手而来。谢谢。

回答

3

默认情况下不支持此类行为,但您可以调整AutoCompleteExtender源以添加此功能。实际上,有两种方法可用:第一种方法是扩展对象,从Web服务返回到扩展器,并使用项目css类的新属性,并将此属性值应用于扩展器客户端脚本中。第二种可用的方法是引入项目创建的新事件,在页面上处理它并根据项目值对项目应用自定义逻辑。让我们在这里实施这两种方法。首先你需要下载AjaxControlToolkit源代码,如果你还没有这个,请打开Client/MicrosoftAjax.Extended/AutoComplete/AutoCompleteBehavior.pre.js文件。在这个文件中,你需要改变,如下_update方法:

_update: function (prefixText, completionItems, cacheResults) { 
    /// <summary> 
    /// Method to update the status of the autocomplete behavior 
    /// </summary> 
    /// <param name="prefixText" type="String" DomElement="false" mayBeNull="true" /> 
    /// <param name="completionItems" type="Object" DomElement="false" mayBeNull="true" /> 
    /// <param name="cacheResults" type="Object" DomElement="false" mayBeNull="true" /> 
    /// <returns />  
    if (cacheResults && this.get_enableCaching()) { 
     if (!this._cache) { 
      this._cache = {}; 
     } 
     this._cache[prefixText] = completionItems; 
    } 

    // If the target control loses focus or 
    // if the value in textbox has changed before the webservice returned 
    // completion items we don't need to show popup 
    if ((!this._textBoxHasFocus) || (prefixText != this._currentCompletionWord())) { 
     this._hideCompletionList(); 
     return; 
    } 

    if (completionItems && completionItems.length) { 
     this._completionListElement.innerHTML = ''; 
     this._selectIndex = -1; 
     var _firstChild = null; 
     var text = null; 
     var value = null; 
     var cssClass = null; 
     var dataItem = null; 

     //remove this line if you don't need to implement itemDataBinding event 
     var itemDataBindingHandler = this.get_events().getHandler('itemDataBinding'); 

     for (var i = 0; i < completionItems.length; i++) { 
      // Create the item     
      var itemElement = null; 
      if (this._completionListElementID) { 
       // the completion element has been created by the user and li won't necessarily work 
       itemElement = document.createElement('div'); 
      } else { 
       itemElement = document.createElement('li'); 
      } 

      // set the first child if it is null 
      if (_firstChild == null) { 
       _firstChild = itemElement; 
      } 

      // Get the text/value for the item 
      try { 
       dataItem = Sys.Serialization.JavaScriptSerializer.deserialize(completionItems[i]); 
       if (dataItem && dataItem.First) { 
        // Use the text and value pair returned from the web service 
        text = dataItem.First; 
        value = dataItem.Second; 

        if (dataItem.CssClass) { 
         cssClass = dataItem.CssClass; 
        } 
       } 
       else { 
        // If the web service only returned a regular string, use it for 
        // both the text and the value 
        text = completionItems[i]; 
        value = text; 
       } 
      } catch (ex) { 
       text = completionItems[i]; 
       value = completionItems[i]; 
      } 


      // Set the text/value for the item 
      // ShowOnlyCurrentWordInCompletionListItem support 
      var optionText = this._showOnlyCurrentWordInCompletionListItem ? text : this._getTextWithInsertedWord(text); 
      itemElement.appendChild(document.createTextNode(optionText)); 
      itemElement._value = value; 
      itemElement.__item = ''; 

      if (this._completionListItemCssClass) { 
       Sys.UI.DomElement.addCssClass(itemElement, this._completionListItemCssClass); 
      } else { 
       var itemElementStyle = itemElement.style; 
       itemElementStyle.padding = '0px'; 
       itemElementStyle.textAlign = 'left'; 
       itemElementStyle.textOverflow = 'ellipsis'; 
       // workaround for safari since normal colors do not 
       // show well there. 
       if (Sys.Browser.agent === Sys.Browser.Safari) { 
        itemElementStyle.backgroundColor = 'white'; 
        itemElementStyle.color = 'black'; 
       } else { 
        itemElementStyle.backgroundColor = this._textBackground; 
        itemElementStyle.color = this._textColor; 
       } 
      } 

      if (cssClass) { 
       Sys.UI.DomElement.addCssClass(itemElement, cssClass); 
      } 

      //remove this if you don't need to implement itemDataBinding event 
      if (itemDataBindingHandler) { 
       itemDataBindingHandler(itemElement, dataItem || completionItems[i]); 
      } 

      this._completionListElement.appendChild(itemElement); 
     } 
     var elementBounds = $common.getBounds(this.get_element()); 
     this._completionListElement.style.width = Math.max(1, elementBounds.width - 2) + 'px'; 
     this._completionListElement.scrollTop = 0; 

     this.raisePopulated(Sys.EventArgs.Empty); 

     var eventArgs = new Sys.CancelEventArgs(); 
     this.raiseShowing(eventArgs); 
     if (!eventArgs.get_cancel()) { 
      this.showPopup(); 
      // Check if the first Row is to be selected by default and if yes highlight it and updated selectIndex. 
      if (this._firstRowSelected && (_firstChild != null)) { 
       this._highlightItem(_firstChild); 
       this._selectIndex = 0; 
      } 
     } 
    } else { 
     this._hideCompletionList(); 
    } 
} 

如果你不打算实施新的客户端事件的情况,这是在项目中,您需要的所有更改。您已经可以从Web服务器方法传递项目css类以及项目的文本和值。唯一的区别是使用自定义类,而不是在默认情况下在AjaxControlToolkit控制使用一对:

[WebMethod] 
public string[] GetCompletionList(string prefixText, int count) 
{ 
    var serializer = new JavaScriptSerializer(); 
    var items = Enumerable.Range(1, count) 
     .Select(id => serializer.Serialize(
         new 
         { 
          Second = id, 
          First = prefixText + "_" + Guid.NewGuid().ToString(), 
          CssClass = id % 2 == 0 ? "even" : "odd" 
         })); 


    return items.ToArray(); 
} 

如果你想还实现自定义客户端事件(即给确实更大的灵活性),那么你需要添加一些更多的代码AutoCompleteBehavior.pre.js文件。添加以下代码某处Sys.Extended.UI.AutoCompleteBehavior.prototype对象:

add_itemDataBinding: function (handler) { 
    this.get_events().addHandler('itemDataBinding', handler); 
}, 

remove_itemDataBinding: function (handler) { 
    this.get_events().removeHandler('itemDataBinding', handler); 
}, 

而且,打开Server/AjaxControlToolkit/AutoComplete/AutoCompleteExtender.cs文件,这个属性添加到AutoCompleteExtender类:

/// <summary> 
/// Handler to attach to the client-side item data binding event 
/// </summary> 
[DefaultValue("")] 
[ExtenderControlEvent] 
[ClientPropertyName("itemDataBinding")] 
public string OnClientItemDataBinding 
{ 
    get { return GetPropertyValue("OnClientItemDataBinding", string.Empty); } 
    set { SetPropertyValue("OnClientItemDataBinding", value); } 
} 

重建项目后就可以使用具有附加功能的自定义AjaxControlToolkit程序集。

<script type="text/javascript"> 
    function itemDataBinding(item, dataItem) { 
     var value = parseInt(dataItem.Second, 10); 
     if (!isNaN(value)) { 
      item.className = value % 2 == 0 ? "even" : "odd"; 
     } 
    } 
</script> 

<ajaxToolkit:AutoCompleteExtender runat="server" ID="autoComplete1" 
    TargetControlID="myTextBox" ServicePath="AutoComplete.asmx" ServiceMethod="GetCompletionList" 
    OnClientItemDataBinding="itemDataBinding"> 
+0

这是我见过的最好的答案之一。非常感谢花时间帮助我。 – user1003916