Sunday, March 18, 2012

AJAX AutoComplete Extender Validation

Ada beberapa cara untuk melakukan autocomplete TextBox pada .NET. Autocomplete menjadi fungsi yang sering digunakan untuk memudahkan pengguna karena memberikan suggest isi dari database.

Di dalam .NET ada beberapa cara untuk melakukan autocomplete. Jika isi dari autocomplete tidak mengambil dari database, sangat mudah sekali untuk dilakukan untuk membuat fungsi tersebut. Tinggal mendaftarkan isi dari autocomplete tersebut kedalam array JavaScript dan kemudian menyettingnya.


<script>
var customarray = new Array('an apple', 'alligator', 'elephant', 'pear', 'kingbird', 'kingbolt', 'kingcraft', 'kingcup', 'kingdom', 'kingfisher', 'kingpin');
</script>

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<script>
var obj = actb(document.getElementById('TextBox1'), customarray);
</script>

Untuk lebih jelasnya penggunaan cara tersebut dapat dilihat pada tutorial berikut.

Selanjutnya, jika menggunakan database maka dapat dilakukan dengan menggunakan bantuan web service. Ada beberapa cara juga melakukannya.

Yang pertama adalah dengan menggunakan JQuery.

<script type="text/javascript">
$(function () {
$(".tb").autocomplete({
source: function (request, response) {
$.ajax({
url: "EmployeeList.asmx/FetchEmailList",
data: "{ 'mail': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
response($.map(data.d, function (item) {
return {
value: item.Email
}
}))
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
minLength: 1
});
});
</script>

<asp:TextBox ID="tbAuto" class="tb" runat="server"></asp:TextBox>

Pada fungsi di atas, akan memanggil list dari Email yang mekanisme pengiriman menggunakan datatype JSON. Fungsi tersebut juga muncul dengan minimal mengetikan 1 karakter. Untuk fungsi melakukan query ke database di web service dilakukan dengan menggunakan fungsi berikut:

var emp = new Employee();
var fetchEmail = emp.GetEmployeeList()
.Where(m => m.Email.ToLower().Contains(mail.ToLower()));
return fetchEmail.ToList();

Untuk lebih jelasnya dapat dilihat pada artikel berikut.

Untuk cara yang kedua adalah dengan menggunakan AJAX Control Toolkit dengan fungsi AutoCompleteExtender, seperti berikut:

<ajaxToolkit:AutoCompleteExtender
runat="server"
BehaviorID="AutoCompleteEx"
ID="autoComplete1"
TargetControlID="myTextBox"
ServicePath="AutoComplete.asmx"
ServiceMethod="GetCompletionList"
MinimumPrefixLength="1"
CompletionInterval="100"
EnableCaching="true"
CompletionSetCount="10"
CompletionListCssClass="autocomplete_completionListElement"
CompletionListItemCssClass="autocomplete_listItem"
CompletionListHighlightedItemCssClass="autocomplete_highlightedListItem"
ShowOnlyCurrentWordInCompletionListItem="true"

OnClientItemSelected="validasi"
>
<Animations>
<OnShow>
<Sequence>
<%-- Make the completion list transparent and then show it --%>
<OpacityAction Opacity="0" />
<HideAction Visible="true" />

<%--Cache the original size of the completion list the first time
the animation is played and then set it to zero --%>
<ScriptAction Script="
// Cache the size and setup the initial size
var behavior = $find('AutoCompleteEx');
if (!behavior._height) {
var target = behavior.get_completionList();
behavior._height = target.offsetHeight - 2;
target.style.height = '0px';
}" />

<%-- Expand from 0px to the appropriate size while fading in --%>
<Parallel Duration=".4">
<FadeIn />
<Length PropertyKey="height" StartValue="0" EndValueScript="$find('AutoCompleteEx')._height" />
</Parallel>
</Sequence>
</OnShow>
<OnHide>
<%-- Collapse down to 0px and fade out --%>
<Parallel Duration=".4">
<FadeOut />
<Length PropertyKey="height" StartValueScript="$find('AutoCompleteEx')._height" EndValue="0" />
</Parallel>
</OnHide>
</Animations>
</ajaxToolkit:AutoCompleteExtender>

<asp:TextBox runat="server" ID="myTextBox" Width="300" autocomplete="off" />

Dengan CSS style sebagai berikut:

<style type="text/css">
.autocomplete_completionListElement
{
visibility: hidden;
margin: 0px !important;
background-color: inherit;
color: windowtext;
border: buttonshadow;
border-width: 0px;
border-style: solid;
cursor: 'default';
overflow: auto;
height: 200px;
text-align: right;
list-style-type: none;
font-family: courier new;
font-size: 10pt;
padding: 0px;
}
/* AutoComplete highlighted item */.autocomplete_highlightedListItem
{
background-color: red;
color: black;
padding: 1px;
}
/* AutoComplete item */.autocomplete_listItem
{
background-color: Blue;
color: windowtext;
padding: 1px;
}

</style>

Dan fungsi di web service adalah sebagai berikut:

public static string[] query(string prefixText, int count)
{

using (HelloWorldEntities ent1 = new HelloWorldEntities())
{
try
{
var ds = (from r in ent1.Coba1
where r.Nama.ToLower().Contains(prefixText.ToLower())
select r.Nama).Take(count);

string[] results = ds.ToArray<string>();
Array.Sort<string>(results);
return results;
}

catch (Exception ex)
{
throw ex;
}

}
}

Untuk lebih jelas cara kedua diatas (original version) dapat dilihat pada artikel code project berikut.

Nah, bagaimana jika ingin menambahkan validasi pada fungsi ajax autocomplete extender diatas? (Saya menggunakan cara yang kedua, yang menggunakan JavaScript). Validasi dapat dilakukan secara client side dengan menggunakan JavaScript. Jadi, ketika pengguna menginputkan data yang tidak ada pada database (tidak ada pada suggestion autocomplete), maka proses tidak dapat dilanjutkan.

Langkah yang dilakukan adalah dengan menuliskan kode JavaScript berikut:

function pageLoad() {

$find('AutoCompleteEx')._onMethodComplete = function (result, context) {
$find('AutoCompleteEx')._update(context, result, false);
callback(result, context);

};
}

function callback(result, context) {
if (result == "")
$find("AutoCompleteEx").get_element().style.backgroundColor = "red";
else if (result[0].toLowerCase() == context.toLowerCase())
$find("AutoCompleteEx").get_element().style.backgroundColor = "yellow";
else
$find("AutoCompleteEx").get_element().style.backgroundColor = "green";
}

Arti dari fungsi diatas adalah akan memanggil AutoCompleteExtender dari Ajax Control Toolkit. Selanjutnya begitu pengguna mengetikkan ke TextBox maka warna TextBox juga akan berubah. Di kode tersebut saya menuliskan bahwa ketika pengguna mengetikkan karakter yang: (saya menyettingnya ignore case sensitive)
- mengandung suggestion akan berwarna hijau
- tidak mengandung suggestion akan berwarna merah
- sesuai dengan suggestion akan berwarna kuning

Dan sebagai tambahan, tambahkan attribute pada AutoCompteExtender dengan:

OnClientItemSelected="validasi"

yaitu akan memanggil fungsi JavaScript berikut:

function validasi(source, eventArgs) {
$find("AutoCompleteEx").get_element().style.backgroundColor = "yellow";
}




Setelah itu tinggal memberikan cek validasi input pada button yang akan mengirim nilai tersebut menggunakan OnClientClick.

<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="return cekvalidasi()" />

Dan akan memanggil fungsi JavaScript berikut:

function cekvalidasi() {
var cekwarna = $find("AutoCompleteEx").get_element().style.backgroundColor;
if (cekwarna == "yellow") {
alert("oke");
return true;
}
else {
alert("Masukan masih belum benar.");
return false;
}
}

Di dalam validasi tersebut akan mengecek jika warna TextBox tidak berwarna kuning maka proses tidak dapat diteruskan.



Kemudian, bagaimana jika pengguna, dari contoh kode diatas, tidak jadi menginputkan karakter dan beralih ke TextBox lain (jika ada situasi seperti itu)?

Maka, TextBox dapat dibuat kembali berwarna putih. Tetapi masalah yang ada adalah ketika fungsi callback tersebut hanya berfungsi ketika ada karakter yang dimasukkan. Artinya jika pengguna menghapus karakter terakhir ke tanpa isian, maka warna TextBox akan tetap seperti pada kondisi 1 karakter tersebut sebelum dihapus.

Terus bagaimana donk cara untuk membuat berwarna putih kembali? Langkah pemecahannya adalah dengan melakukan pengecekan langsung kepada TextBox seperti berikut:

<asp:TextBox runat="server" ID="myTextBox" Width="300" autocomplete="off" OnKeyUp="ceknull()" />

Kemudian fungsi JavaScriptnya adalah sebagai berikut:

function ceknull() {
var aaa = document.getElementById('<%=myTextBox.ClientID%>').value;
if (aaa == "") {
$find("AutoCompleteEx").get_element().style.backgroundColor = "white";
}
}

Seperti itu.....

Selanjutnya tinggal Anda untuk mengakalin cara untuk melakukan pewarnaaan TextBox biar tidak berwarna-warna seperti contoh diatas, misalnya saja warna diubah ke sedikit putih (dengan kombinasi RGB tentunya).

Dan.... Selamat berkreasi :-)

Reference:
- http://www.codeproject.com/Articles/8020/Auto-complete-Control
- http://www.dotnetcurry.com/ShowArticle.aspx?ID=515
- http://www.codeproject.com/Articles/201099/AutoComplete-With-DataBase-and-AjaxControlToolkit

No comments:

Post a Comment