I leave a link music to enjoy this code. Thanks !
Introduction
My problem arose because I couldn't find a control that handles entities, I needed to select data of a list and be able to store it in the form of entity. There were examples online but none of them complied with the storage cycle of the entity, so I didn't have another option but to build it from scratch. I also needed another feature, which could be used within a gridview
for editing. The current problem with a combobox
is that when loading a page, it necessarily loads all data. The developed search control is optimized to respond through (JSON) as well as the query (LINQ - AsNoTracking
- AsParallel
).
Technology
- Visual Studio 2013 - Update 5
- AjaxControlToolkit version=15.1.4.0
- EntityFramework version=6.1.3
- jQuery version=2.1.4
- Newtonsoft.Json version=7.0.1
- Windows Communication Foundation
Description of the Control
- When the control is initialized, I load dynamically the JavaScripts to events
OnClientPopulating
, OnClientHiding
, OnClientPopulated
, OnClientItemSelected
.
Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
Dim Evento_OnClientPopulating As String
Dim Evento_OnClientCompleted As String
Dim Evento_OnClientPopulated As String
Dim Evento_OnClientItemSelected As String
Evento_OnClientPopulating = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulating"
Evento_OnClientCompleted = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientCompleted"
Evento_OnClientPopulated = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulated"
Evento_OnClientItemSelected = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientItemSelected"
AutoCompleteExtenderClients.OnClientPopulating = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulating"
AutoCompleteExtenderClients.OnClientHiding = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientCompleted"
AutoCompleteExtenderClients.OnClientPopulated = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientPopulated"
AutoCompleteExtenderClients.OnClientItemSelected = _
Me.AutoCompleteExtenderClients.ClientID + "_OnClientItemSelected"
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientPopulating, Me.OnClientPopulating(Evento_OnClientPopulating), False)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientCompleted, Me.OnClientCompleted(Evento_OnClientCompleted), False)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientPopulated, Me.OnClientPopulated(Evento_OnClientPopulated), False)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), _
Evento_OnClientItemSelected, Me.OnClientItemSelected(Evento_OnClientItemSelected), False)
End Sub
- The
TextBox
control is associated with the ajaxToolkit:AutoCompleteExtender
control and configured for the web services using WCF. The Asp:HiddenField
control is used to store the serialized selected entity.
<asp:textbox autocompletetype="Search"
autopostback="false" id="txtClient" maxlength="40"
ontextchanged="txtClient_TextChanged" runat="server"></asp:textbox>
<asp:hiddenfield id="hdnValue"
onvaluechanged="hdnValue_ValueChanged" runat="server">
</asp:hiddenfield>
<ajaxtoolkit:autocompleteextender
completioninterval="3"
completionlistcssclass="completionList"
completionlisthighlighteditemcssclass="itemHighlighted"
completionlistitemcssclass="listItem"
completionsetcount="20"
delimitercharacters=""
enablecaching="false"
firstrowselected="true"
id="AutoCompleteExtenderClients"
minimumprefixlength="1"
runat="server"
servicemethod="GetClientsWCF"
servicepath="~/ServicesWCF/Services.svc"
targetcontrolid="txtClient"
usecontextkey="true">
</ajaxtoolkit:autocompleteextender>
- To search the data in the list, enter by the
prefixText
parameter and then execute the LINQ query. Once the consultation is complete, serializes data and then sends Id
and Name
to the client.
Public Function GetClientsWCF(ByVal prefixText As String, ByVal count As Integer, _
ByVal contextKey As String) As IEnumerable(Of Object) Implements IServices.GetClientsWCF
Using ContextUOWork As New DatabaseEntities
Try
Dim AgentesRequest As New ConcurrentBag(Of Object)
ContextUOWork.Database.Connection.Open()
Dim query As List(Of Names) = (From p In ContextUOWork.Names.AsNoTracking _
Where (p.Name.Trim.ToUpper.StartsWith(prefixText.Trim.ToUpper)) _
Take count Order By p.Name Ascending).AsParallel.ToList()
ContextUOWork.Database.Connection.Close()
For Each c As Names In query
AgentesRequest.Add(_json.Serialize(New With { _
Key .Id = c.Id, _
Key .Name = c.Name.Trim.ToUpper()
}))
Next
Return AgentesRequest.Reverse.Cast(Of Object)()
Catch ex As Exception
Throw New Exception("GetClientsWCF")
End Try
End Using
End Function
- The data is displayed in the client by running the JavaScript dynamic created in step 1. I do the parsing of data
JSON.parse
(list.childNodesi.value
) to transform and be able to read them from client in a list.
function Clients_AutoCompleteExtenderClients_OnClientPopulated(sender, e)
{
$('#Clients_txtClient').removeClass('loading');
var list = $find('Clients_AutoCompleteExtenderClients').get_completionList();
var count = list.childNodes.length;
list.childNodes;
for (i = 0; i < count; i++) {
var item = JSON.parse(list.childNodes[i]._value);
var Id = item.Id.toString().rpad('\u00a0',10);
var Name = item.Name.toString().rpad('\u00a0',50);
list.childNodes [i].innerHTML = Id + Name;};
};
- To select the data in the list, is serialized and stored in the variable hidden (
Clients_hdnValue
), then do a postback to the server (doPostBack
) to run the event hdnValueValueChanged
.
function Clients_AutoCompleteExtenderClients_OnClientItemSelected(sender, e) {
var selectedAgente = eval('(' + e._value + ')');
$('#Clients_txtClient').val(selectedAgente.Name);
$('#Clients_hdnValue').val(JSON.stringify(selectedAgente));
__doPostBack('Clients_hdnValue', '')
};
- Deserialize the value that is in the field of type
HiddenField
and Reflection the NameEF
setting. Trigger the event control ClientSelected()
to warn that an entity is selected.
Protected Sub hdnValue_ValueChanged(sender As Object, e As EventArgs) Handles hdnValue.ValueChanged
NameTyped = New JavaScriptSerializer().Deserialize(Of Object)(DirectCast(sender, HiddenField).Value)
For Each prop As System.Reflection.PropertyInfo In _NamesEF.GetType().GetProperties()
If prop.CanRead Then
For Each pair In NameTyped
If pair.Key.Equals(prop.Name) Then
prop.SetValue(_NamesEF, pair.Value, Nothing)
End If
Next
End If
Next
Me.TBL_NAMES = _NamesEF
RaiseEvent ClientSelected()
End Sub
- The WebForm.aspx form detects the event of the control (Clients). The
TBLNAMES
property contains the selected entity.
Private Sub Clients_ClientSelected() Handles Clients.ClientSelected
Id1.Text = Me.Clients.TBL_NAMES.Id
Name1.Text = Me.Clients.TBL_NAMES.Name
UpdatePanel_Data.Update()
End Sub
Observations
The control can be used within a gridview
. When pressed to editing in the GridView
control automatically control sets the value of the EVAL
property IdAgente
, therefore, executes search of the entity by Id
. Then it sets the TBLNAMES
property.
<uc:SearchClients ID="SearchClients_Value"
runat="server" IdAgente='<%# Eval("IdAgente")%>'/>
Browsers Compatibility
- Microsoft Edge
- Google Chrome version 46.0.2490.80 m
- Internet Explorer version 11.0.10.40
- FireFox version 41.0.2