Tag Archives: mootools
Hi,
maybe this could sound obvious but is something that i didn’t know till a few days ago when i was making some changes on a js code i made. like the title says, the each() function used in mootools to apply a code to each element in the array, do not work with associative arrays.
so basically if you have this code:
var myArray=new Array();
myArray["key1"]="value1";
myArray["key2"]="value2";
myArray.each(function (item, index){
//do stuff
});
will not work, simply will not execute the loop on each array element. to fix this, you need to use the for loop like this:
var myArray=new Array();
myArray["key1"]="value1";
myArray["key2"]="value2";
for(key in myArray){
//do stuff
}
dunno if this is a mootools bug or was designed to work like this, but i hope this help you and save you time in debugging when you are using associative arrays.
update: from the comments below, let’s clarify some things:
*there is no associative arrays in javascript, they are objects, and i was wrong, indeed you can process it using the solution that Dimitar Christoff posted
var myArray= {};
myArray["key1"]="value1";
myArray["key2"]="value2";
Object.each(myArray, function (item, key){
console.log(item, key);
});
*when you process the object like this, you need to check that you are not processing the js methods that mootools define, personally i stop processing the object after i found the “$family” key, in the comments recommend to use the hasOwnProperty() function but i don’t see why is better or different than mine, if you know it, post it
thanks for the comments, i recognize when i’m wrong, for your collaboration, i’m a bit a better dev
Regards,
Shadow.
Related Post
Hi,
recently, i have a problem with the flash content in a page that is customized by the user. the problem was that i popup a div with a higher z-index to show some info, this popup was not showing it in front of flash or youtube embed videos. and to make it more difficult, this content was load using ajax and even that i could filter the information or the html code, i prefered to make it using javascript.
here i will share with you the function that process all the objects, embed and youtube iframe tags and set the wmode that you want to them.
function setWmode(mode,reinsert,youtube){
if(youtube==true){
var allIframes=$(document.body).getElements('iframe');
allIframes.each( function (item, index){
if(item.get('src').test('http:\/\/www.youtube.com\/embed\/')){
item.set('wmode',mode);
item.set('src',item.get('src')+"?wmode="+mode);
if(reinsert==true){
var newElem= item.clone(true,true);
var parentElem= item.getParent();
item.destroy();
parentElem.grab(newElem);
}
}
});
}
var allObjects=$(document.body).getElements('object');
allObjects.each(function (item, index){
var allParams=item.getChildren('param');
var WmodeExist=false;
allParams.each(function (item2, index2){
if(item2.get('name')=='wmode'){
item2.set('value',mode);
WmodeExist=true;
}
});
if(WmodeExist==false){
item.grab(new Element('param', {name: 'wmode',value: mode}));
}
if(reinsert==true){
var newElem= item.clone(true,true);
var parentElem= item.getParent();
item.destroy();
parentElem.grab(newElem);
}
});
var allEmbed=$(document.body).getElements('embed');
allEmbed.each(function (item, index){
item.set('wmode',mode);
if(reinsert==true){
var newElem= item.clone(true,true);
var parentElem= item.getParent();
item.destroy();
parentElem.grab(newElem);
}
});
}
this function requires of 3 paramenters:
mode: the value of wmode to set
reinsert: what this make is, clone the iframe/object/embed, erase the original and insert it again on the same location. this is made when you load the content before you set the wmode, so you can restart the load of the flash object and the wmode will have effect.
youtube: process or not youtube videos
i hope it help you in some way and save you maybe some time
Regards,
Shadow.
Related Post
Hi,
i’m still with the images stuff
now i needed to integrate a crop image script using js. so i started to look for a premade solution. you can find several of them here, here and here. i was looking for a mootools based solution and i found 4. for my surprise,one didn’t exist anymore, one of them didn’t worked with mootools 1.2, the others was too complicated and not flexible and none offer what i really needed, that was able to offer “mirrors” as preview of the crop in 2 different sizes. in my adventure, i tried to fix the first one (MooCrop) porting it to 1.2 but i leave it why it would take me too much work, then i tried to modify cwCrop but the code structure seems to be less flexible, and finally i decided to go with uvumiCrop, as it already have a mirror function and just need to be converted into a multi-div function.
so for those who want the mirror feature in the uvumiCrop script, here are the functions and code you need to replace:
Add this to the class var declaration
previewImageArray:new Array(),
On some place around line 102, paste this
this.previewImageArray = new Array();
replace with this from lines 285 to 354
if(this.options.preview){
if(isArray(this.options.preview)){
var previewImgObjArray=new Array();
this.options.preview.each(function (item,index){
var initWidth= $(item).getStyle('width');
var initHeight= $(item).getStyle('height');
//we put the preview in a wrapper div with a fixed height, because preview height and width may change.
var previewWrapperObj = new Element('div',{
styles:{
height:initHeight
}
}).wraps($(item));
//Setting the preview container
$(item).setStyles({
display:'block',
position:'relative',
width:initWidth,
height:initHeight,
overflow:'hidden',
margin:'auto',
fontSize:0,
lineHeight:0,
opacity:1,
visibility: 'visible'
});
//cloning the original image for the preview
var previewImageObJ = this.target.clone();
previewImageObJ.set('id','imgObj_'+index);
previewImageObJ.removeProperties('width','height').setStyle('position','absolute').inject($(item));
previewImgObjArray.push(new Array('imgObj_'+index,item,initWidth,initHeight));
}.bind(this));
this.previewImageArray=previewImgObjArray;
}else{
if($(this.options.preview)){
this.preview = $(this.options.preview);
//we put the preview in a wrapper div with a fixed height, because preview height and width may change.
this.previewWrapper = new Element('div',{
styles:{
height:this.previewSize.y+2*this.preview.getStyle('border-width').toInt()+this.preview.getStyle('margin-top').toInt()+this.preview.getStyle('margin-bottom').toInt()
}
}).wraps(this.preview);
}else{
var previewWrapper = new Element('div',{
'class':'preview'
}).inject(this.toolBox,'top');
this.preview = new Element('div').inject(previewWrapper)
}
//Setting the preview container
this.preview.setStyles({
display:'block',
position:'relative',
width:this.previewSize.x,
height:this.previewSize.y,
overflow:'hidden',
margin:'auto',
fontSize:0,
lineHeight:0,
opacity:0
});
//cloning the original image for the preview
this.previewImage = this.target.clone();
this.previewImage.removeProperties('width','height').setStyle('position','absolute').inject(this.preview);
// this.addEvent('onPreview',this.updatePreview.bind(this));
}
this.addEvent('onPreview',this.updatePreview.bind(this));
}
replace updatePreview function with this code below:
//Function to update the preview
updatePreview: function(top,left,width,height){
if(this.previewImageArray.length>0){
this.previewImageArray.each(function (item,index){
if(height*item[2].toInt()/width<item[3]){
$(item[1]).setStyles({
width:item[2],
height:(item[3].toInt()*height/width).toInt()
});
$(item[0]).setStyles({
width:(this.target_coord.width*item[2].toInt()*this.scaleRatio/width).toInt(),
height:'auto',
top:-(top*item[2].toInt()/width).toInt(),
left:-(left*item[2].toInt()/width).toInt()
});
}else{
$(item[1]).setStyles({
height:item[3],
width:item[3]
});
$(item[0]).setStyles({
height:(this.target_coord.height*item[3].toInt()*this.scaleRatio/height).toInt(),
width:'auto',
top:-(top*item[3].toInt()/height).toInt(),
left:-(left*item[3].toInt()/height).toInt()
});
}
}.bind(this));
}else{
if(height*this.previewSize.x/width<this.previewSize.y){
this.preview.setStyles({
width:this.previewSize.x,
height:(this.previewSize.x*height/width).toInt()
});
this.previewImage.setStyles({
width:(this.target_coord.width*this.previewSize.x*this.scaleRatio/width).toInt(),
height:'auto',
top:-(top*this.previewSize.x/width).toInt(),
left:-(left*this.previewSize.x/width).toInt()
});
}else{
this.preview.setStyles({
height:this.previewSize.y,
width:(this.previewSize.y*width/height).toInt()
});
this.previewImage.setStyles({
height:(this.target_coord.height*this.previewSize.y*this.scaleRatio/height).toInt(),
width:'auto',
top:-(top*this.previewSize.y/height).toInt(),
left:-(left*this.previewSize.y/height).toInt()
});
}
}
},
and the isArray() function used at the beginning of the code:
function isArray(obj) {
return obj.constructor == Array;
}
so, now in the initialization of the uvumiCrop object, you set the preview property as a array ( new Array(‘id1′,’id2′) ) with the id’s of the divs that will be used as mirrors. is important that you set the width and height of each div before you create the uvumiCrop object. this code will maintain the original behavior of the original script, you can still have the floating mirror and the unique mirror.
is also important to mention that i changed the code so the container don’t get the width and height deformed and work as a container hiding the rest of the image. is done like this so the user can know really how it will look after the crop process.
i have sent this post to the developer, so maybe he include it on the next release
i hope you find this useful and save you some time
Regards,
Shadow.
Related Post
Hi,
recently building a app i was need to suggest data to the user when trying to fill a input. so i look for a js script for this. i usually use mootools for my development in js, so looking for a plugin i found this: Meio.Autocomplete plugin for mootools
is a really nice plugin, between their features, support the inbuilt ajax calls using the Request.JSON method from the mootools framework. also support to set up filter for the returned data, the set of field parameter to look for the input by the user, the minimum of characters that the user need to enter to start looking for it, delay between the ajax call and the search in the data and many other properties. you can also customize the look and feel of how the options are displayed.
from their web page you can download the source code and the compressed version for production environments. also there you can see plenty of documentation explaining each property of the plugin and several examples to see and try online.
i hope it help you in some way
Regards,
Shadow.
Related Post
Hi,
one of the task i was need to do, was to write a javascript funtion to serialize a array, so can be sent through ajax.
the task wasn’t easy, why searching on the web i only found partially working functions (some that only proccess numerical arrays, other even’t didn’t worked, and wasn’t recursive) but serching i come up with the perfect javascript serialize function ever
in resume it can:
- parse numerical arrays
- associative arrays
- mixed arrays
- multidimensional arrays
- it detect if the index or values of the element it’s int or string and parse it accordingly
- mootools compatible (read below what i mean with this
so i dont want you wait anymore, here it’s the function:
function serializeArray(ArrayElem)
{
var cont=”";
var counts=0;
var jj;
var res = “”;for(jj in ArrayElem)
{
//if mootools it’s included, this hack prevent that the function parse also the prototype objects
if(jj==”$family”){
res = ‘a:’+counts+’:{‘;
res += cont;
res += ‘}’;
return res;
}
if(isInt(jj)){
cont += ‘i:’+jj+’;';
}else{
cont += ‘s:’+jj.length+’:”‘+jj+’”;’;
}
if(isArray(ArrayElem[jj])){
cont += serializeArray(ArrayElem[jj]);
}else{
if(isInt(ArrayElem[jj])){
cont += ‘i:’+ArrayElem[jj]+’;';
}else{
cont += ‘s:’+ArrayElem[jj].length+’:”‘+ArrayElem[jj]+’”;’;
}
}
counts++;
}res = ‘a:’+counts+’:{‘;
res += cont;
res += ‘}’;return res;
}function isArray(obj) {
return obj.constructor == Array;
}
function isInt(myNum) {
// get the modulus: if it’s 0, then it’s an integer
var myMod = myNum % 1;if (myMod == 0) {
return true;
} else {
return false;
}
}
i going to explain some things about this function:
- the isInt() function it’s very simple, i dont know if it can fail with some weird value, but at least it’s fast and cross browser compatible
- i’m using a counter and not the length propertie of the array why with associative array it return 0
- as you see, there it’s a hack for mootools, that it’s it make it “compatible”, whiteout that hack the function also parse all the native properties and elements added at the moment when you add mootools to the document. i didn’t know any other form to stop it, so if you know something advise
- in the php that receive the serialized array, remember to use stripslashes if the magic quotes are ON and maybe you going to need to use html_entity_decode() (at least that was my case) to convert the doble quotes character to signs.
i hope it help you, it’s very easy to use and understand and can save you some hours of work
Regards,
Shadow





