Tag: javascript
json decode fails on non utf-8
by z3n on Mar.16, 2010, under Coding, Tips & Hints
Problem:
When sending a non utf-8 string as json, the decoding fails.
Solution:
PHP works as utf-8 as default, since i’m using strings with accents (áéíóú..) those are taken as iso-8859-1. Client-side script will not send as utf-8, not even if you force it, so the best solution is convert the json object’s encoding. You may also want to encode your string as plain chars (I use base64) to avoid issues with IE.
Code would look like this:
$json=json_decode(iconv(‘ISO-8859-1′,’UTF-8′,base64_decode($input)),true);
If you’re working with different charsets just change the iso-8859-1, remember that if you’re working with multibyte chars, such as japanese, chinese, etc, you will need to use the mb functions instead.
Sources:
Pablo Viquez (A solution pretty much like mine but for sending data instead)
Gracefully overriding fixed width/height divs
by z3n on Feb.25, 2010, under Coding, Tips & Hints
Problem:
It’s like a industry standard now having everthing tableless, although i still thinking that EVERYTHING is too much, this been like the motto of many programmers around. But let’s skip the blablaing about this and go straight to the point:
You have 2 fixed width div/li `rows` on a site, they are nested and inside the content, due the complex nature of the layout, there’s some other complications. All of sudden the client decides that he wants to ruin your layout adding a long, waaaaaaaaay long, horizontal listing, which not also overlapps the width of your left column but mostly like will make user’s screen to horizontally scroll.
Solution:
As much i like to discuss with client, it’s useless and i will be just wasting my time. This is also a tricky thing to fix since the column sizes are fixed, i would need to make the whole content column bigger, ruining the rest of the top elements. Let’s take a look on the example:
<div style=”width:600px”>
content div header code here
<div style=”width:2000px”>
way long client designed div to ruin layouts
</div>
</div>
(styles are just to simplifly)
so the solution (1) would be something like this:
<div style=”width:600px”>
content div header code here
<div style=”width:2000px;position:absolute;“>
way long client designed div to ruin layouts
</div>
<img src=”blank_image.gif” width=1 height=same height as the long width div>
</div>
solution (2), if your abomination div is also height dynamic:
<div style=”width:600px” id=”container”>
content div header code here
<div style=”width:2000px;position:absolute;” id=”abomination”>
way long client designed div to ruin layouts
</div>
</div>
<script type=”text/javascript”>
// after loading all the content of the abomination div, also assuming that you’re using jquery
$(“#container”).height(parseFloat($(“#abomination”).height()+50)+”px”);
</script>
Reset jwysiwyg
by z3n on Jan.15, 2010, under Coding, Games and Gaming
Problem:
jquery’s extension jwysiwyg can’t be reseted on fly, calling the function again will just append another editor.
Solution:
You will need to do a workaround by adding the jwysiwyg object inside a container then resetting it using this little function:
-
function _reset_jwysiwyg(h,x,j){ // html, first id, second id
-
h=str_replace("\\","",h); // this requires php.js to work, can be removed if you don't add slashes on your vars
-
$("#cf"+x+""+j).html("<textarea id='#f"+x+""+j+"' class='jwysiwyg' name='jwysiwyg' cols=94 rows=30>"+h+"</textarea>");
-
$(".jwysiwyg").wysiwyg({
-
html: h
-
// you may want to add other control options here
-
});
-
}
this will work for this setup:
<span id=’c12′><textarea id=’f12′ class=’jwysiwyg’ name=’jwysiwyg’ cols=94 rows=30></textarea></span>
on this example it will be called as:
_reset_jwysiwyg(“”,1,2);
Note
this function is a snippet from my code, you might not want the identifiers just the div name, that makes it less complicated.
The Ampersand (&) XML Problem
by z3n on Sep.26, 2009, under Coding
Problem:
Having ampersands (&) on a xml makes it non-compliant, causing errors on IE.
Solution:
I’ve been looking on this issue for a while, although I had the answer already I wanted an alternate. One said that you could turn the & into & html entity or it’s ASCII code, but this just gets into another issue, since the & will still there – & & – In my case I had accents encoded as html entities, like áéíóú, which must be encoded (at least on my project) as entities to be passed as xml/json/etc. Other people noted that it’s possible to have specific entities declared on the html header, although this is a drawback, because xml will become quite big if you have too many different entities AND you will have to redeclare them on every reply.
None of the solutions I’ve found were good, so I’m posting mine.
A simple base64 encode would resolve the issue, and you only need to do it on replies, making things easier, so you send as base64 and the user with a little javascript decodes it back.
Base64 Javascript Source Code:
-
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
-
function _enc(input) {
-
var output = "";
-
var chr1, chr2, chr3;
-
var enc1, enc2, enc3, enc4;
-
var i = 0;
-
do {
-
chr1 = input.charCodeAt(i++);
-
chr2 = input.charCodeAt(i++);
-
chr3 = input.charCodeAt(i++);
-
-
enc1 = chr1 >> 2;
-
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
-
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
-
enc4 = chr3 & 63;
-
-
if (isNaN(chr2)) {
-
enc3 = enc4 = 64;
-
} else if (isNaN(chr3)) {
-
enc4 = 64;
-
}
-
-
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
-
keyStr.charAt(enc3) + keyStr.charAt(enc4);
-
} while (i < input.length);
-
-
return output;
-
}
-
-
function _dec(input) {
-
if (input == "NULL") { return ""; }
-
var output = "";
-
var chr1, chr2, chr3;
-
var enc1, enc2, enc3, enc4;
-
var i = 0;
-
-
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
-
input = input.replace(/[^A-Za-z0-9\+\/\=]/g|>, "");
-
-
do {
-
enc1 = keyStr.indexOf(input.charAt(i++));
-
enc2 = keyStr.indexOf(input.charAt(i++));
-
enc3 = keyStr.indexOf(input.charAt(i++));
-
enc4 = keyStr.indexOf(input.charAt(i++));
-
-
chr1 = (enc1 << 2) | (enc2 >> 4);
-
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
-
chr3 = ((enc3 & 3) << 6) | enc4;
-
-
output = output + String.fromCharCode(chr1);
-
-
if (enc3 != 64) {
-
output = output + String.fromCharCode(chr2);
-
}
-
if (enc4 != 64) {
-
output = output + String.fromCharCode(chr3);
-
}
-
} while (i < input.length);
-
-
return output;
-
}
jQuery hoverpulse different image ratio fix
by z3n on Aug.18, 2009, under Coding
The jQuery’s extension hoverpulse created allows you to have images that resize themselfs on a mouse hover, very usefull when you need to have larger thumbs without showing the full image like other extensions does.
However hoverpulse has a issue when it comes to resize non square images, it simply stretches them, so I wrote this little custom version of hoverpulse in order to have this gap filled:
Links:
little jQuery to loop through checkboxes
by z3n on Aug.18, 2009, under Coding
This is a little function to loop throught a specific form or id with checkboxes, it will check if the checkbox is checked and then you can `do something`.
-
function (what)
-
{
-
jQuery.each(jQuery("#"+what+" :checkbox"),function(){
-
if (jQuery(this).is(':checked')) {
-
// do something
-
}
-
});
-
}
Keep it simple, stupid jQuery experience
by z3n on Aug.14, 2009, under Coding, Notes
As much as I like jQuery I must admit that it’s far away from simplifying things. Although it might be a great idea using it on 100% jQuery scripts, it’s a real bad idea using it to refurbish an old script.
Today I’ve spent over 2 hours implement jQuery on a old script I have, and I felt into so many issues that it didn’t worth at all.
My script was simple, I had a huge variable list that could be edited by a form, script loops through the variables building a form with input fields for each variable. I will not get into specific details because it’s boring, but I needed to allow the user to add a new variable inside an array, so i thought that jQuery would help a lot since i only would need to dynamic add a new input field as needed then post everything back to script to save the file.
First I spent an hour figuring out that jQuery was ruining the text by converting the whole thing into UTF-8, loosing all the accents, eventually I found out about contentType encoding ajax variable:
contentType:"application/json; charset=utf-8"
which could be changed to the charset i wanted.
It was useless, jQuery still posting into the wrong charset, there’s some other tweks on this, but they are also useless.
I was able to fix the accent issue with this php statement:
mb_convert_encoding(urldecode($variable),”ISO-8859-1″,”auto”);
This is much more obscure though, but I was familiar with it since i coded in japanese charsets which are a pain to convert.
After having this cleared, and searching a lot of useless blogs and postings, turns out that jQuery was using the hard coded form names to post the data, which could be overlapped by an dynamic added field, I did a script to change the name of the hard coded inputs, something like this:
$(“#field_id”).attr(’name’,’new_name’);
Theorically, it worked, but when I did:
$(“#form”).serialize();
jQuery used the dynamic fields with the ordinary hard coded ignoring the attr changes.
Now I had to add a handler to dynamic convert and read all the inputs and do my own serialize in order to TRY to make it work…and that’s because i didn’t tested it on IE yet.
So that’s when I quit using jQuery for this script and do something plain and simple, which took me about 20 minutes and 0 searches.
It looks like that if I had used DOM elements for the whole form, all elements generated by jQuery itself, not hard coded, i would have less trouble with the form, although, the charset issues still.
Super Fun Sources:
jQuery Ajax Documentation (completly useless since contentType explanation has 2 lines)
Calling a Javascript function from a different frame
by z3n on Jun.09, 2009, under Coding, Tips & Hints
Problem:
How to call a function from a different frame/iframe ?
Solution:
It depends where the function is, when it’s on the main frame, or if you’re calling a funcion that’s on _top from inside a iframe:
top.function();
If you’re calling a function from a frame to another:
parent.frames['frame_name'].function();
or
parent.frames[frame_number].function();
Javascript to get the whole document width and height
by z3n on May.25, 2009, under Coding, Tips & Hints
Problem:
How to get document’s height and width, not only the view area or the window size, but the whole thing including the scrolling.
Solution:
There are some variants of this solution, because some browsers take this proprieties in a different way, however, here’s a little function i wrote able to return the right dimensions no matter what:
with (document.documentElement) {
var h=Math.max(clientHeight,scrollHeight);
var w=Math.max(clientWidth,scrollWidth);
}
there’s also the inner values, but they only work on certain browsers, this would be able to get the numbers you need on IE6+ , FF and mostly of the decent browsers, if you must have working on every browser check quirksmode. This will also return the highest value, meaning that if the page itself won’t fill client’s width/height, it will get the biggest value, perfect when you need to do a full page div or something like that.
Sources:
Simple AJAX/xmlhttp query issue
by z3n on May.20, 2009, under Coding, Tips & Hints
Problem:
You like jQuery, however, doing simple tasks get impossible since jQuery is too massive, even packed it’s over 50kb. The alternate, script.taculo.us, is even bigger!
Solution:
Doing a simple ajax or xmlhttp request, is nothing out of this world, actually, it’s pretty easy, you just need to watch it if you do more than one on the same page, or when a error happen you might want to have a handler.
Based on quirks mode example i wrote this little function, it’s able to do a rudimentar queue and return plain text from a remote server, it’s also compatible with IE.
-
_lD=function(url){
-
if(p==1){
-
setTimeout("_lD('"+url+"')",250);
-
}else{
-
p=1;
-
x=null;
-
if(window.XMLHttpRequest){
-
x=new XMLHttpRequest();
-
}else if(window.ActiveXObject){
-
x=new ActiveXObject("Microsoft.XMLHTTP");
-
}
-
if(x!=null){
-
x.onreadystatechange=function(){
-
var r="";
-
if(x.readyState==4){
-
if(x.status==200){
-
r=x.responseText;
-
-
// manipulate your result here
-
-
p=0;
-
}
-
}
-
}
-
x.open("GET",url,true);
-
x.send(null);
-
}
-
}
-
}
Packed, this function is less than 500 bytes, much better than the 58kb of jQuery, heheh