jQuery debug plugin – print_r style output

The other day I was searching for some Javascript that could output objects and stuff in a similar fashion to PHP’s print_r function, with indentation and all. In the end I ended up combining two different scripts, a simple one that focuses mostly on the presentation, and one that focuses more on the true recursiveness that is required.

When writing this piece I had to search for the two above articles and then I found another piece detailing yet another print_r clone. There I also learned about Firebug’s console.log(). Due to this functionality in Firebug Matt claims a custom print_r function is only useful in edge cases.


I beg to differ, if I didn’t miss something the output is not very well formatted in Firebug, no indentation and so on, if you need to view a big array or object it will give you a headache. Neither does it seem to be outputting infinite depth.

Update: I just had to debug structures containing markup, therefore the function now accepts a third parameter, true/false. True if we want to encode the output (which we want in my case). The code listing below has been updated. See Decoding/Encoding HTML with jQuery for more information on the subject of encoding and decoding HTML with JavaScript.

Update: Doing document.write() was a very very bad idea when more advanced jQuery stuff is going on at the same time, it completely choked up Firefox. This is how the print_r function needs to look:

function encHTML(str){
   return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

(function($){
  $.debug = {
    dump: function(arr, level, enc) {
      var dumped_text = "";
      if(!level) level = 0;
      var level_padding = "";
      for(var j=0;j<level+1;j++) level_padding += "    ";
      if(typeof(arr) == 'object') { //Array/Hashes/Objects
       for(var item in arr) {
        var value = arr[item];
       
        if(typeof(value) == 'object') { //If it is an array,
         dumped_text += level_padding + "'" + item + "' ...\n";
         dumped_text += $.debug.dump(value,level+1);
        }else if(typeof(value) == 'string'){
         value = enc == true ? encHTML(value) : value;
         dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
        } else {
         dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
        }
       }
      } else { //Stings/Chars/Numbers etc.
       dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
      }
      return dumped_text;
    },
    print_r: function(obj, contId){
      $("#"+contId).removeClass().css({
        display: "block",
        position: "absolute",
        top: "0px",
        right: "0px",
        padding: "10px",
        width: "700px",
        height: "auto",
        background: "#ddd",
        color: "black",
        border: "solid 1px black",
        zIndex: 1000
      }).html("<pre>"+$.debug.dump(obj)+"</pre><div id='close-debug'>Close</div>");
      
      $("#close-debug").css({cursor: "pointer"}).click(function(){
        $("#"+contId).remove();
      });
    }
  };
})(jQuery);

The dump function is basically just a copy paste of Binny‘s code. Note the recursiveness and use of a variable to keep track of which level we are on, in order to get the indentation correct.

This is how you can test both the above and Firebug’s console.log(), which output is the easier one to read?

<html>
<head>
<title>test</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="print_r.js"></script>
</head>
<body>
<script>
var arr = [1, 2, {javascript: "interpreted", anobject: {java: "compiled"}, anarray: [1, 2, "three"]}, [1, 2, 3]];
$.debug.print_r(arr, "printOut", false);
console.log(arr);
</script>
<div id="printOut"></div>
</body>
</html>

And finally the result:

screenshot-1.png

My Firebug output:

[1, 2, Object javascript=interpreted anobject=Object anarray=[3], [1, 2, 3 0=1 1=2 2=3]]


Related Posts

Tags: , , , ,