Monday, August 24, 2009

jQuery: open a widescreen dialog (in top.document) from any nested iframe/frame

A problem that I had some days ago was to open a  dialog with jQuery from a nested iframe but using all the document's width/height. If the dialog is inside of the iframe, the modal view (and the position ) depends just about the iframe scope.

Indeed, every time that you execute a line like  $("#dialogDiv").dialog(), the init will set the parameters about the position  and dimentions of the caller object, i.e., if do you want to make a dialog() call from a iframe/frame that just have a few pixels (or just don't have them), the dialog window will not see ok.


One possible solution is to define a dialog div (with id=dialogDiv) in the top.document file. But we can not activate the dialog from the iframe/frame. To solve this, we need add a javascript code like this in the top.document file:

<script type="text/javascript">
var top.window.docDialog=null;
$(document).ready( function() {
$("#main",top.document).prepend("<div id='dialog' title=''></div>");
top.window.docDialog=$("#dialog");
top.window.docDialog.dialog({
bgiframe: true,
minHeight: 30,
minWidth: 200,
height: 100,
width: 250,
autoOpen: false,
modal: true
});
});
</script>

Where the code is adding a div (id=dialog) inside of another existing div (id=main). Then you assign the jQuery object to a variable of the top.window. Thus, we can locate the docDialog variable from any iframe/frame, allowing us to interact with the dialog div defined.


In this hand, if assume that in the nested iframe/frame an error occurs and want to activate the message (dialog), just use a code like this:

<script type="text/javascript">
top.window.docDialog
.html("<div style='font-size:14px;paddig:0;margin:0;color:#FF1111;'><center>No se puede Ingresar en este momento</center></div>")
.dialog('option', 'title', 'ERROR')
.dialog('open');
</script>

Note that the top.window.docDialog object is a jQuery object. Also, this works with Internet Explorer and FireFox.

Thursday, August 20, 2009

jQuery: To select elements from a iframe/frame


When we use jQuery selectors is necesary to deliver an argument of  document, ie, a HTMLDocument object. The problem is that don't work to use  .document or .contentDocument. To make work both,  IE and FF, we need to use  .contentWindow.document.

Ex: suppose a document with an iframe(id=frame_selector) inside it, and the document inside of the iframe have a form(id=sel_indice). We need to set a input element inside of the form with the count of the checked checkboxes before to run a submit of the form. We can use the follows code:


<script>
function doSubmit() {
var docSel=null;
$('#frame_selector').each( function(){ docSel=this.contentWindow.document;});
$("#sel_indice input[id='Cantidad']",docSel).val($("#sel_indice input[id*='check']",docSel).filter(":checked").length);
$("#sel_indice",docSel).submit();
}
</script>



The important is the second code line. If you try to do a selector like  $("#sel_indice"), without the second argument, you will get a empty array as return of the jQuery selector, because jQuery uses the content of the DOM that include the iframe/frame definition as default  HTMLDocument, but not the DOM contained by the iframe/frame. Again, this works using Internet Explorer or FireFox.

Frame/Iframe Scrolls

margin note:  to avoid frames/iframe's scrolls, use the follow properties : overflow-x y overflow-y.

Ex: style="overflow-x: hidden; overflow-y: auto;"

This shows a vertical scroll if it's necesary and never shows an horizontal scroll.

Thursday, July 30, 2009

Selectors, optimizing time and jQuery

When I  learned  to use jQuery, it was necesary to me to understand the several  kinds of selectors to do the same duty.

To confront the problem of to do the init of  a few Datepicker calendars (10 in total ), the first way was to make the follows selector (class selector):

<script>
$(".datepicker").datepicker();
</script>

The problem of this kind of selector is that each time that you do it, the jQuery do a whole search by all DOM. In fact, to do this sentence takes a few seconds.

Searching a solution to this response time GAP, the selector was changed by the follows code (a for with id selector):

<script>
var arrId=new Array("id0","id1","id2","id3","id4","id5","id6","id7","id8","id9");
for (x in arrId) {
$("#"+arrId[x]).datepicker();
}
</script>

Where the arrID var is a array with the id's by each  element to set as a datepicker. The id selector always be faster because uses the feature of a document.getElementById() search. This code just takes arround a second.

A weakness of DatePicker widget

A jQuery's widget, the datepicker, have many users in the website programming field.

But, nothing in programming is perfect. When a webpage includes several calendars (datepicker objects), the init process for each calendar gives atime gap undesired.
Testing in a PC(intel core 2 duo), when init the datepicker calendars, you could have a 500ms time wasted by each object.

Of course, the most webpages have just 1 or 2 calendars, but I need a page with 10. Moreover, we needed the calendars with lenguage's distintion, so, when makes the lenguage's settings the init process was slower.
Apparently, the code .datepicker(option, {var:valor, var:valor}) or options set later to init take more time in the execution than realy we  want. I don't check the sources yet, but in facts, it's clear that for each sentence to init a calendar we produce a time gap when set options.

How to solve this?
By now, we add a previous code (execute on server side, like PHP or ASP code) that using the lenguage defined by the page's user inserts a javascript like this before to init the calendars:


<script>
jQuery(function($){
$.datepicker.setDefaults($.datepicker.regional['es']);
});
</script>


With this reduce the load time from 5 to 1 second.

Friday, July 24, 2009

Publishing HTML code

To publish HTML code in a blog, is necesary to write the code as an "entity-encoded markup". To don't do it by hand, there is a site called simpleCode that does it easier as a copy and paste.

Just need to visit the form and use it.

The important link: http://www.simplebits.com/cgi-bin/simplecode.pl?mode=process.

Internet Explorer and CSS classes

Programming with jQuery an interactive menu to my work website, I realize a curious behavior of Internet Explorer(IE), why not.

Everytime that you  use jQuery code like this: 

$(this).addClass("clicked");

You will see an erratic behavior. If the element (this) have more than one class, the IE have problems to resolve the heritance and procedence to finaly apply the desired style. But this works with others browsers like Firefox(FF) or Chrome.

The only way I know to avoid this, it is use the css jQuery function. In facts, this function does a style attribute definition in the element. By example, suppose a li element like the following:

<li id="li_0" class="classLi otherClass andOtherClass">
<a href="#">Testing element</a>
</li>


and run this jQuery code:

$("#li_0").css( { 'background-color' : '#C0C0C0', 'color': '#FFFFFF'} );

The li element inside the DOM will be setting like this:

<li id="li_0" class="classLi otherClass andOtherClass" style="background-color: #C0C0C0; color: #FFFFFF;">
<a href="#">Testing Element</a>
</li>


And because the style attribute of an element has dominance over every previous CSS definitions, you will get the desired effect. Using this, IE and FF can have the same final behavior.

Useful link: http://www.visualjquery.com/