Web – Resolvendo conflitos no jQuery

23/03/2011 1 comentário

O jQuery é uma biblioteca tão bacana que é usada intensamente por desenvolvedores e web designers.

Isso é ótimo por um lado, pois além de todas as vantagens, traz certa uniformidade para o desenvolvimento, e impede que um dos dois suje demais o código.

O lado péssimo é que, se desenvolvedores e designers não se conversam, o que é comum, cada um acaba por usar versões diferentes do jQuery, o que pode gerar conflitos. Algumas vezes nem dá para chegar em um acordo, pois a depender a implementação, a dependência gerada de uma determinada biblioteca pode tornar inevitável o uso de duas versões. O erro mais comum é passar a não encontrar determinadas funções, mesmo as padrões do jQuery, obtendo resultados como:

$(“#datepicker”).datepicker() is not a function

Isso acontece porque, com mais de uma versão do jQuery, cada uma tenta declarar a variável “$”. Na segunda tentativa de usá-la, o erro acima aparece. A solução? Veja o código abaixo:

var $j = jQuery.noConflict();
$j("#datepicker").datepicker();

O que isso faz? Cria um novo contexto para o jQuery, permitindo que você trabalhe com ele a partir desta nova variável. Uma explicação melhor do que o método noConflict() faz pode ser vista no link abaixo:

http://api.jquery.com/jQuery.noConflict/

Pronto! Seu jQuery voltará a funcionar.

Referências

http://stackoverflow.com/questions/1212696/jquery-ui-datepicker-datepicker-is-not-a-function

Categorias:Javascript, JQuery Tags:,

SQL – Multiplos Bancos no Contexto do Linq To Sql


Dependendo da arquitetura da empresa, é comum encontrarmos sistemas que acessam dados em bancos de dados separados, como uma forma de integração. A query abaixo mostra um exemplo disso sendo feito:

USE ECOMMERCE
SELECT
	pes.Nome,
	cid.Nome
FROM
Pessoa pes
	INNER JOIN BANCO_CORREIOS..Cidades cid ON pes.cidade = cid.id
WHERE
	pes.id = 123

No caso do MS SQL Server, o “..” permite ter acesso a um banco de dados específico, não se atendo ao contexto da query que está sendo construída, no caso, ECOMMERCE.

Usando LINQ To SQL, criaríamos um contexto (DBML) para o banco ECOMMERCE, porem como seria realizado o JOIN com o BANCO_CORREIOS?

Uma solução seria criar dois contextos, um para cada banco, consultar a pessoa de id = ‘123’ no xontexto do banco ECOMMERCE e consultarmos a cidade onde o id = pessoa .cidade no contextos do banco CORREIOS.

O seu arquivo de contexto pode ser o responsável também por consultar as cidades, desde que o usuário usado para conectar no banco de ECOMMERCE tenha acesso ao banco dos CORREIOS. Dessa maneira poderiamos realizar apenas uma consulta com join nas tabelas necessarias.

Para fazer isso, basta inserirmos a tabela de Cidade no xml do arquivo de contexto:

1) Clique com o botão direito no arquivo de contexto e selecione “abrir com/Open with“.
Exição XMLS de DMBL
2) Selecione “Automatic Editor Selector (XML)”.
3) Insira o bloco XML referente a tabela desejada. A propriedade Name deve ser preenchida da mesma maneira como fazemos em uma query simples no SQL. [NomeDoBanco].[Usuario].[Tabela].

<Table Name="BANCO_CORREIOS.dbo.Cidades" Member="Cidades">
	<Type Name="Cidades">
		<Column Name="id" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
		<Column Name="nome" Type="System.String" DbType="VarChar(60) NOT NULL" CanBeNull="false" />
		<Column Name="uf" Type="System.String" DbType="VarChar(2) NOT NULL" CanBeNull="false" />
	</Type>
</Table>

4) Na sua tabela de Pessoa, voce pode inserir uma associação:

<Association Name="Pessoa_Cidade" Member="Cidade" ThisKey="Cidade" OtherKey="ID" Type="Cidade" />

Salve e verifique que a tabela cidade já esta em seu contexto.

Categorias:SQL Tags:,

MVC – MVC Scaffolding


Se você esta usando o MVS Scaffolding [http://mvcscaffolding.codeplex.com/] e não sabe como mudar a connection string, vale à pena dar uma lida no blog [Matt’s work blog].
A solução é simples, basta adicionar no seu “web.config” uma connection string para o banco desejado. A única restrição é que o nome da connectionString deve ser o nome do seu contexto

<connectionStrings>
	<add name="BlogContext" connectionString="Data Source=.; Initial Catalog= Blog; Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
 </connectionStrings>

isso para um contexto de nome BlogContext

public partial class BlogContext : DbContext

Devidos méritos ao Matt.

Categorias:.NET, asp.net, MVC Tags:,

jQuery – Truncando texto


Diversas vezes precisei truncar um texto para não quebrar o layout. Criei uma função JQuery para resolver tal problema. A função busca por uma classe CSS especifica e verifica em um atributo no elemento HTML o limite (em caracteres).

HTML

<span limite="20">Esse texto vai ser truncado de acordo com o limite.</span>

jQuery

$().ready(function() {
     truncarTextos();
 });

 function truncarTextos(){
     $('.truncar').each(function(){
         truncarTexto($(this));
     });
 }

 function truncarTexto(elementoHtml){
     var limite = elementoHtml.attr("limite")

     if(elementoHtml.html().length > limite)
     {
         elementoHtml.html(elementoHtml.html().substring(0,limite) + "...");
     }
 }

Ficou bem simples e resolveu o problema. Porem, quantas pessoas precisam truncar um texto e tomam a mesma atitude? Depois de uma busca percebi que isso acontece freqüentemente e para resolver o problema existem plugins dojQuery que funcionam de uma forma muito mais inteligentes do que a função acima, eles limitam o texto por tamanho e não por caracteres.

O que achei mais bacana é o jTruncate

Se você precisa truncar um texto, use um plugin do jQuery, não faça seu próprio código, isso implica em mais testes e duplicidade de código toda vez que precisar truncar um texto. 🙂

Vou publicar o código para fins educativos, mas seja mais inteligente e produtivo que eu e use um plugin.

Download do meu código

Exceptions – Um caso real de seu uso, ou não


Outro dia, discutia com alguns colegas do trabalho sobre o correto uso de exceptions em uma aplicação. Para ficar um pouco mais explícito, o contexto era mais ou menos o seguinte:

Havia um código em aplicação, já pronto, com toda a lógica necessária para o que ele precisava fazer. Foi preciso, no entanto, adicionar um comportamento que invalidaria o fluxo atual, que estava funcionando bem. Nem preciso dizer que tal mudança no código faria ter que testá-lo novamente na íntegra. No desejo de diminuir o impacto que a mudança causaria no código existente (conceito do programador preguiçoso), pensou-se na solução mais simples que consistia no fato de que, se a nova verificação desejada não fosse feita, causaria um erro na execução do programa. Erro? Oras? Porque não try/catch? Resolveria, não?

Sim, é a resposta rápida a esta pergunta.

Vamos então aos argumentos para torná-la válida.

Primeiro, defendo (na esperança dos ditos colegas concordarem comigo) o uso de todo e qualquer recurso disponível para uso nas linguagens de programação. Se eles estão lá, é para serem usados. O que tem ocorrido ultimamente é que, tendo nós programadores sido bombardeados por tudo que é tipo de filosofia, mais comumente chamadas “boas práticas”, acabamos por somente segui-las, esquecendo a grande parte das possibilidades que as tecnologias nos proporcionam. Aqui, vale um parênteses. Particularmente, acho isso triste, já que uma das características marcantes desta profissão, é a liberdade de se poder fazer o que quiser, como quiser, ou seja, todas as possibilidades. São fatores como esses que acredito ser o que faz com que nosso trabalho nos aproxime mais dos artistas, pintores e músicos do que dos engenheiros e projetistas.

Voltando ao foco do texto, se o try/catch resolve o problema citado, e rápido, porque não usá-lo? Insatisfeitos com a resposta, decidimos assumir esta última como uma possibilidade e partimos para analisar o código mais de perto, fazendo do ocorrido praticamente um Coding Dojo.

A resposta do porque usar a exception para resolver o caso nós já tínhamos. É rápido e fácil de implementar, e resolve pontualmente o problema. Agora, mais do que justamente, vamos ao porque não utilizar essa alternativa.

Primeiro, vale citar um caso típico oferecido pelo próprio .NET Framework. Uma Exception que deve ser conhecida da maioria, é a DivideByZeroException. Seu nome é auto explicativo. Ela é disparada toda vez que ocorre um erro de divisão aritmética por zero em um código .NET. Há alguns evangelistas (amigos inclusive) que defendem que os códigos que podem gerar tal Exception fossem tratados por esta, pois isso o deixaria mais claro e legível a respeito do que está acontecendo, aplicando o mesmo pensamento para outras situações. De todos os argumentos, só defendo e mesmo assim, parcialmente, o último.

O problema de usar Exceptions é que, ao se trabalhar com o disparo destas, estamos causando um overhead no processamento do programa. Convido-o a parar para pensar por um minuto. Se você já depurou um aplicativo, no caso do .NET, no Visual Studio, você provavelmente parou para analisar a pilha de execução de uma Exception, seja ela qual for, e analisar as informações que lá haviam para ajudar a identificar um erro. Pois é. Quando você dispara mesmo que voluntariamente uma Exception, você está carregando a memória e o processamento do seu aplicativo com toda essa informação e os objetos que a acompanham. O mecanismo de Exceptions do .NET Framework é excelente, mas traz consigo uma considerável carga. Não que este nunca deva ser utilizado, até porque, algumas vezes ele é inevitável, mas o fato é que, se você não precisa mesmo da Exception, evite-a!

No caso mais simples, que é o do DivideByZeroException, apesar de ilustrativo, é muito mais simples antes de fazer a divisão, verificar se o divisor tem o valor zero.

Curiosamente, frameworks de teste como NUnit vem ao encontro de necessidades como esta. Um código bem testado precisa de menos tratamento de erros, certo?

Finalmente, após nosso “Dojo”, o resultado foi a reescrita do código, que ficou com menos da metade das linhas da primeira versão, atendendo a nova necessidade e sem nenhum tratamento de Exceptions!

Enfim, apesar do texto ter fugido um pouco ao título, o que ficou de lição neste caso foram os seguintes pontos:

  • Utilize tratamento de Exceptions com muito cuidado. Não envolva seu código em um try/catch só porque você acha que ele pode levar a um erro.
  • A inserção descuidada de um bloco try/catch causa uma quebra lógica na sequência de execução do aplicativo, sendo em vários casos pior do que um if/else. Quando da ocorrência de um erro, praticamente todo o contexto criado dentro do try é perdido, sendo preciso externalizar muita coisa, o que já nos levaria a uma manutenção considerável do código.
  • Sempre, sempre submeta seu código à avaliação dos colegas. Várias cabeças (mas não muitas) pensam melhor do que uma. O pior que pode acontecer é ter que reescrever o código, o que não é essencialmente ruim, já que o resultado utilizando este tipo de cooperação é potencialmente melhor. A certeza é de aprendizado por todos, pois, como somos artistas (:p), cada um provavelmente pensaria em uma solução diferente.

Por fim, o que gostaria de deixar aqui é a vivência que tive com a situação, juntamente com a equipe, mais no sentido como encarar um problema de programação, como no exemplo citado, do que dar uma opção de resposta para este.

Deixo aqui também meus agradecimentos aos amigos @arnascimento e @stupied4ever, com quem vivi e compartilhei a ocasião acima citada.

Curiosidade: escrevi a maior parte deste artigo direto no celular enquanto estava no transporte público. Local atípico para se pensar e escrever um artigo desses, não? 😉

RubyConf – Agenda


Amanha o @tomamais e eu estaremos no RubyConf. Na agenda do site a grade não mostra o titulo das palestras então resolvi colocar em uma planilha. Você pode ver a imagem ou fazer o download da planilha.

RubyConf Agenda

Categorias:Sem categoria

DotNet – Sitemap simples e eficiente


Faz uma semana, eu postei sobre sitemap no MVC, e ontem o @arnascimento precisou de um sitemap, mas tinha que ser para WebForms. Para isso eu fiz uma adaptação do meu código e ele funciona também para WebForms.

O código pode ser encontrado em http://www.rafaelalmeida.net/Content/Exemplos/googlesitemap.zip.

Categorias:.NET, SEO, SiteMap, XML Tags:, , ,

SQL – Apagando todos os registros de um banco de dados SQL Server

05/10/2010 1 comentário

Tirado fundo do baú. 😉

As experiências que tive em um projeto me levaram a ter que descobrir alguns macetes do SQL Server. A pressão realmente faz diamantes e a “experiência” é definitivamente algo insubstituível.

Uma das necessidades da aplicação era a constante troca de ambiente. Uma hora desenvolvimento, outra produção, outra qualidade, enfim.

Como o acesso era extramente restrito, não era algo trivial ficar “dropando” a base de dados, até porque nem era possível. O jeito era trabalhar direto no SQL para substituir algumas rotinas que a ferramenta e o acesso em nível administrativo facilitavam.

Por exemplo, para facilmente excluir todos os dados de todas a tabelas de um banco de dados SQL Server, a seguinte query resolve o problema:

-- desativa a integridade referencial
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO

EXEC sp_MSForEachTable '
IF OBJECTPROPERTY(object_id(''?''), ''TableHasForeignRef'') = 1
DELETE FROM ?
else
TRUNCATE TABLE ?
'
GO

-- reativa a integridade refencial
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO

Em detalhes, o que a query faz: ela usa uma stored procedure não documentada do SQL Server chamada sp_MSForEachTable. Resumidamente, esta stored procedure dispara um comando SQL passado por parâmetro em todas as tabelas de um database, sendo o nome da tabela substituído pelo caracter “?”, como pode ser visto na query anterior. Se além de de apagar os dados das tabelas, quiser também reiniciar a contagem dos campos de chave primária, mais conhecido como RESEED, bastaria colocar a seguinte query antes da reativação da integridade referencial:

-- Reinicia o contador de chave primária de todas as tabelas
EXEC sp_MSForEachTable '
IF OBJECTPROPERTY(object_id(''?''), ''TableHasIdentity'') = 1
DBCC CHECKIDENT (''?'', RESEED, 0)
'
GO

Na falta de ferramentas ou privilégios, esse tipo de macete é uma mão na roda.

Referência:

http://blogs.officezealot.com/mauro/archive/2006/03/12/9402.aspx

Bom proveito!

JQuery – Campo de texto aceitando só números


Uma coisa que sempre precisamos pesquisar ou em projetos antigos ou no google é como deixar um input text só aceitando números, iremos fazer isso utilizando o jquery 😉

Primeiro crie a função:

function verificaNumero(e) {
                if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
                    return false;
                }
            }

Pode ser dentro da página dentro de tags ”, mas eu aconselho criar sempre em um arquivo separado e linkar no html.

Após isso, é só colocar no document.ready quais campos devem ter essa função no keypress:

$(document).ready(function() {
				$("#txtCEP").keypress(verificaNumero);
				$("#txtCEP2").keypress(verificaNumero);
				$("#txtCEP3").keypress(verificaNumero);
			});

Simples!
Testado em: IE, Firefox e Chrome!

Pra quem está tento erros de sintaxe, segue o html completo:

<html>
	<head>
		<title>Teste só numeros</title>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
		<script>
			function verificaNumero(e) {
                if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
                    return false;
                }
            }
			
			$(document).ready(function() {
				$("#txtCEP").keypress(verificaNumero);
				$("#txtCEP2").keypress(verificaNumero);
				$("#txtCEP3").keypress(verificaNumero);
			});
		</script>
	</head>
	<body>
		<input id="txtCEP" type="text"/>
		<input id="txtCEP2" type="text"/>
		<input id="txtCEP3" type="text"/>
	</body>
</html>

Abraço!

DotNet – Porque usar o “ref” para “ReferenceTypes” ?


Esses dias eu estava conversando com um amigo sobre a necessidade de usar “ref” para passar por referência objetos “ReferenceType” [LINK]. Ele me dizia que não era necessário, e eu dizia que mesmo que não fosse necessário, o ideal era utilizar para aumentar a legibilidade.
Hoje conversando sobre isso na empresa o @tomamais me enviou essa pagina do MSDN [LINK] onde os exemplos 4 e 5 respondem a dúvida.

A RESPOSTA:
Um parâmetro do tipo “reference type” será tratado como passagem por referencia mesmo que não use a palavra reservada “ref”, porem se essa variável for “reinstanciada”, as modificações posteriores não vão refletir fora do método.

class Program
{
    static void Change(int[] arr)
    {
        arr[0] = 888;   // Essa mudança afeta o elemento original.
        arr = new int[5] { -3, -1, -2, -3, -4 };   // Essa mudança é local.
        Console.WriteLine("Dentro do metodo, o primeiro valor é: {0}", arr[0]);
    }

    public static void Main()
    {
        int[] myArray = { 1, 4, 5 }; /// Array de 3 posições
        Console.WriteLine("Na Main, antes da chamada do metodo, o primeiro valor é: {0}", myArray[0]);
        Change(myArray);
        Console.WriteLine("Na Main, depois da chamada do metoro, o primeiro valor é: {0}", myArray[0]);
        Console.Read();
    }
}

Saída no console:
Na Main, antes da chamada do metodo, o primeiro valor é: 1
Dentro do metodo, o primeiro valor é: -3
Na Main, depois da chamada do metoro, o primeiro valor é: 888

É por esse motivo que precisamos usar o “ref”.
Repare que com o uso da palavra reservada, o valor é alterado mesmo reinstanciando a variável.

class Program
{
    static void Change(ref int[] arr)
    {
        arr[0] = 888;   // Essa mudança afeta o elemento original.
        arr = new int[5] { -3, -1, -2, -3, -4 };   // Essa mudança é global.
        Console.WriteLine("Dentro do metodo, o primeiro valor é: {0}", arr[0]);
    }

    public static void Main()
    {
        int[] myArray = { 1, 4, 5 }; /// Array de 3 posições
        Console.WriteLine("Na Main, antes da chamada do metodo, o primeiro valor é: {0}", myArray[0]);
        Change(ref myArray);
        Console.WriteLine("Na Main, depois da chamada do metoro, o primeiro valor é: {0}", myArray[0]);
        Console.Read();
    }
}

Saída no console:
Na Main, antes da chamada do metodo, o primeiro valor é: 1
Dentro do metodo, o primeiro valor é: -3
Na Main, depois da chamada do metoro, o primeiro valor é: -3

CONCLUSÃO:
O uso da palavra reservada “ref” é obrigatório não somente pela legibilidade do código, mas também quando acontece a reinstanciação de uma variável. Quando reinstanciamos a variável dentro método no contexto global, o valor será diferente do desejado.

Categorias:.NET Tags:, , , ,