domingo, 27 de diciembre de 2009

Asp .Net: Wizard control y controles en el SideBar

Código para habilitar o deshabilitar uno de los links que aparecen en el
SideBar del control Wizard. Para que funcione en el DataList que aparece en el
SideBarTemplate hay que agregar manualmente el evento

OnItemDataBound="SideBarList_ItemDataBound"
Public Sub SideBarList_ItemDataBound(ByVal sender As Object, ByVal e As DataListItemEventArgs)
Dim dataitem As WizardStep = CType(e.Item.DataItem, WizardStep)
Dim lnkBtn As LinkButton = CType(e.Item.FindControl("SideBarButton"), LinkButton)
If Not dataitem Is Nothing Then

'Código que hace algo.

End If
End Sub

jueves, 24 de diciembre de 2009

MS-Word 2007: El cursor no se pude posicionar con el puntero del mouse.

Me ocurre que usando MS-Word 2007, después de escribir cierta cantidad de líneas de texto, decido corregir una palabra o comenzar a dar estilo a ciertas partes de un párrafo, sin embargo al querer seleccionar una parte del texto con el puntero del mouse, éste no funciona; es decir, no puedo ni posicionar el cursor con ayuda del puntero del mouse en el lugar que yo deseo, lo que tengo que hacer para poder llegar al texto, es usar las teclas de dirección, no obstante, es tedioso estar haciendo eso.

Luego de investigar un rato, encontré la solución para mi caso. Basta con desactivar un plugin el cual a ciencia cierta no puedo decir cuál es porque lo que yo hice fue desactivar todos los pluggines, jeje!, sin embargo en el siguiente link explican en detalle varias soluciones e inclusive explican como detectar cuál pluggin específico es el que está provocando el problema.

Adelanto que para hacer las correcciones, posiblemente va a requerir hacer una modificación en el registro de Windows.

viernes, 18 de diciembre de 2009

Asp .Net::Subir multiples archivos.

Referencias para subir múltiples archivos:

Videos

Video donde se explica en detalle como crear usar un FileUpload Control para poder subir varios videos.

Ejemplo #1
Ejemplo de un FileUpdaload múltiple.


Ejemplo #2

Otro ejemplo, pero éste está más claro y además se puede bajar el proyecto en Visual Studio.


Referencias:
Subida de los ficheros al servidor.
Subir un archivo tu servidor
Tamaños máximos de archivos
Atributos de httpRuntime

jueves, 3 de diciembre de 2009

Función Days360 en Vb.Net y C#

Código C#:
public static int CalculateDays360(DateTime d1, DateTime d2)
{
int years = d2.Year - d1.Year;
int months = d2.Month - d1.Month;

int dayNo1 = 0;
int dayNo2 = 0;

dayNo2 = d2.Day;
dayNo1 = d1.Day;

if (dayNo1 == 31) dayNo1 = 30;
if (dayNo2 == 31) dayNo2 = 30;

int days = dayNo2 - dayNo1;
return years * 360 + months * 30 + days;
}

Código VB.Net:

Public Shared Function CalculateDays360(ByVal d1 As DateTime, ByVal d2 As DateTime) As Integer
Dim years As Integer = d2.Year - d1.Year
Dim months As Integer = d2.Month - d1.Month

Dim dayNo1 As Integer = 0
Dim dayNo2 As Integer = 0
dayNo2 = d2.Day
dayNo1 = d1.Day
If (dayNo1 = 31) Then dayNo1 = 30
If (dayNo2 = 31) Then dayNo2 = 30
Dim days As Integer = dayNo2 - dayNo1
Return years * 360 + months * 30 + days
End Function

domingo, 29 de noviembre de 2009

ASP.NET: Supuestamente el control no existe!

Un caso extraño, que me tomo como una hora en resolverlo, para variar!

El problema consistía en que tenía una tabla con un ID cualquiera. En el momento de hacer referencia a ese control en el CodeBehind y después ejecutar el sitio en modo de depuración, aparecía un error indicando que la tabla no estaba declara. Sin embargo si estaba declarada ya que inclusive pude hacer referencia a la tabla desde CodeBehind.

¿Pero que provocaba ese problema?
El problema era provocado por una copia que había hecho de los mismo archivos (el archivo *.aspx y el archivo *.vb). Parece que VS 2008, supongo que en los anteriores sucede también, detecta que el control ya está declarado pero es para la página de la copia que tenía y supongo yo, que el control Table que tenía en la página original estaba siendo anulado de alguna forma; en fin, para solucionar el asunto fue simplemente borrando los archivos de las copias que tenía en el mismo lugar que los archivos originales.

domingo, 15 de noviembre de 2009

CSS: Mapa de Regiones con CSS

Necesitaba un ejemplo bien claro para crear mapas con CSS o por lo menos saber si se puede lograr el mismo efecto que se hace con el elemento <map> de html. Una fuente de ayuda la encontré en www.freshivore.net

domingo, 1 de noviembre de 2009

Asp.Net: Persistir el ViewState

El siguiente código hace que le viewstate se guarde en una variable de sessión en vez del lado del cliente.

Código para visual Basic:

Dim _pers As PageStatePersister
Protected Overrides ReadOnly Property PageStatePersister() As PageStatePersister
Get
If _pers Is Nothing Then
_pers = New SessionPageStatePersister(Me)
End If
Return _pers
End Get
End Property


Código C#:

PageStatePersister _pers;

protected override PageStatePersister PageStatePersister
{
get
{
if (_pers == null)
{
_pers =
new SessionPageStatePersister(this);
}
return _pers;
}
}


Referencia en www.telerik.com

Mas ayuda en http://geeks.ms

miércoles, 28 de octubre de 2009

¿Cuántos días, meses y años hay entre dos fechas?

Estuve intentando horas de horas con el problema de cómo hacer para obtener la cantidad de días, meses y años, sin importar el lenguaje de programación. Pues el algoritmo al final es simple y lo voy a explicar brevemente.

Supongamos que recibimos dos fechas donde fecha de inicio es 1/1/2004 y fecha final es 30/11/2005. El objetivo final es obtener la cantidad de años, meses y días, pero que sea exacto y esto quiere decir que hay que tomar en cuenta que no todos los meses son de 30 días y que no todos los años tienen 365 debido al año bisiesto.

La solución yo la resolví en VB .Net con la función DateAdd Lo primero es calcular los años. Para eso calculamos la cantida de días totales y la dividimos entre 360 y extraemos la parte absoluta con Math.Abs.

Viene lo más complicadillo y es calcular los meses y los días. Para ambos casos, el truco está siempre es hacerle una suma a la fecha de inicio para irnos acercando a la fecha final. Entonces para calcular los meses hay que sumar a la fecha de inicio la cantidad de años que ya teníamos calculado. Del resultado que obtengo saco los meses y se lo resto a los meses de la fecha final.

Ejemplo VB .Net:

totalMeses = Math.Abs(final.Month - DateAdd(DateInterval.Year, _anios, inicio).Month)

Para calcular los días, la lógica es la misma. Lo que hay que hacer es sumar todos los meses a la fecha de inicio. Esto quiere decir que la cantidad de años que tengo calculado, lo convierto en meses y lo sumo con la cantidad de meses que obtuve en totalMeses. De esa suma, el resultado se lo sumo a la fecha de inicio original. Como le estoy sumando todos los meses a la fecha de inicio, nos va a quedar una fecha que se acerca más a la fecha final.

Finalmente, entonces se deduce que hay que sacar la diferencia en días de la fecha final con la fecha que obtuve en el último paso.

Y bueno, dej esta entrada para recordarme a mí mismo como fue que resolví el algoritmo, jaja!

Para poder saber si los resultados andan bien, se puede usar el siguiente sitio en el cual tiene una pequeña aplicación que hace esos cálculos: www.timeanddate.com

martes, 20 de octubre de 2009

Asp.Net: Validator Controls

En ocasiones, el uso de los controles de validación se pueden volver un dolor de cabeza. Solo para mencionar una de las soluciones por la cual no se activan los validadores o el por qué por ejemplo el control CalendarExtender se comporta indevidamente mal, eso puede ser porque se está usando la propiedad SetFocusOnError. Con solo quitarla todo se puede solucionar.

jueves, 15 de octubre de 2009

PNG: Transparencias de PNG en IE6

Encontré un código perfecto para permitir transparencias en IE6. Es el primer código que veo que sí funcionan. El código que se puede guardar en un archivo *.js es el siguiente:
var arVersion = navigator.appVersion.split("MSIE")
var version = parseFloat(arVersion[1])
if ((version >= 5.5) && (document.body.filters))
{
for(var i=0; i<document.images.length; i++)
{
var img = document.images[i]
var imgName = img.src.toUpperCase()
if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
{
var imgID = (img.id) ? "id='" + img.id + "' " : ""
var imgClass = (img.className) ? "class='" + img.className + "' " : ""
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
var imgStyle = "display:inline-block;" + img.style.cssText
if (img.align == "left") imgStyle = "float:left;" + imgStyle
if (img.align == "right") imgStyle = "float:right;" + imgStyle
if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
var strNewHTML = "<span " + imgID + imgClass + imgTitle
+ " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
+ "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
img.outerHTML = strNewHTML
i = i-1
}
}
}

El enlace donde encontré éste código es: www.webmasterlibre.com

domingo, 11 de octubre de 2009

Asp.Net: Control CustomValidator.

Necesitaba saber cómo implementar una función de validación del lado del cliente para el control Custom Validator; la respuesta la encontré en Mundo Programación

sábado, 3 de octubre de 2009

Ajax .Net: ¿Por qué desaparece el ModalPopup al escoger un item en el DropDownList?

Cada vez que ocurre un PostBack o un AutoPostBack dentro de un ModalPopupExtender, éste se cierra. La solución más rápida es poner éste código en el Head para poder mantener el estado del ModalPopupExtender.

Nota: El control ModalPopupExtender debe tener El atributo BehaviorID con un valor cualquiera. Dicho valor se puede usar en el código JS para poder hacer referencia al mismo de una forma más rápida.

<script type="text/javascript">

var _estadoModal;
function pageLoad() {
$addHandler($get("btnSalir"), "click", OnSalir_Click);

var mpe = $find("mpe");
mpe.add_shown(OnShowModal);

if (_estadoModal)
mpe.show();
}

function OnShowModal(sender) {
_estadoModal = true;
}

function OnSalir_Click(sender) {
_estadoModal = false;
}

</script>

Si en la variable "_estadoModal" está el valor true, entonces
se vuelve a ordenar que el ModalPopup se muestre. Esto hace
que le caiga encima a la instancia anterior que en realidad
ya esta muerta; lo que pasa es que el updatePanel no se a
refrescado y por eso parece que el ModalPopup nunca desapareció
de la pantalla, el efecto es rápido y parece que el Modalpopup
no se cierra.

Si en la variable "_estadoModal" está el valor "false",
entonces el ModalPopup desaparece ya que el Postback hace que
se cierre el ModalPopup y por ende el UpdatePanel se refresca
borrando la imagen del ModalPopup que se estaba mostrando.

NOTA: CUALQUIER OBJETO QUE HAGA UN POSTBACK O UN
AUTOPOSTBACK PROVOCAN QUE EL MODALPOPUPEXTENDER
SE CIERRE DE INMEDIATO. SIENDO MÁS ESPECÍFICOS,
EL MODALPOPUPEXTENDER SE CIERRA PORQUE ESTE
CONTROL NO MANTIENE SU ESTADO EN EL LADO DEL
CLIENTE DESPUÉS DE CADA POSTBACK O AUTOPOSTBACK.

Descargar ejemplo

Ajax .Net: ¿Por qué el TabContainer no aparece?

Puse el TabContainer y al ejecutar el sitio resulta que no se ve el TabContainer.

Solución: El problema es porque estaba agregando el TabContainer ¡a pata!, y olvidé ponerle a cada TabPanel el atributo runat="server". ¡jeje!

viernes, 2 de octubre de 2009

Ajax.Net: Soluciones a problemas de Ajax.

En el siguiente sitio se explican varias soluciones a problemas que podemos encontrar al trabajar con Ajax.net: ver sitio

Por ejemplo, en ese sitio encontré la solución para usar saber cómo mantener el ModalPopupExtender activo después de que ocurra un postback.

Más detalles del framework en http://www.asp.net/AJAX/Documentation/Live/Overview/default.aspx. En éste sitio está todo lo que se necesita para dominar Ajax .Net.

miércoles, 23 de septiembre de 2009

Ajax .Net: ModalPopup y el control DropDownList.

¿Por qué al escoger un item de un DropDownList que está en un ModalPopupExtender, del lado del servidor siempre me devuelve el index del primer item?

Solución: Esto me estaba ocurriendo porque en el evento Page_Load existe un código para llenar el DropDownList, entonces cada vez que se escogía un item y se daba clic en el botón "Guardar" que esta también en el ModalPopup, sucedía que el ciclo de vida de la página pasaba otra vez por el evento Page_Load (lo cual es obvio) y por eso en otro método que tenía, siempre iba a recoger el mismo valor. La solución fue poner una variable de Sessión antes de que el DropDownList se vuelva a llenar.

martes, 15 de septiembre de 2009

Asp.Net: Recuperar ID de fila en GridView a partir de DataKeys

Recuperar el ID de una fila en GridView a partir de la propiedad DataKeys:

key = Convert.ToString(this.grid.DataKeys[this.grid.SelectedIndex].Value);

En la variable key queda un valor que representa el ID del registro. En el GridView se tuvo que haber definido mínimo un valor para la propiedad DataKeyNames. En caso de haber definido más de un DataKeyName, para poder recuperarlo sería de la siguiente forma:

key = Ctype(grid.DataKeys(gris.SelectedIndex).Item(1)

La propiedad Item(1) escoge el segundo Código de la colección DataKeyNames suponiendo que tenemos una clave primaria formada con dos campos.

La ventaja de esto es que podemos poner un columna oculta pero en el DataSource del GridView existe un Select que está recuperando esos valores de las columnas.

Ajax.Net: Más problemas con controles Ajax.Net

1º Tengo un ModalPopupExtender, el problema es que al hacer clic a un botón que está dentro del ModalPopup, éste hace que el modal desaparezca.

Eso ocurre, porque cualquier botón, textbox, etc, que haga Postback, ya sea porque tiene la propiedad AutoPostBack en True o porque se lanza el evento PostBack desde código Javascript, tendremos como resultado que el ModalPopup termine su función. El control ModalPopup está programado para que se cierre cuando ocurra un PostBack dentro de éste.

Solución: La solución es usar Web Services. De hecho esta es la forma que se debería utilizar para actualizar controles dentro de un ModalPopup. Además hay que usar un evento de control HTML para que del lado del servidor llame al WebService. Generalmente se usa el evento onblur el cual equivale a TextChanged de un TextBox, suponiendo que el caso es un TextBox, para otros controles se podría usar el evento onchange.

2º No funcionan los validadores en un ModalPopup.

Solución: Tanto los validadores como los controles que validan deben estar dentro de un ValidationGroup.

3º Mostrar ModalPopup programáticamente.

Exite un problema con éste control ya que la propiedad TargetControlID no puede estar vacía. El truco está en asignarle un control HTML del tipo Hidden y que tenga la propiedad runat="server". Luego, con ayuda de otro botón, se puede poner en code behind el código para mostrar al ModalPopup.

Ejemplo:
ModalPopupExtender1.Show()

La ventaja es que si estamos creando un modal con cuadros de texto dentro, éstos se pueden inicializar con el valor que queramos antes de que el modal aparezca.

Ajax: Recuperar el ID de un control Web Server

En ocasiones hay que recuperar el ID de un control en Ajax.Net. en el código Javascript. Podemos usar el objeto getElementById, el objeto $get, $find, pero que ocurre si el objeto está en un ContentPlaceHolder. Si esto ocurre, el control en la página web toma un nombre de ID diferente; el nombre se complementa y para poner un ejemplo podría ser éste: ctl00_ContentPlaceHolder1_Button1

Para recuperar el ID exacto y poder usarlo correctamente, se puede usar la instrucción:
<%= expresion %>, donde expresion se cambia por el nombre del control que le asignamos del lado del servidor seguido de la propiedad ControlID.

function fnTxt() {
var obj = $get('<%= TextBox1.ClientID %>');
...
}

Ajax: Lanzar un PostBack

Ejemplo para ejecutar un evento postback desde javascript usando el Ajax Framework:

function postbackFromJS(sender, e) {
var postBack = new Sys.WebForms.PostBackAction();
postBack.set_target(sender);   
postBack.set_eventArgument(e);
postBack.performAction();
}

CSS: Comprimir archivos CSS rápidamente en Visual Studio

Es relativamente sencillo, solo hay que descargar el ejecutable "YUI Compressor". Descomprimimos el archivo en un directorio que preferiblemente debemos crear. Luego vamos a Visual Studio y en: Herramientas -> Herramientas Externas ponemos:

Título: YUI Compression
Comando: C:\WINDOWS\system32\java.exe
Argumentos: -jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemPath) –v

Argumentos para comprimir CSS con copia sin tener que reemplazar el original:

-jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemDir)$(ItemFileName).min$(ItemExt) –v


Argumentos para comprimir JS:

-jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemPath) –v --charset utf-8

Argumentos para comprimir JS con copia sin reemplazar el original:

-jar C:\Compresor\yuicompressor-2.4.2.jar $(ItemPath) -o $(ItemDir)$(ItemFileName).min$(ItemExt) –v --charset utf-8

Nota: Después de comprimir un archivo CSS sería bueno quitar el punto y coma que siempre se pone al final de cada regla de las clases o selectores. El punto y coma en la última regla es opcional. Para quitarlo rápidamente ese punto y coma, simplemente hay que hacer un "Replace" de la siguiente combinación de caracteres:

;) (punto y coma con paréntesis)

Luego aceptamos el cuadro de diálogo y listo. Para hacer la prueba, abrimos un archivo CSS en Visual Studio, y luego vamos a Herramientas -> YUI Compression. El resultado será que todas las reglas de CSS se comprimen al máximo; es decir, desaparecen espacios, cambios de línea innecesarios y todo al final queda en una sola línea o más líneas dependiendo de la cantidad de CSS que tenga el archivo. Pero definitivamente lo comprime.

Está de sobra decir, pero para los novatines, les comento que hay que tener java instalado.

Por cierto, ¿saben cómo restaurar el código CSS a su estado original? Yo si sé, jaja!, solo hay que presionar la siguiente combinación de teclas: Ctrl + K + D. Dependiendo de los settings que tengan su Visual Studio, esa combinación de teclas puede ser diferente, por eso, en caso de que no funcione verifiquen en el menú Editar -> Opciones Avanzadas.

Y para mayor detalle una demostración de tantas que existen en YouTube:


También está éste link: Ver

Yui compressor online:Ver

domingo, 13 de septiembre de 2009

GridView: Eliminar múltiples registros.

Referencias:

csharpdotnetfreak.blogspot.com

GridView: Problemas con el GridView?

¿No aparece el paging?
Puede ser porque el PageSize tiene un valor superior para el GridView. Revisar la propiedad PageSize en el cuadro de propiedades.

¿No hace Paging cuando cambia valor en el DropDownList que se coloca en el PagingTemplate?
Activar la propiedad AutoPostBack del DropDownList.

¿El PageTemplate desaparece cuando PageSize es mayor que la cantidad de registros real que se pueden imprimir en el GridView?
En el evento DataBound del GridView poner lo siguiente:
grid.BottomPagerRow.Visible = True

¿La fila a la que se le hizo clic en un GridView, no queda seleccionada?
Puede ser por varias cosas:
1º Se está usando themes pero no se indicó en la directiva Page o en el archivo de configuración.

2º Si no se está usando Themes, entonces puede ser porque la hoja de estilos no se asoció al archivo o porque no se configuró la propiedad SelectedRowStyle del GridView.

3º La fila no tiene el evento onclick y por eso no ocurre el postback.

4º Puede ser que tenga el evento onclick pero el atributo EnableEventValidation está en true (predeterminado) y debería estar en False.

¿Un PageMethod asociado con el Grid no se ejecuta?
La propiedad EnablePageMethods del ScripManager está en False y debería ser True.

viernes, 4 de septiembre de 2009

Asp.Net: Limpiar por completo el VIEWSTATE

Para poder limpiar el viewstate por completo hay que sobre escribir el método SavePageStateToPersistenceMedium y el método LoadPageStateFromPersistenceMedium.

En C# se puede hacer de esta forma:

protected override object LoadPageStateFromPersistenceMedium()
{
return Session["ViewState"];
}

protected override void SavePageStateToPersistenceMedium(object viewState)
{
Session[
"ViewState"] = viewState;
RegisterHiddenField("__VIEWSTATE", "");
}

En Visual Basic .Net:

Protected Overloads Overrides Sub SavePageStateToPersistenceMedium(ByVal viewState As Object)
Page.ClientScript.RegisterHiddenField("__VIEWSTATE", "")
End Sub

Protected Overloads Overrides Function LoadPageStateFromPersistenceMedium() As Object
Return Session("ViewState")
End Function


Referencias:
www.carloszanini.com.ar

www.tek-tips.com

www.listhosting.net

Todo sobre ViewState

How to fine tune your asp net 2.0 app - Part 2

Comprimir el ViewState

La clase LosFormatter

jueves, 3 de septiembre de 2009

Windows Vista: ¿Que está haciendo éste hombre con Windows Vista?

Yo no tengo Windows Vista y me gustaría comprarlo más adelante sin embargo he escuchado durante varios meses que Windows Vista ¡nada que ver!; no me he tomado la molestia de bajar un versión de prueba pero me he puesto a leer algo al respecto. Y entre lectura y lectura encontré un video que demuestra la reacción de una persona que en definitiva no le gusto Windows Vista.



Este video tan cómico lo encontré en www.securitytube.net

CSS: Resetear CSS en todos los navegadores.

En meyerweb.com encontré unas cuantas reglas de CSS que permiten resetear los CSS predeterminados que vienen en los navegadores. Vale la pena probarlo.

El código es el siguiente:
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
body {
line-height: 1;
color: black;
background: white;
}
ol, ul {
list-style: none;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: separate;
border-spacing: 0;
}
caption, th, td {
text-align: left;
font-weight: normal;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: "";
}
blockquote, q {
quotes: "" "";
}

miércoles, 2 de septiembre de 2009

Asp.Net: ModalPopupExtender y evento onclick

Estaba implementando el control ModalPopupExtender pero quería que al presionar el botón que establecí para el atributo OkControlID, hiciera una tarea específica, por ejemplo, que actualice la propiedad Text de un Label. (El atributo CancelControlID también esta presente en el control ModalPopupExtender).

Ya existía del lado del servidor un código que se debía ejecutar cuando hago clic en dicho botón. El problema es que no se estaba ejecutando ese código. El código XHTML para el modalpopup es el que se muestra a continuación:


<div id="modalMsg" style="border: 0.01em dotted brown; display: none; width: 320px; height: 80px;">
<span style="font-weight: bold; margin-bottom: 20px;">¿Seguro que desea eliminar el
registro?</span>
<div>
<asp:button id="btnSi" runat="server" text="Sí" onclick="Msg()">
<asp:button id="btnNo" runat="server" text="No">
</asp:button></asp:button></div>
</div>

También se observan los botones btnSi y btnNo. Veamos que el atributo onclick está presente. Lo puse para ejecutar en el lado del cliente una simple función de ejemplo.

Para empezar, el atributo onclick en un botón del lado del servidor, no es compatible con controles del tipo "Web Serve Control". Lo que se debe usar es el atributo OnClientClick.
Si fuera un botón Html si funcionaría. Si yo dejo el onclick aparecerá un error indicando que la función Msg() no es parte del archivo ASP.default_aspx'. Por lo tanto, en vez de onclick hay que usar OnClientClick.

Pero aun queda el problema de que no se está ejecutando el método del lado del servidor. El código para el botón btnSi es el siguiente:
Protected Sub btnSi_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSi.Click
lblResultado.Text = "Hizo clic en el botón 'Sí'"
End Sub
El objetivo es que ese método del lado del servidor se ejecute sin problemas; es evidente que al usar ModalPopupExtender, dicha funcionalidad se pierde.

La solución es usar el atributo OnClientClick más una función que ejecute el método __doPostBack:
<div id="modalMsg" style="border: 0.01em dotted brown; display: none; width: 320px; height: 80px;">
<span style="font-weight: bold; margin-bottom: 20px;">¿Seguro que desea eliminar el
registro?</span>
<div>
<asp:button id="btnSi" runat="server" text="Sí" onclientclick="server('btnSi')">
<asp:button id="btnNo" runat="server" text="No" onclientclick="server('btnNo')">
</asp:button></asp:button></div>
</div>

<script type="text/javascript">
function server(arg) 
{
 __doPostBack(arg, '');
}
</script>

No obstante existe otra solución. Ya dijimos que los atributos OkControlID y CancelControlID se están utilizando. La segunda solución sería eliminar esos atributos del todo y listo, no es necesario hacer nada más.

En caso de que el Label este dentro de un control UpdatePanel, se debe registrar en el evento Page_Load el botón btnSi con:

ScriptManager1.RegisterAsyncPostBackControl(btnSi)

Eso hará que el Label se actualice asíncronamente si tener que refrescar toda la página. Un equivalente es registrar un Trigger para el botón dentrol del UpdatePanel.

Referencias:
Asp.Net Ajax

martes, 1 de septiembre de 2009

Ado.Net: Códigos valiosos.

ConfigurationManager
Dim cnn As New SqlConnection(ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString)
Response.Write(cnn.ConnectionString)

ConfigurationManager
System.Configuration.ConfigurationSettings.AppSettings["connstr"].ToString();

ConfigurationManager
ConfigurationManager.GetSection("prodSection")

ConfigurationManager
ConfigurationManager.GetWebAppSection("prodSection")

Agregar atributo a una fila de un GridView en Asp.Net:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='Silver'");
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='White'");
}
}

Insertar código JS:

Dim script As New StringBuilder
script.Append("")
Page.ClientScript.RegisterClientScriptBlock(Me.GetType, "MyScript", script.ToString)

Filtrar items que se van insertando en un Repeater control de Asp.Net:


Protected Sub Repeater1_ItemCreated(ByVal sender As Object,
ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater1.ItemCreated
Dim nav As XPathNavigator = CType(e.Item.DataItem, IXPathNavigable).CreateNavigator

For Each o As Object In e.Item.Controls
If TypeOf o Is HtmlAnchor Then
Dim pagina As String = nav.Select("/Titulos/Titulo").Current.SelectSingleNode("pagina").Value
If pagina = "Cursos" Then
If User.Identity.IsAuthenticated Then
Dim archivo As String = nav.Select("/Titulos/Titulo").Current.SelectSingleNode("archivo").Value

o.Attributes.Add("href", "media/images/" + archivo)
o.Attributes.Add("rel", "lightbox[roadtrip]")

Else
o.Attributes.Add("href", "/")
o.Attributes.Add("class", "verModal")
End If
Else
e.Item.Visible = False
End If
End If
Next
End Sub

CSS: Hoja estilo para maquetación básica.

Este es el CSS para maquetar una página con encabezado, tres columnas y un pie de página.

*
{
border: 0;
margin: 0;
}

body
{
font-family: Georgia,Arial, Helvetica, sans-serif;
font-size: medium;
}

/* Si el ancho cambia, hay que reajustar los porcentajes de
la columna central. */
.container
{
width: 800px;
margin: 0 auto;
border:0.01em dotted blue;
}

.header
{
width: 100%;
height: 120px;
background-color: Aqua;
border:0.01em dotted blue;
clear:both;
}

.leftColumn
{
width: 24%;
min-height: 400px;
border:0.01em dotted blue;
float:left;
}

.mainColumn
{
width: 51.2%; /* Ajustar si ancho de Container cambia. */
border:0.01em dotted blue;
min-height: 400px;
float:left;
}

.rightColumn
{
width: 24%;
border:0.01em dotted blue;
min-height: 400px;
float:right;
}

.footer
{
width:100%;
height:50px;
}

#separador
{
clear:both;
}

La estructura básica sería:

<div class="container">
<div class="header">
</div>
<div class="leftColumn">
</div>
<div class="mainColumn">
</div>
<div class="rightColumn">
</div>
<div id="separador">
</div>
<div class="footer">
</div>
</div>

CSS: Menú con CSS

Un ejemplo sencillo de menú horizontal o vertical lo podemos encontrar en www.cssblog.es

Otras referencias:

El iguiente link es interesante, presenta una lista de menus listos para descargar y lo mejor de todo es que se pueden modificar antes de descargarlos. El enlace es www.cssmenumaker.com

Para rematar, jeje! encontré en un blog que presenta una gran lista de sitios que hablan sobre creación de menus con CSS. El sitio es blogvecindad.com

lunes, 31 de agosto de 2009

Drupal: Insertar código Javascript desde archivo template.php

Ejemplo rápido sobre como insertar código JS desde el archivo template.php:

function bluemarine_preprocess_page(&$vars, $hook) {
if ($hook == 'page')
{
drupal_add_js('alert("Hola");','inline');
$vars['scripts'] = drupal_get_js();
}
}

Notar la definición del encabezado de la función que consiste en:

function NombreTheme_preprocess_page(&$vars, $hook) {...}

En la función drupal_add_js el segundo parámetro es 'inline' para indicar que el código que se va a insertar es código que no procede de un archivo externo.

viernes, 28 de agosto de 2009

Drupal: Reescribir una URL con código PHP

Para poder reescribir la URL de un enlace, se puede usar la función "custom_url_rewrite_outbound". Por ejemplo, supongamos que tenemos un catálogo generado por el Ubercart. Cada elemento del catálogo muestra una imágen y un título, cada grupo de imágen y título tienen el mismo URL, el cual lleva al usuario a una página general donde se muestran todos los items relacionados con el nombre de catálogo al cual se le hizo clic.

El problema sería ¿cómo puedo hacer para que después de hacer clic en uno de los items que muestra el catálogo, muestre más bien, el resultado de una Vista u otra página que nosotros queramos?

La solución más rápida que encontré es agregando en el archivo settings.php la función llamada "custom_url_rewrite_outbound". Con ésta función es posible reescribir la url de cualquier enlace que exista en la aplicación Drupal que estemos creando.

El código de ejemplo es:

function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
if (preg_match('|^catalog/(.*)|', $path, $matches)) {
preg_match('/[0-9]+$/', $path, $matches);
switch ($matches[0])
{
case '3':
$path = drupal_get_path_alias('catalogo-alicates');
break;
case '4':
$path = drupal_get_path_alias('catalogo-lijas');
break;
case '5':
$path = drupal_get_path_alias('catalogo-martillos');
break;
}
}
}

Notar que en el primer preg_match: preg_match('|^catalog/(.*)|', $path, $matches), usamos una expresión regular para filtrar la url que queramos analizar. En mi caso la URL original es de la forma:

http://www.dominio.com/catalog/5

Lo que está en color rojo, es lo que deseo cambiar por

http://www.dominio.com/catalogo-martillos

Dependiendo del número que aparezca en la URL, se establece el alias. Esos alias que estoy usando son páginas que apuntan a Vistas de Drupal previamente creadas.

En realidad, la cosa es más compleja, pues estoy usando taxonomía; cada elemento del catálogo es un término taxonómico. En el índice de términos se observa la relación que existe entre el nombre que le dimos al término y la url que se le asignó automáticamente.

Referencias:
http://drupal.org/node/207330
http://drupal.org/node/243889
http://agaric.com/note/override-taxonomy
regular_expressions

miércoles, 26 de agosto de 2009

Archivos CHM no funcionan.

Descargué un archivo con formato *.chm. El problema es que no podía verlo, ¿por qué?

La respuesta se explica en esta página: Chm Files

Brevemente, para poder ver el archivo, hay que ir a las propiedades del archivo y notaremos que existe un botón que dice "Unblock". Hay que hacer clic en dicho botón y listo!

martes, 18 de agosto de 2009

Drupal: Corregir imágenes transparentes en IE5, IE6

Excelente módulo para corregir transparencias que en IE5 ó IE6 definitivamente son un caso especial. El módulo está en www.jwpctips.com

Lo único que hay que hacer es instalar el módulo, luego en el archivo page.tpl.php buscamos la imágen que queremos corregir. Dicha imágen la encerramos con un bloque DIV de la forma:

<div class="pngfix">
<img .......>
</div>

Alternativa dos: Enlace relacionado

Alternativa 3:
Otra alternativa que en lo personal, me gusta mucho es ni más ni menos que evitar de una vez por todas el uso de versiones inferiores a IE7. En lo personal creo que los navegadores web de Microsoft definitivamente llevan la contraria a lo que es CSS, de hecho es el único, que yo sepa!, que no respeta las normas de CSS establecidas por la W3C. Una forma para indicarle al usuario que se actualice es usando ie6-upgrade-warning de lo contrario inventarse un código para que detecte en que navegador se va a presentar la información y de esa forma impedir la carga del sitio o mostrar un mensaje de advertencia indicando que el sitio no se puede ver correctamente en versiones IE6 e inferiores.

martes, 11 de agosto de 2009

Asp.Net: Código para descargar un archivo.

Código para descargar un archivo:

JQuery: Establecer colores en líneas alternas de una tabla.

En el siguiente trozo de código se muestra como utilizando JQuery es posible cambiar el color de las líneas de una tabla pero en forma alterna:

$(document).ready(function()
{
    $('tr:odd').addClass('odd');
    $('tr:even').addClass('even');
}

viernes, 7 de agosto de 2009

martes, 4 de agosto de 2009

lunes, 3 de agosto de 2009

Asp .Net Ajax: Control Modal PopUp

Código xhtml:

Agregar el control ModalPopUpExtender manualmente para que se inserte la instrucción @Resgister.



No se ocupa programar nada en el codebehind pero lo que si sería necesario es crear unas buenas reglas CSS para personalizar el Panel.

Asp.Net Ajax: Usar control PopupExtender

Código que va en la página aspx:


Código que va en el CodeBehind:

Asp .Net: Proyectos libre descarga hechos en Asp.Net

En las páginas de Asp.Net Ajax encontré un enlace que nos lleva a una sección de descarga de Starter Kits y entre ellos podemos encontrar un Shopping Cart y un Report Web Site ya hechos; pero obviamente son bien básicos.

El enlace para ir a la página es el siguiente: Starter Kits

Ajax .Net: Actualizar un UpdatePanel con código Javascript

Digamos que tengo dentro de un UpdatePanel la hora que se recupera del lado del servidor y no de la computadora del cliente y se desea que la hora se actualice cada segundo del lado del cliente; éste siempre debe ver la hora del servidor.

El primer paso es modificar el evento Load del UpdatePanel; en éste control debemos poner el código para que la hora que aparece en un label se actualice cada vez que ocurre un postback asíncrono.

Protected Sub UpdatePanel1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles UpdatePanel1.Load
Label1.Text = DateTime.Now
End Sub

El siguiente paso es usar el siguiente código Javascript:

<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
setTimeout("Actualizar()", 1000);
function Actualizar() {
prm._doPostBack("UpdatePanel1", "");
setTimeout("Actualizar()", 1000);
}
</script>

Obviamente, con éste ejemplo se pueden implementar muchas otras cosas!.

En caso de no querer implementar la función actualizar, entonces se podría usar el control Timer. En el evento Tick se pone el código para que actualice el contenido del Lable1. Y en el UpdatePanel se agrega un Trigger que haga referencia al control Timer y al evento Tick.

domingo, 2 de agosto de 2009

Asp .Net: Ajax y consumo de WebServices con Javascript

Buscando una explicación sobre que scripts se carga cuando agrego un control ScriptManager a un proyecto Asp.Net, encontré un interesante sitio donde explican muy claro como trabajar con Javascript y los WebServices. Está muy bien explicado y al mismo tiempo esta resumido, no se anda con rodeos; el sitio es TecBlog.

El sitio donde explican más o menos cómo usar el framework de Asp.Net Ajax está en CideSoft

viernes, 31 de julio de 2009

Web Service: ¿Service1 is not define?

Hice un web service que permite comunicar código javascript con un método que existe en el web service, éste se ejecuta en forma asíncrona. En el código javascript está el siguiente código de ejemplo:

function btnEnviar_onclick() {
var resultado = Service1.HelloWorld(document.getElementById("txtNombre").value,
OnComplete, OnTimeOut, OnError);
return true;
}

function OnComplete(arg) {
alert(arg);
}

function OnTimeOut() {
alert("Time is up");
}

function OnError() {
alert("Error");
}

El problema es que estoy consiguiendo el error "Service1 is not define". Existe cinco cosas importantes que hay que tomar en cuenta:

1º - El web service debe estar corriendo, ¡obvio!
2º - El nombre del directorio donde está el web service debe ser utilizado en el momento de instanciar o llamar a un método del web service.
3º - Por supuesto, también es importante agregar el control ScripManager a la página *.aspx y dentro de ese control agregar un ServiceReference.
4º Si aun no aparece, entonces revizar el código Javascript y verificar que los nombres de los métodos OnComplete, OnTimeOut y OnError estén bien escritos en todo lado donde se vayan a usar. Recordemos que Javascript es sencible a mayúsculas y minúsculas.
5º Si se están usando WebService estáticos, el método debe ser declarado con la palabra reservada Shared (VB) o static (C#).
6º Puede ocurrir que el web service es llamado pero se lanza una excepción indicando que no encuentra al web service y por más que intente hacerlo funcionar, no ocurre. Un caso así ocurrió cuando se ejecutaba una aplicación en una máquina virtual. La solución fue simplemente reiniciar la máquina virtual. Sí por supuesto, dicha solición se aplicó casí después de tres horas después de tantos intentos infructuosos, jaja!

7º Existe un caso especial, pero ocurre solo si utilizamos Web Services Estáticos.El mensaje de error equivalente con el que podemos toparnos es el siguiente:
   Error: Sys.Net.WebServiceFailedException: The server 
   method 'StaticMethod' failed with the following error: 
   Archivo de origen: http://localhost:10258/WebSite2
   /ScriptResource.axd?d=58xHtP0kV6y42p9jtK_IzqsHQXnRb-
   2ldpNeZlGfSlZEESQ9GeHLihiyxiP1&t=d2c0a1c Línea: 5488

Eso es por una única razón. Se produce si un botón que se 
supone llama a una función de JS y la función de JS llama 
a una función stática en el lado del servidor, es muy 
probable que la función sí se pueda ejecutar (la del lado 
del servidor) pero la respuesta de retorno va a fallar ya 
que el botón hace postback haciendo que el otro mensaje 
que se había enviado, falle totalemente.
Y continuando con la solución para el problema anterior del Web Service, lo que hay que hacer es llamar al web service utilizando el nombre del directorio seguido del nombre de la clase web service separado con punto quedando ahora:

var resultado = SimpleWebService.Service1.HelloWorld.....;

Otro punto importante es que debe existir la siguiente línea de código en el encabezado
de la clase:

<System.Web.Script.Services.ScriptService()> _

miércoles, 22 de julio de 2009

Javascript: Los 10 frameworks más populares.

Resumen de los diez mejores frameworks hechos con Javascript en ajaxline.com

Frases acerca de software y programación

Esta buena ésta lista de frases que encontré en Web Intenta:

  • La simplicidad es requisito previo para la fiabilidad. (Dijkstra)
  • No debes dar al mundo lo que pide, pero sí lo que necesita. (Dijkstra)
  • Si un oyente asiente con la cabeza cuando estás explicando tu programa, despiértale. (Perlis)
  • No tengas buenas ideas si no estás dispuesto a responsabilizarte de las mismas. (Perlis)
  • Optimización prematura es la fuente de todo mal -o al menos la mayor parte- en la programación. (Knuth)
  • Hablar es barato. Muéstrame el código. (Torvalds)
  • Sólo podemos vislumbrar un corto período hacia el futuro, pero podemos ver que hay muchas cosas por hacer. (Turing)
  • Hay muchas preguntas que los tontos pueden hacer y que los sabios no pueden responder. (Polya)
  • Daría mi brazo derecho a ser ambidiestro. (Kernighan)
  • UNIX es básicamente un sistema operativo sencillo, pero tienes que ser un genio para entender su simplicidad. (Ritchie)
  • A veces la manera más fácil de conseguir algo es ser un poco ingenuo al respecto. (Joy)
  • El software es un gas, se expande hasta llenar su recipiente. (Myhrvold)
  • Se requiere una mente muy inusual para llevar a cabo el análisis de lo obvio. (Whitehead)
  • Todas las verdades son fáciles de entender una vez que se descubren, la cuestión es descubrirlas. (Galilei)
  • No hay nada más despreciable en el campo de la programación que un programa no documentado. (Yourdan)
  • El control de la complejidad es la esencia de la programación. (Kernighan)
  • Es mejor tener 100 funciones que operan sobre una estructura de datos, que 10 funciones que operan sobre 10 estructuras de datos. (Perlis)
  • La mejor manera de predecir el futuro es inventarlo. (Kay)
  • Un ejemplo no es otra manera de enseñar, es la única manera de enseñar. (Einstein)
  • Cada programa es una parte de algún otro programa y rara vez se ajustan. (Perlis)

MySql: HeidiSQL, un gestor gráfico más.


HeidiSql es un interfaz gráfico para administrar MySQL. Permite navegar y gestionar las bases de datos MySQL de una forma intuitiva y con un interfaz Windows. El programa es gratuito.

Con un tamaño de descarga inferior a los 2Mb y de ejecución rápida y liviana, otras de sus características principales son:

- Generación de exportaciones SQL.
- Sincronización de tablas entre bases de datos.
- Gestión de privilegios de usuario.
- Importación de archivos de texto.
- Exportación de datos a formatos CSV, HTML y XML.
- Navegación y edición de los datos de las tablas en una "confortable" grid.
- Procesos de inserción batch y ficheros binarios dentro de las tablas.
- Escritura de consultas con un resaltado de sintaxis personalizado y con autocompletado.
- Monitorización y eliminación de procesos de cliente.


martes, 14 de julio de 2009

Asp.Net: Validar páginas en CSS Validation Service

En el pie de página de un sitio que estaba haciendo, quise poner un link que diga Validar CSS, implica que al dar clic debería cargar el servicio de validación de CSS que ofrece W3C, pero éste debería mostrame si la página actual que tenía abierta esta conforme a las reglas de CSS.

Analizando un poco la situación vi que la URL para llamar al servicio es:

http://jigsaw.w3.org/css-validator/validator?uri=URL

Donde URL es donde debemos poner la URL de nuestra página. Entonces muy fácil, solo tengo que poner en código una sentencia que me devuelva la URL de la página web en la que estoy navengando. Para obtener la dirección de un recurso específico del sitio web (URI) se puede usar la función Page.Request.Url.AbsoluteUri.

Finalmente todo el link para mandar a validar la página me quedó de la siguiente manera:

<a href="http://jigsaw.w3.org/css-validator/validator?uri=<% Response.Write(Page.Request.Url.AbsoluteUri) %>">Validar CSS</a>

domingo, 12 de julio de 2009

Drupal: Problemas con APC

Desde que instalé Ubercart y Delve en el informe de estado del sistema de Drupal me aparecen tres advertencias que dicen lo siguiente:

Performance logging APC.
Performance logging on live web sites works best if APC is enabled.

Performance logging APC memory size.
APC has been configured for , which is less than the recommended 48 MB of memory. If you encounter errors when viewing the summary report, then try to increase that limit for APC.

Performance logging details
Performance detailed logging is enabled. This can cause severe issues on live sites.

Esto se debe a que yo había activado el módulo llamado Performance logging details y por eso estaba recibiendo dichas advertencias. Basándome en soluciones encontradas en diferentes foros se dice que tengo que activar un módulo en el archivo php.ini. El módulo es php_apc.dll (se activa quitando el punto y coma que lo precede) además hay que agregar una línea de código al final del mismo archivo; la línea de código es la siguiente:

apc.shm_size = 64

Luego reinicie el servidor Apache y efectivamente las advertencias dejaron de aparecer. El detallazo es que me comenzó a salir un cuadro de diálogo avisando sobre un error en el servidor Apache. En otras palabras arreglé una cosa pero se daño el sistema por otro lado.

Finalmente, llegué a una conclusión efectiva. Como a mi no me gusta ver esas advertencias llegué a la conclusión de desactivar el módulo
Performance logging details, de por sí, ni me interesaba, jaja!

viernes, 10 de julio de 2009

Web: Que buen sitio

Encontré un sitio que vale la pena recordar ya que en él se habla de todo un poco sobre diseño, herramientas de desarrollo, etc. Está muy completo y lo recomiendo.

El sitio es www.baluart.net

sábado, 4 de julio de 2009

Asp.Net: Referenciar un objeto de un CreateUserWizard object

En caso de querer modificar el valor de un objeto del control CreateUserWizard, es necesario hacer un casting para obtener el objeto y a parte de eso hay que usar una serie de métodos para poder referenciar al objeto ya que el control CreateUserWizard está dividido en varias partes:

Dim errMessage As Literal
errMessage = CType(AsistenteCrearUsuario.CreateUserStep.
ContentTemplateContainer.FindControl("ErrorMessage"), Literal)

En el caso de que se esté usando un CreateUserWizard dentro de un UpdatePanel, lo mejor es convertir el CreateUserWizard en templates ya que los controles de Login no permiten modificar fácilmente los controles dentro del CreateUserWizard.

Asp.Net: Modificar Items que crea un Repeater Control

En ocasiones uno desea modificar un valor que se va a presentar en un Repeater control de Asp.Net. Entonces hay que obtener por así decirlo toda la estructura que viene en el objeto DataItem. A continuación el código en C# y VB.Net:

VB.Net:

Dim nav As XPathNavigator = CType(e.Item.DataItem, IXPathNavigable).CreateNavigator
Dim pagina As String = nav.Select("/Titulos/Titulo").Current.SelectSingleNode("pagina").Value


C#:
XPathNavigator nav = ((IXPathNavigable) e.Item.DataItem).CreateNavigator();
string pagina = nav.Select("/Titulos/Titulo").Current.SelectSingleNode("pagina").Value

El objeto XPathNavigator también tiene el método SelectSingleNode("nombreNodo") para recuperar el valor de un nodo.

Asp.Net: Response.End()

El método End() del objeto Response siempre lanza una excepción; para corregirlo se puede usar la siguiente instrucción en vez de usar Response.End():

  • HttpContext.Current.ApplicationInstance.CompleteRequest()

Asp.Net: Globalization

Cinco formas de implementar globalization en una aplicación web con Asp.Net:

1º En CodeBehind usar el objeto GetLocalResourceObject:

  • Label1.Text = GetLocalResourceObject("Label1Resource1.Text").ToString()
2º En el source de la página aspx modificar la propiedad Text del control:

  • <asp:Label ID="Label1" runat="server" Text="<% Resources:Label1.Text %>" />

3º En el source usar el atributo meta en el elemento del control Asp.Net:

  • <asp:Label ID="Label1" runat="server" meta:ResourceKey="lblLabel1" />
lblLabel1 = es un key en el archivo de recursos.

4º Usando recursos globales; en el source modificar el atributo Text:

  • <asp:Label ID="Label1" runat="server" Text="<%$ Resources:ClassNameRS, Label1 %>" />

5º Usando recursos globales; en el code behind usar objeto Resources:

  • Label1.Text = Resources.ClassNameRS.Label1
Resources.ClassNameRS.Label1 = Label1 es un key en el archivo de recursos globales.


En la parte gráfica de la página (Diseño) existe una propiedad llamada Expressions. Esa propiedad permite asociar un key que se encuentra en un archivo de recursos con una propiedad del control. Esto es solo para hacer las cosas más rápido.

lunes, 15 de junio de 2009

Error en PhpMyAdmin: Se necesita salvoconducto

Error:

Cuando dice que se necesita un salvoconducto, significa que hay que agregar la siguiente línea en
el archivo config.inc.php:

$cfg['blowfish_secret'] = 'cualquier cadena';

Error en PhpMyAdmin: Extención mcrypt

Error:
No se pudo cargar la extensión mcrypt, por favor revise su configuración de PHP.

Hay que descomentariar la línea de código:

extension=php_mcrypt.dll

MySql: Resetear clave de MySql

Error:

#1130 - Host 'localhost' is not allowed to connect to this MySQL server

Para esto aplicar los siguientes pasos para resetear la clave de MySql:


1º Detener el servicio de MySql.

2º Si se está en Windows usar una CMD y poner:

mysqld --skip-grant-tables

Si se está en Linux usar las instrucciones que están en:
www.kopernix.com

3º Luego abrir otra consola en Windows y poner:

mysql -u root mysql

4º Ahora ya se puede cambiar la clave:
  • UPDATE mysql.user SET Password=PASSWORD('nuevo_password') WHERE User='root';
  • FLUSH PRIVILEGES;
  • quit

5º Reiniciar los procesos.

¿CSS limitado para GMail, Hotmail, etc?

Curioso, no!

Con razón, yo trataba de poner un simple texto encima de una imagen, pero en el correo del destinatario el texto aparecía debajo de la imagen, ¿por qué?

La respuesta es porque los servicios de correo como GMail, Hotmail, etc, filtran algunas o todas las hojas de estilo. Obviamente es por seguridad o quién sabe que más será y lo desconozco por ahora.

Por lo que he leido lo que casi siempre funciona es la utilización de hojas de estilo en línea, esto quiere decir que hay que usar el atributo style dentro del mismo elemento. Por ejemplo:

<p style="color:Blue" />

Algunos links donde hablan de ducho tema:

  • Una buena explicación en español por Jairo Blanco


  • Programa Online para transformar mensajes de correo en formato HTML con CSS a un estilo que acepta GMail: Emogrifier


  • En Xavier Frenette encontramos bien detallado éste asunto, además hay links a otras páginas que también tratan el tema.


  • Esta otra página está buenísima pues muestra cuáles clientes web aceptan el repertorio de las hojas de estilo en cascada. La página es www.campaignmonitor.com

domingo, 7 de junio de 2009

Error Drupal: Barra de Progreso

El mensaje de error que aparece en el reporte que muestra Drupal es:

Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library (prefered) or to install APC.

La solución es simple; solo hay que activar la librería php_uploadprogress.dll

Si se está usando Wamp5 entonces se puede usar el icono que está en la barra de tareas para ir directamente a activar la dll.

¿Pero cómo se activa dicha librería si no usamos Wamp?

Para poder activarla hay que buscar el archivo php.ini. En dicho archivo buscar lo siguiente:

;extension=php_uploadprogress.dll

El siguiente paso es quitar el punto y coma de ésta forma pasa de ser un comentario a una sentencia válida que el PHP va a considerar y así es como activamos esa biblioteca, el resultado es:

extension=php_uploadprogress.dll

En la subcarpeta ext desde la carpeta principal donde esté instalado PHP, debería existir el archivo php_uploadprogress.dll. Generalmente siempre está;

Lo que sí puede suceder es que la sentencia que mencioné antes resulte que no existe en el archivo php.ini. Si ese es el caso, entonces debemos agregar esa sentencia que tengo marcada en color azul y listo. Si se está preguntado en qué parte del archivo poner la sentencia, pues le digo que eso no interesa tanto, se puede poner al inicio o al final del archivo, pero para mantener el orden busque donde dice ; Windows Extensions , un poco más abajo comienza la lista de todas las bibliotecas algunas activas y otras que están como comentarios. Entonces al final de esa lista se podría poner extension=php_uploadprogress.dll y ya está!

Finalmente, hay que reiniciar Apache.
 
En el caso de PHP 5 con Xampp lo único que hay que hacer es descomentar en php.ini la línea que dice:

[PECL]
extension=php_apc.dll

luego agregar la siguiente línea de código: apc.rfc1867 = on

Instalar Wamp correctamente

En el siguiente link se explica paso a paso cómo instalar Wamp y corregir ciertos errores que aparecen en PHPMyAdmin.

Instalar Wamp

Establecer la clave para el root de MySql

Esto se puede hacer desde PhpMyAdmin o desde consola de MySql:

mysql> update user set password=PASSWORD('aquiVaElPassword') where user='root';
mysql> flush privileges;

Luego resetar los servicios.

Las siguientes páginas son una gran ayuda porque explican como instalar PhpMyAdmin, Apache, etc:

En la documentación de MySql (buscar por "PASSWORD(str)") se recomienda usar mejor la función MD5() o SHA1().


IvLabs
Maestros del Web

martes, 2 de junio de 2009

Validar valor de una enumeración

Si queremos que una variable tenga un solo valor y no una combinación de valores de una enumeración, entonces hay que validar la enumeración con el método IsDefined de la clase Enum. En el siguiente código, si quitaramos el bloque if y en caso de que el CType (VB .Net) no falle, entonces se devolverá una combinación de días separadas con coma.

Código en VB .Net:

<Flags()> _
Enum Dias As Byte
Lunes = 1
Martes = 2
Miercoles = 4
Jueves = 8
Viernes = 16
Sábado = 32
Domingo = 64
NA = 128
End Enum


Sub Main()

Dim a As Dias
a = CType(254, Dias)
If [Enum].IsDefined(GetType(Dias), a) = False Then
a = Dias.NA
End If
Console.Write(a.ToString)
Console.Read()
End Sub


Código en C#:

[Flags()]
enum Dias : byte
{
Lunes = 1,
Martes = 2,
Miercoles = 4,
Jueves = 8,
Viernes = 16,
Sabado = 32,
Domingo = 64,
NA = 128
}

class Program
{
static void Main(string[] args)
{
Dias d = (Dias)254;
if (Enum.IsDefined(typeof(Dias),d) == false)
d = Dias.NA;
Console.Write(d.ToString());
Console.Read();
}
}

jueves, 28 de mayo de 2009

Excelente curso introductorio de C#

Es el mejor curso que he encontrado hasta ahora. Me interesó mucho porque explica en el penúltimo capítulo el tema de LINQ, además el tema de los web services está bien claro de entender. Ver curso

Otros cursos en Cursos Online de Microsoft

Curso de Introducción a .NET con Visual Basic 2008

Curso de Desarrollo web con Visual Studio 2008

sábado, 23 de mayo de 2009

De un XML String a un DataSet - Web Services

En éste ejemplo se muestra cómo recuperar una lista de nombres de países proporcionados por un web service y luego presentados en una página web. Es un ejemplo sencillo, la URL del sercicio web es la siguiente:
http://www.webservicex.net/country.asmx?wsdl
     Sitio oficial: webserviceX.net


Hay que agregar la referencia web, en mi caso estoy utilizando Visual Web Developer 2008 para desarrollar dicho ejemplo. El método que preparé es el siguiente:
 private void Mostrar()
{
net.webservicex.www.country ws = 
new net.webservicex.www.country();       
DataSet ds = new DataSet();
ds.ReadXml(new StringReader(ws.GetCountries()));
gvPaises.DataSource = ds;
gvPaises.DataBind();
}

El web service también expone muchos otros web methods entre ellos está el método llamado GetCurrencies(). Este web method devuelve un xml con los elementos Name, CountryCode, Currency (Moneda) y CurrencyCode (iniciales de país). Dichos elemntos se puede pasar a un dataset y mostrarlos en un GridView, etc.

Para buscar otros Web Service existe Seekda.

jueves, 21 de mayo de 2009

Mi primera Estrella

Hace años, creo que en el 2006 o 2007 supe sobre las certificaciones "Dessarrollador cinco Estrellas". En ese tiempo decidí hacer el primer examen para obtener la estrella cero. Me saqué un triste 75, jeje!

Hoy Jueves 21 de Mayo, 2009, decidí bajar y estudiar el material para la primera estrella y gracias a Dios me saqué un 90 en el examen general y para los exámenes de C# y VB.Net saque 80 y 85 respectivamente.

Los exámenes son relativamente fáciles, cualquiera si se lo propone y estudia con buena gana, de fijo sale bien, mmmmmmm!, bueno!, eso sentí cuando hice los exámenes para la primera estrella!, vamos a ver como me va en la segunda tanda, jeje!

martes, 12 de mayo de 2009

¿Qué tan rápido digitas?

SpeedTest es un sitio que te pone a prueba a la hora de tener que digitar palabras. El sistema muestra palabras al azar y uno tiene que ir digitándolas lo más rápido que se pueda y luego de un minuto el sistema indica cuántas palabras eres capaz de digitar por minuto.

Si necesitas practicar

Videos de YouTube sin Flash

AL instalar Ubuntu 9.04 noté que los videos en YouTube se observan como pausados o entre-cortados y realmente es algo molesto considerando que tengo buena conexión. La mejor solución que encontré fue instalar: GreaseMonkey + Free YouTube

martes, 5 de mayo de 2009

Instalar cámara web en Ubuntu

En éste sitio web se detalla como llevar a cabo la instalación de los drivers para las cámaras web.

Programas para cámara web que me funcionaron sin tener que hacer nada en Ubuntu 9.04:

1- wxcam (éste es el que más me gustó!)
2 - xawTV (sudo apt-get install xawtv)
3 - Cheese (sudo apt-get install cheese)

¿Gratis?

Encontré que bar-zone.blogspot.com es un blog que reune cientos de links a sitios con libros, material de estudio entre otras cosas totalmente gratis.

domingo, 3 de mayo de 2009

Codecs para Ubuntu

En TuxApuntes se explica cuáles paquetes tenemos que bajar para instalar los codecs correctos.

Diez clientes de mensajeria para Linux

La lista para escoger es:

sudo apt-get install pidgin
sudo apt-get install amsn
sudo apt-get install mercury
sudo apt-get install psi
sudo apt-get install monkey
sudo apt-get installempathy
sudo apt-get install skype
sudo apt-get install emesene
sudo apt-get install kmess
sudo apt-get install kopete

Error en el Gestor de paquetes Synaptic


Para corregir el error que aparece cuando se recarga el gestor de paquetes, simplemente hay que ejecutar las siguientes dos líneas en una terminal:

              > sudo rm /var/lib/apt/lists/* -vf
              > sudo LC_ALL=C apt-get update

lunes, 27 de abril de 2009

Preparar dominio en Ubuntu 8.10

En el archivo /etc/apache2/sites-available/default es posible agregar todos los dominios que queramos. A parte del directorio virtual por defecto se puede indicar al servidor Apache que existe otro servidor agregando otra directiva :


<VirtualHost xxx.xxx.xxx.xxx:80>
ServerName localhost
ServerAlias http://demo.com/
DocumentRoot /var/www/demo

<Directory "/var/www/demo/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Allow from xxx.xxx.xxx.xxx
</Directory>

</VirtualHost>

Donde dice xxx.xxx.xxx.xxx es la IP que nos fue asignada.

Links para más ayuda:
HTTPD - Servidor web Apache2
Configuración de múltiples dominios
Cómo configurar las máquinas virtuales en Apache
Instalar un servidor Ubuntu

Obtener la lista de funciones de PHP

En PHP existe una interesante función que nos devuelve una lista completa de todas las funciones definidas en PHP y también todas las funciones definidas por el usuario. El resultado es una matriz multidimensional donde ['internal'] corresponde a las funciones de PHP y ['user'] corresponde a las funciones definidas por el usuario:

Ver ejemplo en Php Español

Las funciones más utilizadas en Symfony

Lista de funciones de PHP

Tutorial PHP

miércoles, 22 de abril de 2009

Videos de Microsoft Visual Studio (Express Editions)

Interesante el siguiente enlace, es un buen curso en videos y buenas lecturas del Beginner Developer Learning Center (en esa página hay un link que dice "Mi ruta de aprendizaje" éste los llevará a los videos).

O también ver estos videos Asp.Net.

martes, 21 de abril de 2009

Enviar correo electrónico desde Drupal sobre Linux

Complicado el envío de mensajes desde Drupal; supuestamente no hay que hacer nada, en teoría es cierto, pero a mí no me funcionaba ya que cada vez que enviaba un correo desde el formulario de "Contacto" que proporciona Drupal, no me funcionaba para nada. El error que aparecía era simplemente que "no se pudo envíar su mensaje de correo electrónico".

¿Soluciones?

- Empecé como siempre googleando un poco, jaja!
- El primer paso fue resetear el servidor Apache:

>sudo /etc/init.d/apache2 restart

- Eso no funcionó. Entonces procedí a trabajar sobre php.ini:

>sudo gedit /etc/php5/apache2/php.ini

Buscar donde dice [mail function], y las siguiente líneas tienen que estar
activas; es decir que NO estén como comentarios:

SMTP = localhost
smtp_port = 25

Si se desea usar como servidor de correo por ejemplo a racsa, entonces
cambiar localhost por smtp.racsa.co.cr luego reiniciar el servidor Apache.

Lo anterior funcionó pero observé que el envío de mensajes es muy lento, entonces decidí instalar el módulo PHPMailer. En el readme.txt se indica que hay que descargar además dos archivos extras de SourceForge (lean dicho archivo). Posteriormente instalar el módulo en Drupal de la forma tradicional.

Luego ir a la configuración Mail la cual se puede encontrar en:

http://localhost/Demo/admin/settings/phpmailer

Activar donde dice "Use PHPMailer for sending e-mails"

En esa página se configura también el SMTP primario que puede ser localhost o poner el SMTP de RACSA (smtp.racsa.co.cr). El puerto se deja en 25.

Advertencia: Si se usa RACSA o cualquier otro servicio que no sea local, lo más probable es que se tenga que digitar el login y password (hay un lugar para eso en la página), de lo contrario el mensaje no se enviará o si se enviará pero aparecerá un posible error en la página.

Si se usa localhost entonces no completar el login ni password. Después de salvar todo, ya es posible enviar los mensajes de correo un poco más rápido.

sábado, 18 de abril de 2009

Firestarter no funciona

Recien instalado Firestarter me aparece un error relacionado con que no se pudo iniciar el cortafuego. El error es el que se observa en la siguiente imagen:




La solución es modifcar el archivo firestarter.sh:

gksu gedit /etc/firestarter/firestarter.sh

Una vez abierto el archivo ponemos como comentario el siguiente código:

if [ "$MASK" = "" -a "$1" != "stop" ]; then
echo "External network device $IF is not ready. Aborting.."
exit 2
fi

lunes, 6 de abril de 2009

Drupal Error: GD Image Filtering

Me aparece el siguiente error en Ubuntu 8.10:

GD Image Filtering Low Quality - Poor Perfomance ....
GD Image Rotation Low Quality - Poor Perfomance ....

Corresponde a un caso de mala instalación de los paquetes que conforman al PHP5. La solución está en la siguiente página de PHP.

Compiz Fusion

Ejemplos para configurar el Cubo de Compiz al gusto en Fedoreando

domingo, 5 de abril de 2009

Solucionar sonido en Ubuntu Linux 8.10

Casi todo un día para lograr escuchar sonido en mi compu luego de que instale Ubuntu Linux para hacer simplemente unas pruebas con Drupal y carga de videos.

La solución la encontre en el blog de Federico Almada

viernes, 3 de abril de 2009

Drupal en Linux Ubuntu

He estado trabajando Drupal sobre Windows XP; le llegó la hora a Ubuntu, esto porque he notado un bajo rendimiento y demasiado consumo de recursos del sistema. Todo ha andado mal en cuanto a velocidad al trabajar bajo Windows y por más cambios que ya de por sí hice hace días, no han tenido el efecto que yo esperaba. Vamos a ver cómo me va con Ubuntu.

Algunos elances recomendados son:

Enlace #1
Existe bastante información en este línk.

Video
Video sobre que cómo instalar Drupal en Ubuntu.

lunes, 30 de marzo de 2009

Técnicas y herramientas para HTML y CSS

"Más que todo el esfuerzo en construir tu sitio web, la cosa más importante para tus usuarios es cómo se ve tu sitio. Administrar las inconsistencias en tus temas para cada browser, para cada módulo y para los temas seleccionados para tus usuarios puede ser un gran reto..."

Lo anterior es parte de las técnicas y herramientas que se exponen en el sitio web de Drupal y que mejor que ellos para explicarlo. En esa página se explican las precausiones y herramientas de validación para los sitios web que vayamos a desarrollar.

HTML and CSS techniques and tools

sábado, 28 de marzo de 2009

Traducir un módulo de Drupal

A continuación resumo los pasos que hay que realizar para traducir un módulo específico de esos que nos bajamos para instalar en Drupal.

Primera Etapa:
  Descargar el módulo potx
Descargar el programa Poedit
Instalar dichos programas (obvio jaja!).

Segundo Etapa:
Lo siguiente es traducir un módulo, el módulo que
queramos traducir por ejemplo el módulo de Ubercart;
vamos al directorio de Ubercart y creamos un
sub-directorio que se llame "translations" para poner
en dicho directorio los archivos que vamos a generar.

Otra vez volvamos a la carpeta de Ubercart. En ese
lugar pegar los archivos potx.inc y potx-cli.php los
cuales se encuentran en el módulo de Potx.

En línea de comandos ubiquémonos en la carpeta de
Ubercart y ejecutamos el comando php potx-cli.php.
Ese comando genera mínimo un archivo con el nombre
"general.pot"

En ese archivo (general.pot) están todas las cadenas
de texto que se identificaron para traducir.

Lo que se necesita ahora es crear un archivo con
extención *.po el cual sirve para importarlo utilizando
la opción que se encuentra en "Traducir interfaz" del
sistema Drupal; pero primero generemos el archovo *.po.

El archivo *.po se genera con ayuda del programa
Poedit. En la opción de menú:

"Archivo" -> "Nuevo catálogo esde un archivo POT"

servirá para cargar el archivo creado anteriomente.
Una vez generado el archivo hay que guardarlo en el
directorio "Tranlations" para mantener la misma
convención que se mantiene con las otras traduciones
existentes en Drupal.

Lo demás es más que obvio, simplemente proceda a
traducir cada cadena usando el mismo programa POEdit
y posteriormente importe el archivo a Drupal.

Como empezar el brete de diseño web.

En los siguientes enlaces se muestra como ir paso a paso con el diseño y desarrollo de un sitio web:

Ejemplo #1

Ejemplo #2

viernes, 27 de marzo de 2009

Imagen Rollover para menu

Para crear una imagen rollover por ejemplo para un menú, hay que preparar una única imagen con los estados que va a tener cuando se está inactivo, encima, etc.

En el archivo de estilos se puede agregar un código como el siguiente:


.button a:link,
.button a:visited
{
display:block;
overflow:hidden;
background-image:url(images/menu.png);
background-repeat:none;
height:0;
width:400px;
padding-top:100px;
background-position:0px 0px;
}

.button a:hover
{
background-position:0px -100px;
}

miércoles, 25 de marzo de 2009

Animación con JQuery

Ejemplo:


Por supuesto, para que esto funcione tenemos que incluir el script
de JQuery a la página web.

<fieldset id="bloque" style="display:block">
<legent>Ejemplo</legent>
<br />
<input type='textbox' id="txt" name="txt" value="" />
<br />
<br />
<input type="button" id="btn" value="Press Me!" />
</fieldset>

<script type="text/javascript">

$("#btn").click
(
function()
{
$("#bloque").fadeOut("slow",function(){$("#bloque").fadeIn(1000);});
}
);

</script>

Este código hace que el elemento Fieldset desaparezca lentamente y vuelve a aparecer otra vez igualmente lentamente.

lunes, 23 de marzo de 2009

Javascript: Mostrar un objeto cada segundo

Este código consiste en hacer cambiar la propiedad opacity del objeto textbox. La propiedad opacity va aumentando desde 0 hasta 1 en intervalos de 0.1. Cuando se llega al valor 1, el ciclo se detiene y el cuadro de texto queda renderizado totalmente con opcidad completa.


<script type="text/javascript">
document.getElementById('txt').style.opacity = 0;

var opa = 0.0;
var intv;
start();
function start()
{
if (start.length == 0)
intv = setInterval("Aumentar();", 500);
else
/* El parámetro arguments[0] son los milisegundos. */
intv = setInterval("Aumentar();", arguments[0]);
}

function Aumentar()
{
opa = opa + 0.1;
document.getElementById('txt').style.opacity = opa;

if(opa>1)
{
clearInterval(intv);
document.getElementById('txt').value = "Stopped!";
}
}

</script>