Archive for javascript

voFactory

I use a lot value objects (VO) in Javascript storing JSON content and it is quite boring to create a new VO. So i did a factory to automate the process.

Create a new VO:
var TestVO = AMF.voFactory([
    ['name', {type: 'string'}],
    ['age', {type: 'int'}],
    ['height', {type: 'float'}],
    ['friends', {type: 'array', defaultValue: null, addName: 'friend'}],
    'x',
    ['y', {}]
]);

Create a new instance on t:
var t = new TestVO();

Set values:
t.setName('My Name');
t.setAge(28);
t.setHeight(1.74);
t.setFriends(['Friend A', 'Friend B']);
t.addFriend('Friend C');
t.setX('value X');
t.setY('value Y');

Get values:
t.getName() - My Name
t.getAge() - 28
t.getHeight() - 1.74
t.getFriends() - Friend A,Friend B,Friend C
t.getX() - value X
t.getY() - value Y
t.toString() -
    name: My Name,
    age: 28,
    height: 1.74,
    friends: [Friend A, Friend B, Friend C],
    x: value X,
    y: value Y
t.serialize() - name=My%20Name&age=28&height=1.74& friends=Friend%20A%2CFriend%20B%2CFriend%20C& x=value%20X&y=value%20Y

Using parse() method (JSON notation):
var v = {'name': 'My New Name', 'age': 29, 'height': 1,76, 'friends': ['Friend D', 'Friend E'], 'x': 'value X2', 'y': 'value Y2'};
t.parse(v);

Get new values:
t.getName() - My New Name
t.getAge() - 29
t.getHeight() - 1.76
t.getFriends() - Friend D,Friend E
t.getX() - value X2
t.getY() - value Y2
t.toString() -
    name: My Novo Name,
    age: 29,
    height: 1.76,
    friends: [Friend D, Friend E],
    x: value X2,
    y: value Y2
t.serialize() - name=My%20Novo%20Name&age=29&height=1.76& friends=Friend%20D%2CFriend%20E& x=value%20X2&y=value%20Y2

The methods parse(), toString() and serialize() are created as default, but you can reewrite anyone as you need.
TestVO.prototype.parse = function() { ... };
TestVO.prototype.toString = function() { ... };
TestVO.prototype.serialize = function() { ... };

Download it here (vofactory.zip 6kb)

Comments (2)

Flickr group admin hack

Do you know how to interact through all the HTML a tags of the document.body and replace the text in each href attribute using javascrit? No? So this page is not for you. Use it at your own risk.

Recently Flickr has changed the group management system by adding a moderator permission. Moderators can moderate photos and monitor discussions, but don’t have all admin powers.

Just after this new feature was launched there was a link on your group that you could demote everybody that had admin powers to regular members. Then you can promote everyone to moderator. Making this simple action very annoying and time consuming. You need to click on promote, ok, confirm with ok again on an alert, wait until the page reloads and go to the moderators tab. After this you need to click on the members tab and do it again with the next user. When you have more than a thousand users on a group it is almost impossible to do it quickly and in a reasonable way.

I have found that you can click on the Promote link to open on a new tab – middle mouse button or Ctrl + click on Firefox – and it works nicely. BUT the link is not right. They send your user from regular member to admin. By using javascript you can fix that.

Copy this piece of code and paste it right over the Flickr url on your group Manage Members page with the members tab opened.

What it does?

javascript:
Tell you browser that you are using a javascript code.
A=document.getElementsByTagName(%22a%22);
Get all a tags and stores it on a A variable.
for(i=0; i<A.length; i++){ ... }
Loops over all the newly found a tags.
if(A[i].href.indexOf(%22promote=admin%22)>-1){ ... }
Check if this a tag has the following string – ‘promote=admin’. We want to change it to ‘promote=moderator’.
A[i].href=A[i].href.replace(%22promote=admin%22, %22promote=moderator%22);
Now we change the href of this a tag to the right string. Using the replace String method we change ‘promote=admin’ to ‘promote=moderator’.
void(null);
This is the return of the method so you can continue on the page you were before using the code.

Now you can click on each link opening a new window (or new tab) to promote your users on a easy way. I hope Flickr creates a new way for administrators to change the user rights on your groups one day.

Comments (5)

formatTable

This is an easy way to dynamic format a HTML table. Instead of go throught every table inserting class names to all ‘tr’ and ‘td’, you can use javascript do it for you. Create your css class, the format object and call the function on window ‘onload’ event.

With this script:

<script type="text/javascript">

var fmt1 = {
	table: 'table1',
	rolls: ['', 'trOdd'],
	cells: ['', 'tdCenter tdBg', '', 'tdCenter tdBg']
}

AMF.formatTableInit = function() {
	AMF.formatTable(fmt1);
}

onload = AMF.formatTableInit;

</script>

And this HTML:

<table id="table1">
	<thead>
		<tr>
			<td style="width:40%">Loren Ipsun</td>
			<td style="width:10%" class="tdCenter">Ono</td>
			<td style="width:40%">Loren Ipsun</td>
			<td style="width:10%" class="tdCenter">Ono</td>
		</tr>
	<thead>
	<tbody>
		<tr>
			<td>Loren Ipsun Dolor</td>
			<td>123</td>
			<td>Loren Ipsun Dolor</td>
			<td>456</td>
		<tr>
		<tr>
			<td>Loren Ipsun Dolor</td>
			<td>123</td>
			<td>Loren Ipsun Dolor</td>
			<td>456</td>
		<tr>
	</tbody>
<table>

You can format your tables anyway you want. From this:
Before

To this:
After

Download it here (formattable.zip 3kb)

Comments (1)

Cross-browser PNG background

Muitas vezes temos problemas para implementar transparência (PNG ou filtro de transparência) com sucesso em todos os browsers sem muita dor de cabeça. Reuni aqui uma forma que acredito seja eficaz porque está tudo no mesmo CSS e não precisa de JavaScript.

O CSS

#box {
    background-image: url(../img/boxBg.png) !important;
    background-image: none;
    filter: none !important;
    filter: progid:DXImageTransform.Microsoft.AlphaImageLoader
(src='img/boxBg.png',sizingMethod='scale');
    position: static;
}

O HTM

<div id="box">
    <p>Conteúdo aqui</p>
</div>

Supondo que você trabalhe com a seguinte árvore de diretórios:

/css/box.css
/img/boxBg.png
/index.htm

Vamos analisar cada linha do CSS:

background-image: url(../img/boxBg.png) !important;
Define a imagem de fundo do elemtento, no caso o div, e o !important define que esta linha é a definição de background-image que vai prevalecer sobre todas as outras declarações desse atributo. Note que o Internet Explorer (IE) 6.0 e anteriores ignora o !important se tiver alguma declaração do mesmo atributo depois dessa linha.
O caminho da imagem quando você usa ela em um .css no background-image é relativo ao arquivo .css.
background-image: none;
Filtro para o IE 6.0 e anteriores. Como ele ignora o !important da linha acima ele não vai mostrar a imagem de fundo no elemento.
filter: none !important;
O, recém lançado, IE 7.0 já trabalha com o comportamento padrão do !important no CSS. Se não existir essa linha, ele vai renderizar dois PNG’s um sobre o outro, já que essa nova versão já tem suporte para PNG de 24bits.
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader
(src='img/boxBg.png',sizingMethod='scale');
Mais uma linha para IE 6.0. Ele vai ignorar o !important da linha anterior e vai usar o filtro para exibir o PNG com todos os níveis de transparência.
O caminho da imagem quando você usa ela em um .css no filter é relativo à página que você está chamando.
No filtro AlphaImageLoader você têm três opções para o atributo sizingMethod:

  • sizingMethod='image' – mantém a imagem do tamanho original, ele “estoura” o tamanho do elemento se a imagem for maior que ele
  • sizingMethod='scale' – redimensiona a imagem pra caber dentro do elemnto, distorcendo ela se for necessário
  • sizingMethod='crop' – corta a imagem do tamanho do elemento
position: static;
Quando o IE 6.0 aplica o filtro, ele renderiza todo o conteúdo e o elemtento fica “chapado” como se fosse uma imagem. Links (a), campos de formulário (input) e outros elementos, perdem o seu comportamento padrão e os eventos não funcionam para o elemento. Para resolver esse problema usamos position: static; que contorna essa falha de renderização. Se for necessário posicionar o elemento na tela vai ser necessário colocá-lo dentro de um container (div) e este elemento “pai” pode ter a posição absoluta ou relativa na tela.

Essa solução tem se mostrado ideal nos projetos que tenho trabalhod. Foi testado no Firefox 1.5, Internet Explorer 5.5; 6.0; 7.0 e Opera 9.0, todos rodando Windows XP. Fico agradecido se alguém conseguir testar em outros sistemas operacionais, pricipalmente Macintosh.

Comments (10)