jueves, 3 de julio de 2008

Web Control en Asp.Net

Bueno la idea es hacer un WebControl que se le añada un listado de opciones, y este las valla sugiriendo al escribir en el TextBox, algo asi como http://www.google.com/webhp?complete=1&hl=en
Pero muuuucho mas pedorro, sin web service ( para eso ver el ajax control toolkit http://www.asp.net/AJAX/AjaxControlToolkit/Samples/AutoComplete/AutoComplete.aspx)

Bueno en un proyecto distinto (seria lo ideal para reutilizar este)

Agregamos Carpeta al proyecto "WebControls"
y dentro otra "SuggestTextBox"


Agregamos una Clase que herede de textbox llamada "SuggestTextBox"




using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Web.UI.HtmlControls;
using System.Web;
using System.Collections.Generic;

namespace XFramework.Web.WebControls
{

/// <summary&gt;
/// Textbox con sugerencia al estilo http://www.google.com/webhp?complete=1&hl=en
/// </summary&gt;
public class SuggestTextBox: TextBox
{

}
}




le agregamos la propiedad



private List<string&gt; values;

/// <summary&gt;
/// Valores a Sugerir en la escritura de texto
/// </summary&gt;
public List< string> SuggestValues
{
get {
if (values == null)
{
values = new List<string&gt;();
}
return values; }
set { values = value; }
}

private ListBox lbox;

public ListBox LBox
{
get
{
if (lbox == null)
{
lbox = new ListBox();
}

lbox.Rows = SuggestSize;
lbox.DataSource = SuggestValues;
lbox.DataBind();
lbox.Width = this.Width;
lbox.Attributes.Add("onclick", "javascript:setSelectedText('M" + this.ClientID + "');");

return lbox;
}
set { lbox = value; }
}






sobre escribimos el metodo render




/// <summary&gt;
/// Renderiza el textbox y un div con posibles datos
/// </summary&gt;
protected override void Render(HtmlTextWriter writer) {

writer.AddAttribute("m", "M" + this.ClientID);
writer.RenderBeginTag("div");
writer.AddAttribute("onKeyUp", "javascript:showSuggest('M" + this.ClientID + "');");
base.Render(writer);

writer.RenderBeginTag("div");

LBox.Style.Add("display", "none");
LBox.RenderControl(writer);

//dummy
LBox.CssClass = "dummy";
LBox.RenderControl(writer);

writer.RenderEndTag();
writer.RenderEndTag();
}



-----------------------------------------------------------------------

dentro de la carpeta "SuggestTextBox"
agregamos la carpeta resources

y dentro agregamos un nuevo item javascript y otro css

suggestTextBox.css
suggestTextBox.js

------------------------------------------------------------------------

Nota: No importa si es la mejor manera de hacer esto (seguro no la mas prolija) pq tengo q terminarlo rápido, lo importante son los pasos para la creación de WebControl



suggestTextBox.css



div[m] select {
color:CornflowerBlue;
cursor:pointer;
padding :1px;
}

div[m] select option {
padding :5px;
}

div[m] select option:hover {
background-color:navy;
color:white;
font-weight:bold;
}

.dummy{
visibility:hidden;
display:none;
position:absolute;
}



------------------------------------------------------------------------

suggestTextBox.js



/*
Math. 03/07/2008
Requiere JQuery
*/

/*Setea el texto seleccionado en el select al textbox*/
function setSelectedText(mId){
var mTag = "div[m=" + mId +"]" ;

var txt = $$$(mTag +' input')[0];
var lb = $$$(mTag +' select')[0];
try{
txt.value = lb.value;
//lb.show("slow");
$$$(mTag +' select').hide("slow");
}
catch(e){}
}

var opciones;
/*Muestra y filtra el suggest*/
function showSuggest(mId){
var mTag = "div[m=" + mId +"]" ;

var txt = $$$(mTag +' input')[0];
var lb = $$$(mTag +' select')[0];
var dummys = $$$(mTag +' .dummy option') ;

var value = txt.value +'(.*?)' ;
var regex = new RegExp(value );

lb.options.length = 0;

//alert(value);
for ( indice = 0; indice < dummys.length; indice++)
{
if ( dummys[indice].value.match( regex )){
//$$$(opciones[indice]).hide();
lb.options.add( new Option(dummys[indice].value,dummys[indice].value ) , lb.options.length );
}
}

lb.value = txt.value;
$$$(mTag +' select').show("slow");
}


--------------------------------------------------------------

Ahora en el assembly.info (AssemblyInfo.cs)

agregamos



/* ******************** ******************** ******************** */
/* SuggestTextBox */
/* ******************** ******************** ******************** */
[assembly: WebResource("XFramework.Web.WebControls.SuggestTextBox.resources.suggestTextBox.js", "text/javascript")]
[assembly: WebResource("XFramework.Web.WebControls.SuggestTextBox.resources.suggestTextBox.css", "text/css")]



donde XFramework.Web.WebControls.SuggestTextBox.resources es las Carpetas relativas donde se encuentra el archivo. (OJO ES CASE SENSITIVE)

y asegurarse que ambos archivos tienen seteada la propiedad Build Action en : "Embedded Resource" Para esto se selecciona y se presiona F4.


--------------------------------------------------------------


Ahora el paso final es que cuando valla a renderizar agregue estos archivos al header


para esto sobreescribimos el onPreRender



/// <summary&gt;
/// agrega los js, css necesarios
/// </summary&gt;
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
HtmlLink linkExists = Page.Header.FindControl("xTxtLink") as HtmlLink;
if (linkExists == null)
{
HtmlLink hlLight = new HtmlLink();
hlLight.Href = getCssPath();
hlLight.ID = "xTxtLink";
hlLight.Attributes["text"] = "text/css";
hlLight.Attributes["rel"] = "stylesheet";
Page.Header.Controls.Add(hlLight);
}

if (!DesignMode)
{
if (!Page.ClientScript.IsClientScriptIncludeRegistered("suggestTextBox"))
ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "suggestTextBox", GetJScript());
}
}


private const string RESOURCEPATH = "XFramework.Web.WebControls.SuggestTextBox.resources.";

private string getCssPath()
{
return Page.ClientScript.GetWebResourceUrl(GetType(), RESOURCEPATH + "suggestTextBox.css");
}

private string GetJScript()
{
return Page.ClientScript.GetWebResourceUrl(GetType(), RESOURCEPATH + "suggestTextBox.js");
}


--------------------------------------------------------------------------


Probamos un sitio web y un form . agregamos las dependencias y



<%@ Register Assembly="XFramework.Web" Namespace="XFramework.Web.WebControls" TagPrefix="XWebControl" %>


and



<xwebcontrol:suggesttextbox id="miSuggestTxt" runat="server">
</xwebcontrol:suggesttextbox&gt;


y en el page load



List<string&gt; list = new List<string&gt;();
list.Add("pepe");
list.Add("asc");
list.Add("pesdfpe2");

list.Add("fdss");
miSuggestTxt.SuggestValues = list;
miSuggestTxt.Width = new Unit(200);

No hay comentarios.: