terça-feira, 31 de março de 2009

[snippet] Adicionando inputs ao pressionar enter

Inserindo mais inputs no enter:

adminEssays.form = {};

adminEssays.form.addInput = function(target) {
var nextInput;
inputs = $("#category-subs").children('input');
if(inputs.length == 0) {
nextInput = 0;
}
else {
nextInput = 0;
for (var a = 0; a < inputs.length; a++) {
id = parseInt(inputs[a].id.substr(21));
if (id >= nextInput) {
nextInput = id + 1;
}
}
}
id = "category-subcategory-" + nextInput;
html = "< input type='text' size='70' id='" + id + "' class='category-subcategory' name='subcategory[]' style='display:block'/>";
if(nextInput == 0) {
$('#category-subs').html(html);
}
else {
$(target).after(html);
}
$(".category-subcategory").bind("keypress",adminEssays.form.inputEnter);
}

adminEssays.form.submitForm = function(id) {
JsonC.submitForSfAction('adminEssays/insertSubcategories',{},'form-insert-subcategories','form-insert-subcategories-loading');
}

adminEssays.form.inputEnter = function(evt) {
if(evt.keyCode == 8 || evt.keyCode == 46) {
var tgt = $(evt.currentTarget);
if(tgt.val() == '') {
if( $('#category-subs').children().length > 1 ) {
var inputToFocus;
if(tgt.next().length > 0) {
inputToFocus = tgt.next()[0];
}
else {
inputToFocus = tgt.prev()[0];
}
tgt.remove();
inputToFocus.focus();
}
return false;
}
}
if(evt.keyCode == 13) {
prox = $(evt.currentTarget).next().length;
if(prox > 0) {
$($(evt.currentTarget).next()[0]).focus();
}
else {
adminEssays.form.addInput(evt.currentTarget);
$($(evt.currentTarget).next()[0]).focus();
}
}
};

quinta-feira, 5 de março de 2009

Criando uma estrutura de arvore para o jsTree


public function createTreeStructure($dir) {
$ar = array(
'attributes'=>array('id'=>'node-root'),
'data'=>'TESTS',
'children'=>$this->createChildren($dir)
);
return $ar;
}

public function createChildren($dir) {
static $n=0;
$it = new RecursiveDirectoryIterator($dir);
$arAll = array();
foreach($it as $file) {
if(strpos($file,'.svn') !== false) continue;
$ar = array(
'attributes'=>array('id'=>'node-'.$n),
'data'=>$file->getFilename()
);
if($file->isDir()) {
$ar['children'] = $this->createChildren($file);
}
$arAll[] = $ar;
}
return $arAll;
}

O valor de longo prazo de um software é diretamente proporcional a qualidade do código.

Já imaginou se todo gerente e toda organização tivessem esta consciência? Seria bem mais fácil de fazer um bom trabalho. Pena que de maneira geral o brasileiro ainda não tem visão de médio e longo prazo.

O que acontece é que o custo de desenvolvimento de um software, se for bem feito, pode reduzir muito o custo do próximo pelas bibliotecas geradas. E também a manutenção em bom código é muito mais fácil.

segunda-feira, 2 de março de 2009

Module Pattern

Existem diversos bons artigos na net a este respeito. Aqui não vou tentar explorar todas as possibilidades deste padrão. Pretendo apenas dar uma explicação básica do seu funcionamento.

O "Module Patern" tira proveito dos "closures" do JS. Quando uma função declara variáveis dentro dela e também declara outras funções ou objetos estes objetos e funções têm acesso às variáveis declaradas. Ex:


pessoa = function(nome,telefone) {
var nome = nome;
var telefone = telefone;
this.nome2 = "nome2 - " + nome;
return {
mostra: function() {
document.writeln('Nome:' + nome + '< br / >');
document.writeln('Telefone:' + telefone + '< br / >');
}
};
}


A função "mostra" do objeto retornado no código acima, por estar definida dentro da função pessoa, tem acesso às variáveis "nome" e "telefone".

O interessante é que mesmo depois de a função pessoa ter sido executada, o objeto continua tendo acesso àquelas variáveis. Isto quer dizer que se chamarmos:


p = pessoa('joao','3344 5678');


vai acontecer o seguinte:

1 - a função pessoa será executada declarando as variáveis "nome" e "telefone"
2 - ela vai retornar um objeto, definido por um código JSON, com um método mostra()
3 - este método mostra vai ter acesso às variáveis "nome" e "telefone" já declaradas.
4 - como a função já foi executada, não temos mais como mexer nas variáveis "nome" e "telefone" a não ser pelo "mostra".
5 - com isso criamos um escopo "privado" para as variaveis definidas.

O mesmo método pode ser usado para retornar uma função:


mostraLista = function(nome,telefone) {
var lista = {'segredo1':'noite','segredo2':'dia'};
return function() {
for(i in lista) {
document.writeln(i + ':' + lista[i] + '< br / >');
}
}
}();


Neste caso repare que depois da declaração já executamos a função. Com isso fazemos o seguinte:

1 - a função é executada declarando o objeto "lista";
2 - ela retorna uma outra função, que fica atribuida a "mostraLista"
3 - esta função retornada fica com acesso "privado" a variável "lista"

assim podemos chamar


mostraLista();


para que este método seja executado com acesso ao objeto. Porém não podemos acessar diretamente por "mostraLista.lista" pois este objeto não existe, o que existe é o acesso dele à variável da função que já foi executada. Caso você queira experimentar, veja que o valor será igual a "undefined".