Translation update done using Pootle.
[phpmyadmin/dkf.git] / js / functions.js
blobe49d5d09f22776ee01e4603b16c875a8a5038330
1 /* vim: set expandtab sw=4 ts=4 sts=4: */
2 /**
3  * general function, usally for data manipulation pages
4  *
5  * @version $Id$
6  */
8 /**
9  * @var sql_box_locked lock for the sqlbox textarea in the querybox/querywindow
10  */
11 var sql_box_locked = false;
13 /**
14  * @var array holds elements which content should only selected once
15  */
16 var only_once_elements = new Array();
18 /**
19  * @var ajax_message_init   boolean boolean that stores status of
20  *      notification for PMA_ajaxShowNotification
21  */
22 var ajax_message_init = false;
24 /**
25  * selects the content of a given object, f.e. a textarea
26  *
27  * @param   object  element     element of which the content will be selected
28  * @param   var     lock        variable which holds the lock for this element
29  *                              or true, if no lock exists
30  * @param   boolean only_once   if true this is only done once
31  *                              f.e. only on first focus
32  */
33 function selectContent( element, lock, only_once ) {
34     if ( only_once && only_once_elements[element.name] ) {
35         return;
36     }
38     only_once_elements[element.name] = true;
40     if ( lock  ) {
41         return;
42     }
44     element.select();
47 /**
48  * Displays an confirmation box before to submit a "DROP DATABASE" query.
49  * This function is called while clicking links
50  *
51  * @param   object   the link
52  * @param   object   the sql query to submit
53  *
54  * @return  boolean  whether to run the query or not
55  */
56 function confirmLinkDropDB(theLink, theSqlQuery)
58     // Confirmation is not required in the configuration file
59     // or browser is Opera (crappy js implementation)
60     if (PMA_messages['strDoYouReally'] == '' || typeof(window.opera) != 'undefined') {
61         return true;
62     }
64     var is_confirmed = confirm(PMA_messages['strDropDatabaseStrongWarning'] + '\n' + PMA_messages['strDoYouReally'] + ' :\n' + theSqlQuery);
65     if (is_confirmed) {
66         theLink.href += '&is_js_confirmed=1';
67     }
69     return is_confirmed;
70 } // end of the 'confirmLinkDropDB()' function
72 /**
73  * Displays an confirmation box before to submit a "DROP/DELETE/ALTER" query.
74  * This function is called while clicking links
75  *
76  * @param   object   the link
77  * @param   object   the sql query to submit
78  *
79  * @return  boolean  whether to run the query or not
80  */
81 function confirmLink(theLink, theSqlQuery)
83     // Confirmation is not required in the configuration file
84     // or browser is Opera (crappy js implementation)
85     if (PMA_messages['strDoYouReally'] == '' || typeof(window.opera) != 'undefined') {
86         return true;
87     }
89     var is_confirmed = confirm(PMA_messages['strDoYouReally'] + ' :\n' + theSqlQuery);
90     if (is_confirmed) {
91         if ( typeof(theLink.href) != 'undefined' ) {
92             theLink.href += '&is_js_confirmed=1';
93         } else if ( typeof(theLink.form) != 'undefined' ) {
94             theLink.form.action += '?is_js_confirmed=1';
95         }
96     }
98     return is_confirmed;
99 } // end of the 'confirmLink()' function
103  * Displays an confirmation box before doing some action
105  * @param   object   the message to display
107  * @return  boolean  whether to run the query or not
109  * @todo used only by libraries/display_tbl.lib.php. figure out how it is used
110  *       and replace with a jQuery equivalent
111  */
112 function confirmAction(theMessage)
114     // TODO: Confirmation is not required in the configuration file
115     // or browser is Opera (crappy js implementation)
116     if (typeof(window.opera) != 'undefined') {
117         return true;
118     }
120     var is_confirmed = confirm(theMessage);
122     return is_confirmed;
123 } // end of the 'confirmAction()' function
127  * Displays an error message if a "DROP DATABASE" statement is submitted
128  * while it isn't allowed, else confirms a "DROP/DELETE/ALTER" query before
129  * sumitting it if required.
130  * This function is called by the 'checkSqlQuery()' js function.
132  * @param   object   the form
133  * @param   object   the sql query textarea
135  * @return  boolean  whether to run the query or not
137  * @see     checkSqlQuery()
138  */
139 function confirmQuery(theForm1, sqlQuery1)
141     // Confirmation is not required in the configuration file
142     if (PMA_messages['strDoYouReally'] == '') {
143         return true;
144     }
146     // The replace function (js1.2) isn't supported
147     else if (typeof(sqlQuery1.value.replace) == 'undefined') {
148         return true;
149     }
151     // js1.2+ -> validation with regular expressions
152     else {
153         // "DROP DATABASE" statement isn't allowed
154         if (PMA_messages['strNoDropDatabases'] != '') {
155             var drop_re = new RegExp('(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i');
156             if (drop_re.test(sqlQuery1.value)) {
157                 alert(PMA_messages['strNoDropDatabases']);
158                 theForm1.reset();
159                 sqlQuery1.focus();
160                 return false;
161             } // end if
162         } // end if
164         // Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement
165         //
166         // TODO: find a way (if possible) to use the parser-analyser
167         // for this kind of verification
168         // For now, I just added a ^ to check for the statement at
169         // beginning of expression
171         var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s', 'i');
172         var do_confirm_re_1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
173         var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
174         var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
176         if (do_confirm_re_0.test(sqlQuery1.value)
177             || do_confirm_re_1.test(sqlQuery1.value)
178             || do_confirm_re_2.test(sqlQuery1.value)
179             || do_confirm_re_3.test(sqlQuery1.value)) {
180             var message      = (sqlQuery1.value.length > 100)
181                              ? sqlQuery1.value.substr(0, 100) + '\n    ...'
182                              : sqlQuery1.value;
183             var is_confirmed = confirm(PMA_messages['strDoYouReally'] + ' :\n' + message);
184             // statement is confirmed -> update the
185             // "is_js_confirmed" form field so the confirm test won't be
186             // run on the server side and allows to submit the form
187             if (is_confirmed) {
188                 theForm1.elements['is_js_confirmed'].value = 1;
189                 return true;
190             }
191             // statement is rejected -> do not submit the form
192             else {
193                 window.focus();
194                 sqlQuery1.focus();
195                 return false;
196             } // end if (handle confirm box result)
197         } // end if (display confirm box)
198     } // end confirmation stuff
200     return true;
201 } // end of the 'confirmQuery()' function
205  * Displays a confirmation box before disabling the BLOB repository for a given database.
206  * This function is called while clicking links
208  * @param   object   the database
210  * @return  boolean  whether to disable the repository or not
211  */
212 function confirmDisableRepository(theDB)
214     // Confirmation is not required in the configuration file
215     // or browser is Opera (crappy js implementation)
216     if (PMA_messages['strDoYouReally'] == '' || typeof(window.opera) != 'undefined') {
217         return true;
218     }
220     var is_confirmed = confirm(PMA_messages['strBLOBRepositoryDisableStrongWarning'] + '\n' + PMA_messages['strBLOBRepositoryDisableAreYouSure']);
222     return is_confirmed;
223 } // end of the 'confirmDisableBLOBRepository()' function
227  * Displays an error message if the user submitted the sql query form with no
228  * sql query, else checks for "DROP/DELETE/ALTER" statements
230  * @param   object   the form
232  * @return  boolean  always false
234  * @see     confirmQuery()
235  */
236 function checkSqlQuery(theForm)
238     var sqlQuery = theForm.elements['sql_query'];
239     var isEmpty  = 1;
241     // The replace function (js1.2) isn't supported -> basic tests
242     if (typeof(sqlQuery.value.replace) == 'undefined') {
243         isEmpty      = (sqlQuery.value == '') ? 1 : 0;
244         if (isEmpty && typeof(theForm.elements['sql_file']) != 'undefined') {
245             isEmpty  = (theForm.elements['sql_file'].value == '') ? 1 : 0;
246         }
247         if (isEmpty && typeof(theForm.elements['sql_localfile']) != 'undefined') {
248             isEmpty  = (theForm.elements['sql_localfile'].value == '') ? 1 : 0;
249         }
250         if (isEmpty && typeof(theForm.elements['id_bookmark']) != 'undefined') {
251             isEmpty  = (theForm.elements['id_bookmark'].value == null || theForm.elements['id_bookmark'].value == '');
252         }
253     }
254     // js1.2+ -> validation with regular expressions
255     else {
256         var space_re = new RegExp('\\s+');
257         if (typeof(theForm.elements['sql_file']) != 'undefined' &&
258                 theForm.elements['sql_file'].value.replace(space_re, '') != '') {
259             return true;
260         }
261         if (typeof(theForm.elements['sql_localfile']) != 'undefined' &&
262                 theForm.elements['sql_localfile'].value.replace(space_re, '') != '') {
263             return true;
264         }
265         if (isEmpty && typeof(theForm.elements['id_bookmark']) != 'undefined' &&
266                 (theForm.elements['id_bookmark'].value != null || theForm.elements['id_bookmark'].value != '') &&
267                 theForm.elements['id_bookmark'].selectedIndex != 0
268                 ) {
269             return true;
270         }
271         // Checks for "DROP/DELETE/ALTER" statements
272         if (sqlQuery.value.replace(space_re, '') != '') {
273             if (confirmQuery(theForm, sqlQuery)) {
274                 return true;
275             } else {
276                 return false;
277             }
278         }
279         theForm.reset();
280         isEmpty = 1;
281     }
283     if (isEmpty) {
284         sqlQuery.select();
285         alert(PMA_messages['strFormEmpty']);
286         sqlQuery.focus();
287         return false;
288     }
290     return true;
291 } // end of the 'checkSqlQuery()' function
293 // Global variable row_class is set to even
294 var row_class = 'even';
297 * Generates a row dynamically in the differences table displaying
298 * the complete statistics of difference in  table like number of
299 * rows to be updated, number of rows to be inserted, number of
300 * columns to be added, number of columns to be removed, etc.
302 * @param  index         index of matching table
303 * @param  update_size   number of rows/column to be updated
304 * @param  insert_size   number of rows/coulmns to be inserted
305 * @param  remove_size   number of columns to be removed
306 * @param  insert_index  number of indexes to be inserted
307 * @param  remove_index  number of indexes to be removed
308 * @param  img_obj       image object
309 * @param  table_name    name of the table
312 function showDetails(i, update_size, insert_size, remove_size, insert_index, remove_index, img_obj, table_name)
314     // The path of the image is split to facilitate comparison
315     var relative_path = (img_obj.src).split("themes/");
317     // The image source is changed when the showDetails function is called.
318     if (relative_path[1] == 'original/img/new_data_hovered.jpg') {
319         img_obj.src = "./themes/original/img/new_data_selected_hovered.jpg";
320         img_obj.alt = PMA_messages['strClickToUnselect'];  //only for IE browser
321     } else if (relative_path[1] == 'original/img/new_struct_hovered.jpg') {
322         img_obj.src = "./themes/original/img/new_struct_selected_hovered.jpg";
323         img_obj.alt = PMA_messages['strClickToUnselect'];
324     } else if (relative_path[1] == 'original/img/new_struct_selected_hovered.jpg') {
325         img_obj.src = "./themes/original/img/new_struct_hovered.jpg";
326         img_obj.alt = PMA_messages['strClickToSelect'];
327     } else if (relative_path[1] == 'original/img/new_data_selected_hovered.jpg') {
328         img_obj.src = "./themes/original/img/new_data_hovered.jpg";
329         img_obj.alt = PMA_messages['strClickToSelect'];
330     }
332     var div = document.getElementById("list");
333     var table = div.getElementsByTagName("table")[0];
334     var table_body = table.getElementsByTagName("tbody")[0];
336     //Global variable row_class is being used
337     if (row_class == 'even') {
338         row_class = 'odd';
339     } else {
340         row_class = 'even';
341     }
342     // If the red or green button against a table name is pressed then append a new row to show the details of differences of this table.
343     if ((relative_path[1] != 'original/img/new_struct_selected_hovered.jpg') && (relative_path[1] != 'original/img/new_data_selected_hovered.jpg')) {
345         var newRow = document.createElement("tr");
346         newRow.setAttribute("class", row_class);
347         newRow.className = row_class;
348         // Id assigned to this row element is same as the index of this table name in the  matching_tables/source_tables_uncommon array
349         newRow.setAttribute("id" , i);
351         var table_name_cell = document.createElement("td");
352         table_name_cell.align = "center";
353         table_name_cell.innerHTML = table_name ;
355         newRow.appendChild(table_name_cell);
357         var create_table = document.createElement("td");
358         create_table.align = "center";
360         var add_cols = document.createElement("td");
361         add_cols.align = "center";
363         var remove_cols = document.createElement("td");
364         remove_cols.align = "center";
366         var alter_cols = document.createElement("td");
367         alter_cols.align = "center";
369         var add_index = document.createElement("td");
370         add_index.align = "center";
372         var delete_index = document.createElement("td");
373         delete_index.align = "center";
375         var update_rows = document.createElement("td");
376         update_rows.align = "center";
378         var insert_rows = document.createElement("td");
379         insert_rows.align = "center";
381         var tick_image = document.createElement("img");
382         tick_image.src = "./themes/original/img/s_success.png";
384         if (update_size == '' && insert_size == '' && remove_size == '') {
385           /**
386           This is the case when the table needs to be created in target database.
387           */
388             create_table.appendChild(tick_image);
389             add_cols.innerHTML = "--";
390             remove_cols.innerHTML = "--";
391             alter_cols.innerHTML = "--";
392             delete_index.innerHTML = "--";
393             add_index.innerHTML = "--";
394             update_rows.innerHTML = "--";
395             insert_rows.innerHTML = "--";
397             newRow.appendChild(create_table);
398             newRow.appendChild(add_cols);
399             newRow.appendChild(remove_cols);
400             newRow.appendChild(alter_cols);
401             newRow.appendChild(delete_index);
402             newRow.appendChild(add_index);
403             newRow.appendChild(update_rows);
404             newRow.appendChild(insert_rows);
406         } else if (update_size == '' && remove_size == '') {
407            /**
408            This is the case when data difference is displayed in the
409            table which is present in source but absent from target database
410           */
411             create_table.innerHTML = "--";
412             add_cols.innerHTML = "--";
413             remove_cols.innerHTML = "--";
414             alter_cols.innerHTML = "--";
415             add_index.innerHTML = "--";
416             delete_index.innerHTML = "--";
417             update_rows.innerHTML = "--";
418             insert_rows.innerHTML = insert_size;
420             newRow.appendChild(create_table);
421             newRow.appendChild(add_cols);
422             newRow.appendChild(remove_cols);
423             newRow.appendChild(alter_cols);
424             newRow.appendChild(delete_index);
425             newRow.appendChild(add_index);
426             newRow.appendChild(update_rows);
427             newRow.appendChild(insert_rows);
429         } else if (remove_size == '') {
430             /**
431              This is the case when data difference between matching_tables is displayed.
432             */
433             create_table.innerHTML = "--";
434             add_cols.innerHTML = "--";
435             remove_cols.innerHTML = "--";
436             alter_cols.innerHTML = "--";
437             add_index.innerHTML = "--";
438             delete_index.innerHTML = "--";
439             update_rows.innerHTML = update_size;
440             insert_rows.innerHTML = insert_size;
442             newRow.appendChild(create_table);
443             newRow.appendChild(add_cols);
444             newRow.appendChild(remove_cols);
445             newRow.appendChild(alter_cols);
446             newRow.appendChild(delete_index);
447             newRow.appendChild(add_index);
448             newRow.appendChild(update_rows);
449             newRow.appendChild(insert_rows);
451         } else {
452             /**
453             This is the case when structure difference between matching_tables id displayed
454             */
455             create_table.innerHTML = "--";
456             add_cols.innerHTML = insert_size;
457             remove_cols.innerHTML = remove_size;
458             alter_cols.innerHTML = update_size;
459             delete_index.innerHTML = remove_index;
460             add_index.innerHTML = insert_index;
461             update_rows.innerHTML = "--";
462             insert_rows.innerHTML = "--";
464             newRow.appendChild(create_table);
465             newRow.appendChild(add_cols);
466             newRow.appendChild(remove_cols);
467             newRow.appendChild(alter_cols);
468             newRow.appendChild(delete_index);
469             newRow.appendChild(add_index);
470             newRow.appendChild(update_rows);
471             newRow.appendChild(insert_rows);
472         }
473         table_body.appendChild(newRow);
475     } else if ((relative_path[1] != 'original/img/new_struct_hovered.jpg') && (relative_path[1] != 'original/img/new_data_hovered.jpg')) {
476       //The case when the row showing the details need to be removed from the table i.e. the difference button is deselected now.
477         var table_rows = table_body.getElementsByTagName("tr");
478         var j;
479         var index = 0;
480         for (j=0; j < table_rows.length; j++)
481         {
482             if (table_rows[j].id == i) {
483                 index = j;
484                 table_rows[j].parentNode.removeChild(table_rows[j]);
485             }
486         }
487         //The table row css is being adjusted. Class "odd" for odd rows and "even" for even rows should be maintained.
488         for(index; index < table_rows.length; index++)
489         {
490             row_class_element = table_rows[index].getAttribute('class');
491             if (row_class_element == "even") {
492                 table_rows[index].setAttribute("class","odd");  // for Mozilla firefox
493                 table_rows[index].className = "odd";            // for IE browser
494             } else {
495                 table_rows[index].setAttribute("class","even"); // for Mozilla firefox
496                 table_rows[index].className = "even";           // for IE browser
497             }
498         }
499     }
503  * Changes the image on hover effects
505  * @param   img_obj   the image object whose source needs to be changed
507  */
509 function change_Image(img_obj)
511      var relative_path = (img_obj.src).split("themes/");
513     if (relative_path[1] == 'original/img/new_data.jpg') {
514         img_obj.src = "./themes/original/img/new_data_hovered.jpg";
515     } else if (relative_path[1] == 'original/img/new_struct.jpg') {
516         img_obj.src = "./themes/original/img/new_struct_hovered.jpg";
517     } else if (relative_path[1] == 'original/img/new_struct_hovered.jpg') {
518         img_obj.src = "./themes/original/img/new_struct.jpg";
519     } else if (relative_path[1] == 'original/img/new_data_hovered.jpg') {
520         img_obj.src = "./themes/original/img/new_data.jpg";
521     } else if (relative_path[1] == 'original/img/new_data_selected.jpg') {
522         img_obj.src = "./themes/original/img/new_data_selected_hovered.jpg";
523     } else if(relative_path[1] == 'original/img/new_struct_selected.jpg') {
524         img_obj.src = "./themes/original/img/new_struct_selected_hovered.jpg";
525     } else if (relative_path[1] == 'original/img/new_struct_selected_hovered.jpg') {
526         img_obj.src = "./themes/original/img/new_struct_selected.jpg";
527     } else if (relative_path[1] == 'original/img/new_data_selected_hovered.jpg') {
528         img_obj.src = "./themes/original/img/new_data_selected.jpg";
529     }
533  * Generates the URL containing the list of selected table ids for synchronization and
534  * a variable checked for confirmation of deleting previous rows from target tables
536  * @param   token   the token generated for each PMA form
538  */
540 function ApplySelectedChanges(token)
542     var div =  document.getElementById("list");
543     var table = div.getElementsByTagName('table')[0];
544     var table_body = table.getElementsByTagName('tbody')[0];
545     // Get all the rows from the details table
546     var table_rows = table_body.getElementsByTagName('tr');
547     var x = table_rows.length;
548     var i;
549     /**
550      Append the token at the beginning of the query string followed by
551     Table_ids that shows that "Apply Selected Changes" button is pressed
552     */
553     var append_string = "?token="+token+"&Table_ids="+1;
554     for(i=0; i<x; i++){
555            append_string += "&";
556            append_string += i+"="+table_rows[i].id;
557     }
559     // Getting the value of checkbox delete_rows
560     var checkbox = document.getElementById("delete_rows");
561     if (checkbox.checked){
562         append_string += "&checked=true";
563     } else {
564          append_string += "&checked=false";
565     }
566     //Appending the token and list of table ids in the URL
567     location.href += token;
568     location.href += append_string;
572 * Displays error message if any text field
573 * is left empty other than port field.
575 * @param  string   the form name
576 * @param  object   the form
578 * @return  boolean  whether the form field is empty or not
580 function validateConnection(form_name, form_obj)
582     var check = true;
583     var src_hostfilled = true;
584     var trg_hostfilled = true;
586     for (var i=1; i<form_name.elements.length; i++)
587     {
588         // All the text fields are checked excluding the port field because the default port can be used.
589         if ((form_name.elements[i].type == 'text') && (form_name.elements[i].name != 'src_port') && (form_name.elements[i].name != 'trg_port')) {
590             check = emptyFormElements(form_obj, form_name.elements[i].name);
591             if (check==false) {
592                 element = form_name.elements[i].name;
593                 if (form_name.elements[i].name == 'src_host') {
594                     src_hostfilled = false;
595                     continue;
596                 }
597                 if (form_name.elements[i].name == 'trg_host') {
598                     trg_hostfilled = false;
599                     continue;
600                 }
601                 if ((form_name.elements[i].name == 'src_socket' && src_hostfilled==false) || (form_name.elements[i].name == 'trg_socket' && trg_hostfilled==false))
602                     break;
603                 else
604                     continue;
605             }
606         }
607     }
608     if (!check) {
609         form_obj.reset();
610         element.select();
611         alert(PMA_messages['strFormEmpty']);
612         element.focus();
613     }
614     return check;
618  * Check if a form's element is empty
619  * should be
621  * @param   object   the form
622  * @param   string   the name of the form field to put the focus on
624  * @return  boolean  whether the form field is empty or not
625  */
626 function emptyCheckTheField(theForm, theFieldName)
628     var isEmpty  = 1;
629     var theField = theForm.elements[theFieldName];
630     // Whether the replace function (js1.2) is supported or not
631     var isRegExp = (typeof(theField.value.replace) != 'undefined');
633     if (!isRegExp) {
634         isEmpty      = (theField.value == '') ? 1 : 0;
635     } else {
636         var space_re = new RegExp('\\s+');
637         isEmpty      = (theField.value.replace(space_re, '') == '') ? 1 : 0;
638     }
640     return isEmpty;
641 } // end of the 'emptyCheckTheField()' function
646  * @param   object   the form
647  * @param   string   the name of the form field to put the focus on
649  * @return  boolean  whether the form field is empty or not
650  */
651 function emptyFormElements(theForm, theFieldName)
653     var theField = theForm.elements[theFieldName];
654     var isEmpty = emptyCheckTheField(theForm, theFieldName);
657     return isEmpty;
658 } // end of the 'emptyFormElements()' function
662  * Ensures a value submitted in a form is numeric and is in a range
664  * @param   object   the form
665  * @param   string   the name of the form field to check
666  * @param   integer  the minimum authorized value
667  * @param   integer  the maximum authorized value
669  * @return  boolean  whether a valid number has been submitted or not
670  */
671 function checkFormElementInRange(theForm, theFieldName, message, min, max)
673     var theField         = theForm.elements[theFieldName];
674     var val              = parseInt(theField.value);
676     if (typeof(min) == 'undefined') {
677         min = 0;
678     }
679     if (typeof(max) == 'undefined') {
680         max = Number.MAX_VALUE;
681     }
683     // It's not a number
684     if (isNaN(val)) {
685         theField.select();
686         alert(PMA_messages['strNotNumber']);
687         theField.focus();
688         return false;
689     }
690     // It's a number but it is not between min and max
691     else if (val < min || val > max) {
692         theField.select();
693         alert(message.replace('%d', val));
694         theField.focus();
695         return false;
696     }
697     // It's a valid number
698     else {
699         theField.value = val;
700     }
701     return true;
703 } // end of the 'checkFormElementInRange()' function
706 function checkTableEditForm(theForm, fieldsCnt)
708     // TODO: avoid sending a message if user just wants to add a line
709     // on the form but has not completed at least one field name
711     var atLeastOneField = 0;
712     var i, elm, elm2, elm3, val, id;
714     for (i=0; i<fieldsCnt; i++)
715     {
716         id = "#field_" + i + "_2";
717         elm = $(id);
718         val = elm.val()
719         if (val == 'VARCHAR' || val == 'CHAR' || val == 'BIT' || val == 'VARBINARY' || val == 'BINARY') {
720             elm2 = $("#field_" + i + "_3");
721             val = parseInt(elm2.val());
722             elm3 = $("#field_" + i + "_1");
723             if (isNaN(val) && elm3.val() != "") {
724                 elm2.select();
725                 alert(PMA_messages['strNotNumber']);
726                 elm2.focus();
727                 return false;
728             }
729         }
731         if (atLeastOneField == 0) {
732             id = "field_" + i + "_1";
733             if (!emptyCheckTheField(theForm, id)) {
734                 atLeastOneField = 1;
735             }
736         }
737     }
738     if (atLeastOneField == 0) {
739         var theField = theForm.elements["field_0_1"];
740         alert(PMA_messages['strFormEmpty']);
741         theField.focus();
742         return false;
743     }
745     return true;
746 } // enf of the 'checkTableEditForm()' function
750  * Ensures the choice between 'transmit', 'zipped', 'gzipped' and 'bzipped'
751  * checkboxes is consistant
753  * @param   object   the form
754  * @param   string   a code for the action that causes this function to be run
756  * @return  boolean  always true
757  */
758 function checkTransmitDump(theForm, theAction)
760     var formElts = theForm.elements;
762     // 'zipped' option has been checked
763     if (theAction == 'zip' && formElts['zip'].checked) {
764         if (!formElts['asfile'].checked) {
765             theForm.elements['asfile'].checked = true;
766         }
767         if (typeof(formElts['gzip']) != 'undefined' && formElts['gzip'].checked) {
768             theForm.elements['gzip'].checked = false;
769         }
770         if (typeof(formElts['bzip']) != 'undefined' && formElts['bzip'].checked) {
771             theForm.elements['bzip'].checked = false;
772         }
773     }
774     // 'gzipped' option has been checked
775     else if (theAction == 'gzip' && formElts['gzip'].checked) {
776         if (!formElts['asfile'].checked) {
777             theForm.elements['asfile'].checked = true;
778         }
779         if (typeof(formElts['zip']) != 'undefined' && formElts['zip'].checked) {
780             theForm.elements['zip'].checked = false;
781         }
782         if (typeof(formElts['bzip']) != 'undefined' && formElts['bzip'].checked) {
783             theForm.elements['bzip'].checked = false;
784         }
785     }
786     // 'bzipped' option has been checked
787     else if (theAction == 'bzip' && formElts['bzip'].checked) {
788         if (!formElts['asfile'].checked) {
789             theForm.elements['asfile'].checked = true;
790         }
791         if (typeof(formElts['zip']) != 'undefined' && formElts['zip'].checked) {
792             theForm.elements['zip'].checked = false;
793         }
794         if (typeof(formElts['gzip']) != 'undefined' && formElts['gzip'].checked) {
795             theForm.elements['gzip'].checked = false;
796         }
797     }
798     // 'transmit' option has been unchecked
799     else if (theAction == 'transmit' && !formElts['asfile'].checked) {
800         if (typeof(formElts['zip']) != 'undefined' && formElts['zip'].checked) {
801             theForm.elements['zip'].checked = false;
802         }
803         if ((typeof(formElts['gzip']) != 'undefined' && formElts['gzip'].checked)) {
804             theForm.elements['gzip'].checked = false;
805         }
806         if ((typeof(formElts['bzip']) != 'undefined' && formElts['bzip'].checked)) {
807             theForm.elements['bzip'].checked = false;
808         }
809     }
811     return true;
812 } // end of the 'checkTransmitDump()' function
816  * This array is used to remember mark status of rows in browse mode
817  */
818 var marked_row = new Array;
821  * enables highlight and marking of rows in data tables
823  */
824 function PMA_markRowsInit() {
825     // for every table row ...
826     var rows = document.getElementsByTagName('tr');
827     for ( var i = 0; i < rows.length; i++ ) {
828         // ... with the class 'odd' or 'even' ...
829         if ( 'odd' != rows[i].className.substr(0,3) && 'even' != rows[i].className.substr(0,4) ) {
830             continue;
831         }
832         // ... add event listeners ...
833         // ... to highlight the row on mouseover ...
834         if ( navigator.appName == 'Microsoft Internet Explorer' ) {
835             // but only for IE, other browsers are handled by :hover in css
836             rows[i].onmouseover = function() {
837                 this.className += ' hover';
838             }
839             rows[i].onmouseout = function() {
840                 this.className = this.className.replace( ' hover', '' );
841             }
842         }
843         // Do not set click events if not wanted
844         if (rows[i].className.search(/noclick/) != -1) {
845             continue;
846         }
847         // ... and to mark the row on click ...
848         $(rows[i]).bind('mousedown', function(event) {
849             var unique_id;
850             var checkbox;
851             var table;
853             // Somehow IE8 has this not set
854             if (!event) var event = window.event
856             checkbox = this.getElementsByTagName( 'input' )[0];
857             if ( checkbox && checkbox.type == 'checkbox' ) {
858                 unique_id = checkbox.name + checkbox.value;
859             } else if ( this.id.length > 0 ) {
860                 unique_id = this.id;
861             } else {
862                 return;
863             }
865             if ( typeof(marked_row[unique_id]) == 'undefined' || !marked_row[unique_id] ) {
866                 marked_row[unique_id] = true;
867             } else {
868                 marked_row[unique_id] = false;
869             }
871             if ( marked_row[unique_id] ) {
872                 this.className += ' marked';
873             } else {
874                 this.className = this.className.replace(' marked', '');
875             }
877             if ( checkbox && checkbox.disabled == false ) {
878                 checkbox.checked = marked_row[unique_id];
879                 if (typeof(event) == 'object') {
880                     table = this.parentNode;
881                     parentTableLimit = 0;
882                     while (table.tagName.toLowerCase() != 'table' && parentTableLimit < 20) {
883                         parentTableLimit++;
884                         table = table.parentNode;
885                     }
887                     if (event.shiftKey == true && table.lastClicked != undefined) {
888                         if (event.preventDefault) {event.preventDefault();} else {event.returnValue = false;}
889                         i = table.lastClicked;
891                         if (i < this.rowIndex) {
892                             i++;
893                         } else {
894                             i--;
895                         }
897                         while (i != this.rowIndex) {
898                             $(table.rows[i]).mousedown();
899                             if (i < this.rowIndex) {
900                                 i++;
901                             } else {
902                                 i--;
903                             }
904                         }
905                     }
907                     table.lastClicked = this.rowIndex;
908                 }
909             }
910         });
912         // ... and disable label ...
913         var labeltag = rows[i].getElementsByTagName('label')[0];
914         if ( labeltag ) {
915             labeltag.onclick = function() {
916                 return false;
917             }
918         }
919         // .. and checkbox clicks
920         var checkbox = rows[i].getElementsByTagName('input')[0];
921         if ( checkbox ) {
922             checkbox.onclick = function() {
923                 // opera does not recognize return false;
924                 this.checked = ! this.checked;
925             }
926         }
927     }
929 $(document).ready(PMA_markRowsInit);
932  * marks all rows and selects its first checkbox inside the given element
933  * the given element is usaly a table or a div containing the table or tables
935  * @param    container    DOM element
936  */
937 function markAllRows( container_id ) {
938     
939     $("#"+container_id).find("input:checkbox:enabled").attr('checked', 'checked')
940     .parents("tr").addClass("marked");
941     return true;
945  * marks all rows and selects its first checkbox inside the given element
946  * the given element is usaly a table or a div containing the table or tables
948  * @param    container    DOM element
949  */
950 function unMarkAllRows( container_id ) {
951     
952     $("#"+container_id).find("input:checkbox:enabled").removeAttr('checked')
953     .parents("tr").removeClass("marked");
954     return true;
958  * Sets/unsets the pointer and marker in browse mode
960  * @param   object    the table row
961  * @param   integer  the row number
962  * @param   string    the action calling this script (over, out or click)
963  * @param   string    the default background color
964  * @param   string    the color to use for mouseover
965  * @param   string    the color to use for marking a row
967  * @return  boolean  whether pointer is set or not
968  */
969 function setPointer(theRow, theRowNum, theAction, theDefaultColor, thePointerColor, theMarkColor)
971     var theCells = null;
973     // 1. Pointer and mark feature are disabled or the browser can't get the
974     //    row -> exits
975     if ((thePointerColor == '' && theMarkColor == '')
976         || typeof(theRow.style) == 'undefined') {
977         return false;
978     }
980     // 1.1 Sets the mouse pointer to pointer on mouseover and back to normal otherwise.
981     if (theAction == "over" || theAction == "click") {
982         theRow.style.cursor='pointer';
983     } else {
984         theRow.style.cursor='default';
985     }
987     // 2. Gets the current row and exits if the browser can't get it
988     if (typeof(document.getElementsByTagName) != 'undefined') {
989         theCells = theRow.getElementsByTagName('td');
990     }
991     else if (typeof(theRow.cells) != 'undefined') {
992         theCells = theRow.cells;
993     }
994     else {
995         return false;
996     }
998     // 3. Gets the current color...
999     var rowCellsCnt  = theCells.length;
1000     var domDetect    = null;
1001     var currentColor = null;
1002     var newColor     = null;
1003     // 3.1 ... with DOM compatible browsers except Opera that does not return
1004     //         valid values with "getAttribute"
1005     if (typeof(window.opera) == 'undefined'
1006         && typeof(theCells[0].getAttribute) != 'undefined') {
1007         currentColor = theCells[0].getAttribute('bgcolor');
1008         domDetect    = true;
1009     }
1010     // 3.2 ... with other browsers
1011     else {
1012         currentColor = theCells[0].style.backgroundColor;
1013         domDetect    = false;
1014     } // end 3
1016     // 3.3 ... Opera changes colors set via HTML to rgb(r,g,b) format so fix it
1017     if (currentColor.indexOf("rgb") >= 0)
1018     {
1019         var rgbStr = currentColor.slice(currentColor.indexOf('(') + 1,
1020                                      currentColor.indexOf(')'));
1021         var rgbValues = rgbStr.split(",");
1022         currentColor = "#";
1023         var hexChars = "0123456789ABCDEF";
1024         for (var i = 0; i < 3; i++)
1025         {
1026             var v = rgbValues[i].valueOf();
1027             currentColor += hexChars.charAt(v/16) + hexChars.charAt(v%16);
1028         }
1029     }
1031     // 4. Defines the new color
1032     // 4.1 Current color is the default one
1033     if (currentColor == ''
1034         || currentColor.toLowerCase() == theDefaultColor.toLowerCase()) {
1035         if (theAction == 'over' && thePointerColor != '') {
1036             newColor              = thePointerColor;
1037         }
1038         else if (theAction == 'click' && theMarkColor != '') {
1039             newColor              = theMarkColor;
1040             marked_row[theRowNum] = true;
1041             // Garvin: deactivated onclick marking of the checkbox because it's also executed
1042             // when an action (like edit/delete) on a single item is performed. Then the checkbox
1043             // would get deactived, even though we need it activated. Maybe there is a way
1044             // to detect if the row was clicked, and not an item therein...
1045             // document.getElementById('id_rows_to_delete' + theRowNum).checked = true;
1046         }
1047     }
1048     // 4.1.2 Current color is the pointer one
1049     else if (currentColor.toLowerCase() == thePointerColor.toLowerCase()
1050              && (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])) {
1051         if (theAction == 'out') {
1052             newColor              = theDefaultColor;
1053         }
1054         else if (theAction == 'click' && theMarkColor != '') {
1055             newColor              = theMarkColor;
1056             marked_row[theRowNum] = true;
1057             // document.getElementById('id_rows_to_delete' + theRowNum).checked = true;
1058         }
1059     }
1060     // 4.1.3 Current color is the marker one
1061     else if (currentColor.toLowerCase() == theMarkColor.toLowerCase()) {
1062         if (theAction == 'click') {
1063             newColor              = (thePointerColor != '')
1064                                   ? thePointerColor
1065                                   : theDefaultColor;
1066             marked_row[theRowNum] = (typeof(marked_row[theRowNum]) == 'undefined' || !marked_row[theRowNum])
1067                                   ? true
1068                                   : null;
1069             // document.getElementById('id_rows_to_delete' + theRowNum).checked = false;
1070         }
1071     } // end 4
1073     // 5. Sets the new color...
1074     if (newColor) {
1075         var c = null;
1076         // 5.1 ... with DOM compatible browsers except Opera
1077         if (domDetect) {
1078             for (c = 0; c < rowCellsCnt; c++) {
1079                 theCells[c].setAttribute('bgcolor', newColor, 0);
1080             } // end for
1081         }
1082         // 5.2 ... with other browsers
1083         else {
1084             for (c = 0; c < rowCellsCnt; c++) {
1085                 theCells[c].style.backgroundColor = newColor;
1086             }
1087         }
1088     } // end 5
1090     return true;
1091 } // end of the 'setPointer()' function
1094  * Sets/unsets the pointer and marker in vertical browse mode
1096  * @param   object    the table row
1097  * @param   integer   the column number
1098  * @param   string    the action calling this script (over, out or click)
1099  * @param   string    the default background Class
1100  * @param   string    the Class to use for mouseover
1101  * @param   string    the Class to use for marking a row
1103  * @return  boolean  whether pointer is set or not
1105  */
1106 function setVerticalPointer(theRow, theColNum, theAction, theDefaultClass1, theDefaultClass2, thePointerClass, theMarkClass) {
1107     // 1. Pointer and mark feature are disabled or the browser can't get the
1108     //    row -> exits
1109     if ((thePointerClass == '' && theMarkClass == '')
1110         || typeof(theRow.style) == 'undefined') {
1111         return false;
1112     }
1114     var tagSwitch = null;
1116     // 2. Gets the current row and exits if the browser can't get it
1117     if (typeof(document.getElementsByTagName) != 'undefined') {
1118         tagSwitch = 'tag';
1119     } else if (typeof(document.getElementById('table_results')) != 'undefined') {
1120         tagSwitch = 'cells';
1121     } else {
1122         return false;
1123     }
1125     var theCells = null;
1127     if (tagSwitch == 'tag') {
1128         theRows     = document.getElementById('table_results').getElementsByTagName('tr');
1129         theCells    = theRows[1].getElementsByTagName('td');
1130     } else if (tagSwitch == 'cells') {
1131         theRows     = document.getElementById('table_results').rows;
1132         theCells    = theRows[1].cells;
1133     }
1135     // 3. Gets the current Class...
1136     var currentClass   = null;
1137     var newClass       = null;
1139     // 3.1 ... with DOM compatible browsers except Opera that does not return
1140     //         valid values with "getAttribute"
1141     if (typeof(window.opera) == 'undefined'
1142         && typeof(theCells[theColNum].getAttribute) != 'undefined') {
1143         currentClass = theCells[theColNum].className;
1144     } // end 3
1146     // 4. Defines the new Class
1147     // 4.1 Current Class is the default one
1148     if (currentClass == ''
1149         || currentClass.toLowerCase() == theDefaultClass1.toLowerCase()
1150         || currentClass.toLowerCase() == theDefaultClass2.toLowerCase()) {
1151         if (theAction == 'over' && thePointerClass != '') {
1152             newClass              = thePointerClass;
1153         } else if (theAction == 'click' && theMarkClass != '') {
1154             newClass              = theMarkClass;
1155             marked_row[theColNum] = true;
1156         }
1157     }
1158     // 4.1.2 Current Class is the pointer one
1159     else if (currentClass.toLowerCase() == thePointerClass.toLowerCase() &&
1160              (typeof(marked_row[theColNum]) == 'undefined' || !marked_row[theColNum]) || marked_row[theColNum] == false) {
1161             if (theAction == 'out') {
1162                 if (theColNum % 2) {
1163                     newClass              = theDefaultClass1;
1164                 } else {
1165                     newClass              = theDefaultClass2;
1166                 }
1167             }
1168             else if (theAction == 'click' && theMarkClass != '') {
1169                 newClass              = theMarkClass;
1170                 marked_row[theColNum] = true;
1171             }
1172     }
1173     // 4.1.3 Current Class is the marker one
1174     else if (currentClass.toLowerCase() == theMarkClass.toLowerCase()) {
1175         if (theAction == 'click') {
1176             newClass              = (thePointerClass != '')
1177                                   ? thePointerClass
1178                                   : ((theColNum % 2) ? theDefaultClass2 : theDefaultClass1);
1179             marked_row[theColNum] = false;
1180         }
1181     } // end 4
1183     // 5 ... with DOM compatible browsers except Opera
1185     if (newClass) {
1186         var c = null;
1187         var rowCnt = theRows.length;
1188         for (c = 0; c < rowCnt; c++) {
1189             if (tagSwitch == 'tag') {
1190                 Cells = theRows[c].getElementsByTagName('td');
1191             } else if (tagSwitch == 'cells') {
1192                 Cells = theRows[c].cells;
1193             }
1195             Cell  = Cells[theColNum];
1197             // 5.1 Sets the new Class...
1198             Cell.className = Cell.className.replace(currentClass, newClass);
1199         } // end for
1200     } // end 5
1202      return true;
1203  } // end of the 'setVerticalPointer()' function
1206  * Checks/unchecks all checkbox in given conainer (f.e. a form, fieldset or div)
1208  * @param   string   container_id  the container id
1209  * @param   boolean  state         new value for checkbox (true or false)
1210  * @return  boolean  always true
1211  */
1212 function setCheckboxes( container_id, state ) {
1214     if(state) {
1215         $("#"+container_id).find("input:checkbox").attr('checked', 'checked');
1216     }
1217     else {
1218         $("#"+container_id).find("input:checkbox").removeAttr('checked');
1219     }
1221     return true;
1222 } // end of the 'setCheckboxes()' function
1225 // added 2004-05-08 by Michael Keck <mail_at_michaelkeck_dot_de>
1226 //   copy the checked from left to right or from right to left
1227 //   so it's easier for users to see, if $cfg['ModifyAtRight']=true, what they've checked ;)
1228 function copyCheckboxesRange(the_form, the_name, the_clicked)
1230     if (typeof(document.forms[the_form].elements[the_name]) != 'undefined' && typeof(document.forms[the_form].elements[the_name + 'r']) != 'undefined') {
1231         if (the_clicked !== 'r') {
1232             if (document.forms[the_form].elements[the_name].checked == true) {
1233                 document.forms[the_form].elements[the_name + 'r'].checked = true;
1234             }else {
1235                 document.forms[the_form].elements[the_name + 'r'].checked = false;
1236             }
1237         } else if (the_clicked == 'r') {
1238             if (document.forms[the_form].elements[the_name + 'r'].checked == true) {
1239                 document.forms[the_form].elements[the_name].checked = true;
1240             }else {
1241                 document.forms[the_form].elements[the_name].checked = false;
1242             }
1243        }
1244     }
1248 // added 2004-05-08 by Michael Keck <mail_at_michaelkeck_dot_de>
1249 //  - this was directly written to each td, so why not a function ;)
1250 //  setCheckboxColumn(\'id_rows_to_delete' . $row_no . ''\');
1251 function setCheckboxColumn(theCheckbox){
1252     if (document.getElementById(theCheckbox)) {
1253         document.getElementById(theCheckbox).checked = (document.getElementById(theCheckbox).checked ? false : true);
1254         if (document.getElementById(theCheckbox + 'r')) {
1255             document.getElementById(theCheckbox + 'r').checked = document.getElementById(theCheckbox).checked;
1256         }
1257     } else {
1258         if (document.getElementById(theCheckbox + 'r')) {
1259             document.getElementById(theCheckbox + 'r').checked = (document.getElementById(theCheckbox +'r').checked ? false : true);
1260             if (document.getElementById(theCheckbox)) {
1261                 document.getElementById(theCheckbox).checked = document.getElementById(theCheckbox + 'r').checked;
1262             }
1263         }
1264     }
1269   * Checks/unchecks all options of a <select> element
1270   *
1271   * @param   string   the form name
1272   * @param   string   the element name
1273   * @param   boolean  whether to check or to uncheck the element
1274   *
1275   * @return  boolean  always true
1276   */
1277 function setSelectOptions(the_form, the_select, do_check)
1280     if( do_check ) {
1281         $("form[name='"+ the_form +"']").find("select[name='"+the_select+"']").find("option").attr('selected', 'selected');
1282     }
1283     else {
1284         $("form[name='"+ the_form +"']").find("select[name="+the_select+"]").find("option").removeAttr('selected');
1285     }
1286     return true;
1287 } // end of the 'setSelectOptions()' function
1291   * Create quick sql statements.
1292   *
1293   */
1294 function insertQuery(queryType) {
1295     var myQuery = document.sqlform.sql_query;
1296     var myListBox = document.sqlform.dummy;
1297     var query = "";
1298     var table = document.sqlform.table.value;
1300     if (myListBox.options.length > 0) {
1301         sql_box_locked = true;
1302         var chaineAj = "";
1303         var valDis = "";
1304         var editDis = "";
1305         var NbSelect = 0;
1306         for (var i=0; i < myListBox.options.length; i++) {
1307             NbSelect++;
1308             if (NbSelect > 1) {
1309                 chaineAj += ", ";
1310                 valDis += ",";
1311                 editDis += ",";
1312             }
1313             chaineAj += myListBox.options[i].value;
1314             valDis += "[value-" + NbSelect + "]";
1315             editDis += myListBox.options[i].value + "=[value-" + NbSelect + "]";
1316         }
1317     if (queryType == "selectall") {
1318         query = "SELECT * FROM `" + table + "` WHERE 1";
1319     } else if (queryType == "select") {
1320         query = "SELECT " + chaineAj + " FROM `" + table + "` WHERE 1";
1321     } else if (queryType == "insert") {
1322            query = "INSERT INTO `" + table + "`(" + chaineAj + ") VALUES (" + valDis + ")";
1323     } else if (queryType == "update") {
1324         query = "UPDATE `" + table + "` SET " + editDis + " WHERE 1";
1325     } else if(queryType == "delete") {
1326         query = "DELETE FROM `" + table + "` WHERE 1";
1327     }
1328     document.sqlform.sql_query.value = query;
1329     sql_box_locked = false;
1330     }
1335   * Inserts multiple fields.
1336   *
1337   */
1338 function insertValueQuery() {
1339     var myQuery = document.sqlform.sql_query;
1340     var myListBox = document.sqlform.dummy;
1342     if(myListBox.options.length > 0) {
1343         sql_box_locked = true;
1344         var chaineAj = "";
1345         var NbSelect = 0;
1346         for(var i=0; i<myListBox.options.length; i++) {
1347             if (myListBox.options[i].selected){
1348                 NbSelect++;
1349                 if (NbSelect > 1)
1350                     chaineAj += ", ";
1351                 chaineAj += myListBox.options[i].value;
1352             }
1353         }
1355         //IE support
1356         if (document.selection) {
1357             myQuery.focus();
1358             sel = document.selection.createRange();
1359             sel.text = chaineAj;
1360             document.sqlform.insert.focus();
1361         }
1362         //MOZILLA/NETSCAPE support
1363         else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart == "0") {
1364             var startPos = document.sqlform.sql_query.selectionStart;
1365             var endPos = document.sqlform.sql_query.selectionEnd;
1366             var chaineSql = document.sqlform.sql_query.value;
1368             myQuery.value = chaineSql.substring(0, startPos) + chaineAj + chaineSql.substring(endPos, chaineSql.length);
1369         } else {
1370             myQuery.value += chaineAj;
1371         }
1372         sql_box_locked = false;
1373     }
1377   * listbox redirection
1378   */
1379 function goToUrl(selObj, goToLocation) {
1380     eval("document.location.href = '" + goToLocation + "pos=" + selObj.options[selObj.selectedIndex].value + "'");
1384  * getElement
1385  */
1386 function getElement(e,f){
1387     if(document.layers){
1388         f=(f)?f:self;
1389         if(f.document.layers[e]) {
1390             return f.document.layers[e];
1391         }
1392         for(W=0;W<f.document.layers.length;W++) {
1393             return(getElement(e,f.document.layers[W]));
1394         }
1395     }
1396     if(document.all) {
1397         return document.all[e];
1398     }
1399     return document.getElementById(e);
1403   * Refresh the WYSIWYG scratchboard after changes have been made
1404   */
1405 function refreshDragOption(e) {
1406     var elm = $('#' + e);
1407     if (elm.css('visibility') == 'visible') {
1408         refreshLayout();
1409         TableDragInit();
1410     }
1414   * Refresh/resize the WYSIWYG scratchboard
1415   */
1416 function refreshLayout() {
1417     var elm = $('#pdflayout')
1418     var orientation = $('#orientation_opt').val();
1419     if($('#paper_opt').length==1){
1420         var paper = $('#paper_opt').val();        
1421     }else{
1422         var paper = 'A4';
1423     }
1424     if (orientation == 'P') {
1425         posa = 'x';
1426         posb = 'y';
1427     } else {
1428         posa = 'y';
1429         posb = 'x';
1430     }
1431     elm.css('width', pdfPaperSize(paper, posa) + 'px');
1432     elm.css('height', pdfPaperSize(paper, posb) + 'px');
1436   * Show/hide the WYSIWYG scratchboard
1437   */
1438 function ToggleDragDrop(e) {
1439     var elm = $('#' + e);
1440     if (elm.css('visibility') == 'hidden') {
1441         PDFinit(); /* Defined in pdf_pages.php */
1442         elm.css('visibility', 'visible');
1443         elm.css('display', 'block');
1444         $('#showwysiwyg').val('1')
1445     } else {
1446         elm.css('visibility', 'hidden');
1447         elm.css('display', 'none');
1448         $('#showwysiwyg').val('0')
1449     }
1453   * PDF scratchboard: When a position is entered manually, update
1454   * the fields inside the scratchboard.
1455   */
1456 function dragPlace(no, axis, value) {
1457     var elm = $('#table_' + no);
1458     if (axis == 'x') {
1459         elm.css('left', value + 'px');
1460     } else {
1461         elm.css('top', value + 'px');
1462     }
1466  * Returns paper sizes for a given format
1467  */
1468 function pdfPaperSize(format, axis) {
1469     switch (format.toUpperCase()) {
1470         case '4A0':
1471             if (axis == 'x') return 4767.87; else return 6740.79;
1472             break;
1473         case '2A0':
1474             if (axis == 'x') return 3370.39; else return 4767.87;
1475             break;
1476         case 'A0':
1477             if (axis == 'x') return 2383.94; else return 3370.39;
1478             break;
1479         case 'A1':
1480             if (axis == 'x') return 1683.78; else return 2383.94;
1481             break;
1482         case 'A2':
1483             if (axis == 'x') return 1190.55; else return 1683.78;
1484             break;
1485         case 'A3':
1486             if (axis == 'x') return 841.89; else return 1190.55;
1487             break;
1488         case 'A4':
1489             if (axis == 'x') return 595.28; else return 841.89;
1490             break;
1491         case 'A5':
1492             if (axis == 'x') return 419.53; else return 595.28;
1493             break;
1494         case 'A6':
1495             if (axis == 'x') return 297.64; else return 419.53;
1496             break;
1497         case 'A7':
1498             if (axis == 'x') return 209.76; else return 297.64;
1499             break;
1500         case 'A8':
1501             if (axis == 'x') return 147.40; else return 209.76;
1502             break;
1503         case 'A9':
1504             if (axis == 'x') return 104.88; else return 147.40;
1505             break;
1506         case 'A10':
1507             if (axis == 'x') return 73.70; else return 104.88;
1508             break;
1509         case 'B0':
1510             if (axis == 'x') return 2834.65; else return 4008.19;
1511             break;
1512         case 'B1':
1513             if (axis == 'x') return 2004.09; else return 2834.65;
1514             break;
1515         case 'B2':
1516             if (axis == 'x') return 1417.32; else return 2004.09;
1517             break;
1518         case 'B3':
1519             if (axis == 'x') return 1000.63; else return 1417.32;
1520             break;
1521         case 'B4':
1522             if (axis == 'x') return 708.66; else return 1000.63;
1523             break;
1524         case 'B5':
1525             if (axis == 'x') return 498.90; else return 708.66;
1526             break;
1527         case 'B6':
1528             if (axis == 'x') return 354.33; else return 498.90;
1529             break;
1530         case 'B7':
1531             if (axis == 'x') return 249.45; else return 354.33;
1532             break;
1533         case 'B8':
1534             if (axis == 'x') return 175.75; else return 249.45;
1535             break;
1536         case 'B9':
1537             if (axis == 'x') return 124.72; else return 175.75;
1538             break;
1539         case 'B10':
1540             if (axis == 'x') return 87.87; else return 124.72;
1541             break;
1542         case 'C0':
1543             if (axis == 'x') return 2599.37; else return 3676.54;
1544             break;
1545         case 'C1':
1546             if (axis == 'x') return 1836.85; else return 2599.37;
1547             break;
1548         case 'C2':
1549             if (axis == 'x') return 1298.27; else return 1836.85;
1550             break;
1551         case 'C3':
1552             if (axis == 'x') return 918.43; else return 1298.27;
1553             break;
1554         case 'C4':
1555             if (axis == 'x') return 649.13; else return 918.43;
1556             break;
1557         case 'C5':
1558             if (axis == 'x') return 459.21; else return 649.13;
1559             break;
1560         case 'C6':
1561             if (axis == 'x') return 323.15; else return 459.21;
1562             break;
1563         case 'C7':
1564             if (axis == 'x') return 229.61; else return 323.15;
1565             break;
1566         case 'C8':
1567             if (axis == 'x') return 161.57; else return 229.61;
1568             break;
1569         case 'C9':
1570             if (axis == 'x') return 113.39; else return 161.57;
1571             break;
1572         case 'C10':
1573             if (axis == 'x') return 79.37; else return 113.39;
1574             break;
1575         case 'RA0':
1576             if (axis == 'x') return 2437.80; else return 3458.27;
1577             break;
1578         case 'RA1':
1579             if (axis == 'x') return 1729.13; else return 2437.80;
1580             break;
1581         case 'RA2':
1582             if (axis == 'x') return 1218.90; else return 1729.13;
1583             break;
1584         case 'RA3':
1585             if (axis == 'x') return 864.57; else return 1218.90;
1586             break;
1587         case 'RA4':
1588             if (axis == 'x') return 609.45; else return 864.57;
1589             break;
1590         case 'SRA0':
1591             if (axis == 'x') return 2551.18; else return 3628.35;
1592             break;
1593         case 'SRA1':
1594             if (axis == 'x') return 1814.17; else return 2551.18;
1595             break;
1596         case 'SRA2':
1597             if (axis == 'x') return 1275.59; else return 1814.17;
1598             break;
1599         case 'SRA3':
1600             if (axis == 'x') return 907.09; else return 1275.59;
1601             break;
1602         case 'SRA4':
1603             if (axis == 'x') return 637.80; else return 907.09;
1604             break;
1605         case 'LETTER':
1606             if (axis == 'x') return 612.00; else return 792.00;
1607             break;
1608         case 'LEGAL':
1609             if (axis == 'x') return 612.00; else return 1008.00;
1610             break;
1611         case 'EXECUTIVE':
1612             if (axis == 'x') return 521.86; else return 756.00;
1613             break;
1614         case 'FOLIO':
1615             if (axis == 'x') return 612.00; else return 936.00;
1616             break;
1617     } // end switch
1619     return 0;
1623  * for playing media from the BLOB repository
1625  * @param   var
1626  * @param   var     url_params  main purpose is to pass the token
1627  * @param   var     bs_ref      BLOB repository reference
1628  * @param   var     m_type      type of BLOB repository media
1629  * @param   var     w_width     width of popup window
1630  * @param   var     w_height    height of popup window
1631  */
1632 function popupBSMedia(url_params, bs_ref, m_type, is_cust_type, w_width, w_height)
1634     // if width not specified, use default
1635     if (w_width == undefined)
1636         w_width = 640;
1638     // if height not specified, use default
1639     if (w_height == undefined)
1640         w_height = 480;
1642     // open popup window (for displaying video/playing audio)
1643     var mediaWin = window.open('bs_play_media.php?' + url_params + '&bs_reference=' + bs_ref + '&media_type=' + m_type + '&custom_type=' + is_cust_type, 'viewBSMedia', 'width=' + w_width + ', height=' + w_height + ', resizable=1, scrollbars=1, status=0');
1647  * popups a request for changing MIME types for files in the BLOB repository
1649  * @param   var     db                      database name
1650  * @param   var     table                   table name
1651  * @param   var     reference               BLOB repository reference
1652  * @param   var     current_mime_type       current MIME type associated with BLOB repository reference
1653  */
1654 function requestMIMETypeChange(db, table, reference, current_mime_type)
1656     // no mime type specified, set to default (nothing)
1657     if (undefined == current_mime_type)
1658         current_mime_type = "";
1660     // prompt user for new mime type
1661     var new_mime_type = prompt("Enter custom MIME type", current_mime_type);
1663     // if new mime_type is specified and is not the same as the previous type, request for mime type change
1664     if (new_mime_type && new_mime_type != current_mime_type)
1665         changeMIMEType(db, table, reference, new_mime_type);
1669  * changes MIME types for files in the BLOB repository
1671  * @param   var     db              database name
1672  * @param   var     table           table name
1673  * @param   var     reference       BLOB repository reference
1674  * @param   var     mime_type       new MIME type to be associated with BLOB repository reference
1675  */
1676 function changeMIMEType(db, table, reference, mime_type)
1678     // specify url and parameters for jQuery POST
1679     var mime_chg_url = 'bs_change_mime_type.php';
1680     var params = {bs_db: db, bs_table: table, bs_reference: reference, bs_new_mime_type: mime_type};
1682     // jQuery POST
1683     jQuery.post(mime_chg_url, params);
1687  * Jquery Coding for inline editing SQL_QUERY
1688  */
1689 $(document).ready(function(){
1690     var $oldText,$db,$table,$token,$sql_query;
1691     $oldText=$(".inner_sql").html();
1692     $("#inline_edit").click(function(){
1693         $db=$("input[name='db']").val();
1694         $table=$("input[name='table']").val();
1695         $token=$("input[name='token']").val();
1696         $sql_query=$("input[name='sql_query']").val();
1697         $(".inner_sql").replaceWith("<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">"+ $sql_query +"</textarea><input type=\"button\" id=\"btnSave\" value=\"" + PMA_messages['strGo'] + "\"><input type=\"button\" id=\"btnDiscard\" value=\"" + PMA_messages['strCancel'] + "\">");
1698         return false;
1699     });
1701     $("#btnSave").live("click",function(){
1702         window.location.replace("import.php?db="+$db+"&table="+$table+"&sql_query="+$("#sql_query_edit").val()+"&show_query=1&token="+$token+"");
1703     });
1705     $("#btnDiscard").live("click",function(){
1706         $(".sql").html("<span class=\"syntax\"><span class=\"inner_sql\">"+$oldText+"</span></span>");
1707     });
1709     $('.sqlbutton').click(function(evt){
1710         insertQuery(evt.target.id);
1711         return false;
1712     });
1714     $("#export_type").change(function(){
1715         if($("#export_type").val()=='svg'){
1716             $("#show_grid_opt").attr("disabled","disabled");
1717             $("#orientation_opt").attr("disabled","disabled");
1718             $("#with_doc").attr("disabled","disabled");
1719             $("#show_table_dim_opt").removeAttr("disabled");
1720             $("#all_table_same_wide").removeAttr("disabled");
1721             $("#paper_opt").removeAttr("disabled","disabled");
1722             $("#show_color_opt").removeAttr("disabled","disabled");
1723             //$(this).css("background-color","yellow");
1724         }else if($("#export_type").val()=='dia'){
1725             $("#show_grid_opt").attr("disabled","disabled");
1726             $("#with_doc").attr("disabled","disabled");
1727             $("#show_table_dim_opt").attr("disabled","disabled");
1728             $("#all_table_same_wide").attr("disabled","disabled");
1729             $("#paper_opt").removeAttr("disabled","disabled");
1730             $("#show_color_opt").removeAttr("disabled","disabled");
1731             $("#orientation_opt").removeAttr("disabled","disabled");
1732         }else if($("#export_type").val()=='eps'){
1733             $("#show_grid_opt").attr("disabled","disabled");
1734             $("#orientation_opt").removeAttr("disabled");
1735             $("#with_doc").attr("disabled","disabled");
1736             $("#show_table_dim_opt").attr("disabled","disabled");
1737             $("#all_table_same_wide").attr("disabled","disabled");
1738             $("#paper_opt").attr("disabled","disabled");
1739             $("#show_color_opt").attr("disabled","disabled");
1740             
1741         }else if($("#export_type").val()=='pdf'){
1742             $("#show_grid_opt").removeAttr("disabled");
1743             $("#orientation_opt").removeAttr("disabled");
1744             $("#with_doc").removeAttr("disabled","disabled");
1745             $("#show_table_dim_opt").removeAttr("disabled","disabled");
1746             $("#all_table_same_wide").removeAttr("disabled","disabled");
1747             $("#paper_opt").removeAttr("disabled","disabled");
1748             $("#show_color_opt").removeAttr("disabled","disabled");
1749         }else{
1750             // nothing
1751         }
1752     });
1754     $('#sqlquery').focus();
1755     if ($('#input_username')) {
1756         if ($('#input_username').val() == '') {
1757             $('#input_username').focus();
1758         } else {
1759             $('#input_password').focus();
1760         }
1761     }
1765  * Function to process the plain HTML response from an Ajax request.  Inserts
1766  * the various HTML divisions from the response at the proper locations.  The 
1767  * array relates the divisions to be inserted to their placeholders.
1769  * @param   var divisions_map   an associative array of id names
1771  * <code>
1772  * PMA_ajaxInsertResponse({'resultsTable':'resultsTable_response',
1773  *                         'profilingData':'profilingData_response'});
1774  * </code>
1776  */
1778 function PMA_ajaxInsertResponse(divisions_map) {
1779     $.each(divisions_map, function(key, value) {
1780         var content_div = '#'+value;
1781         var target_div = '#'+key;
1782         var content = $(content_div).html();
1784         //replace content of target_div with that from the response
1785         $(target_div).html(content);
1786     });
1790  * Show a message on the top of the page for an Ajax request
1792  * @param   var     message     string containing the message to be shown.
1793  *                              optional, defaults to 'Loading...'
1794  * @param   var     timeout     number of milliseconds for the message to be visible
1795  *                              optional, defaults to 5000
1796  */
1798 function PMA_ajaxShowMessage(message, timeout) {
1799     
1800     //Handle the case when a empty data.message is passed.  We don't want the empty message
1801     if(message == '') {
1802         return true;
1803     }
1805     /**
1806      * @var msg String containing the message that has to be displayed
1807      * @default PMA_messages['strLoading']
1808      */
1809     if(!message) {
1810         var msg = PMA_messages['strLoading'];
1811     }
1812     else {
1813         var msg = message;
1814     }
1816     /**
1817      * @var timeout Number of milliseconds for which {@link msg} will be visible
1818      * @default 5000 ms
1819      */
1820     if(!timeout) {
1821         var to = 5000;
1822     }
1823     else {
1824         var to = timeout;
1825     }
1827     if( !ajax_message_init) {
1828         //For the first time this function is called, append a new div
1829         $(function(){
1830             $('<div id="loading_parent"></div>')
1831             .insertBefore("#serverinfo");
1833             $('<span id="loading" class="ajax_notification"></span>')
1834             .appendTo("#loading_parent")
1835             .html(msg)
1836             .slideDown('medium')
1837             .delay(to)
1838             .slideUp('medium', function(){
1839                 $(this)
1840                 .html("") //Clear the message
1841                 .hide();
1842             });
1843         }, 'top.frame_content');
1844         ajax_message_init = true;
1845     }
1846     else {
1847         //Otherwise, just show the div again after inserting the message
1848         $("#loading")
1849         .clearQueue()
1850         .html(msg)
1851         .slideDown('medium')
1852         .delay(to)
1853         .slideUp('medium', function() {
1854             $(this)
1855             .html("")
1856             .hide();
1857         })
1858     }
1862  * Hides/shows the "Open in ENUM/SET editor" message, depending on the data type of the column currently selected
1863  */
1864 function toggle_enum_notice(selectElement) {
1865     var enum_notice_id = selectElement.attr("id").split("_")[1];
1866     enum_notice_id += "_" + (parseInt(selectElement.attr("id").split("_")[2]) + 1);
1867     var selectedType = selectElement.attr("value");
1868     if(selectedType == "ENUM" || selectedType == "SET") {
1869         $("p[id='enum_notice_" + enum_notice_id + "']").show();
1870     } else {
1871           $("p[id='enum_notice_" + enum_notice_id + "']").hide();
1872     }
1876  * jQuery function that uses jQueryUI's dialogs to confirm with user. Does not
1877  *  return a jQuery object yet and hence cannot be chained
1879  * @param   string      question
1880  * @param   string      url         URL to be passed to the callbackFn to make
1881  *                                  an Ajax call to
1882  * @param   function    callbackFn  callback to execute after user clicks on OK
1883  */
1885 jQuery.fn.PMA_confirm = function(question, url, callbackFn) {
1886     if (PMA_messages['strDoYouReally'] == '') {
1887         return true;
1888     }
1890     /**
1891      *  @var    button_options  Object that stores the options passed to jQueryUI
1892      *                          dialog
1893      */
1894     var button_options = {};
1895     button_options[PMA_messages['strOK']] = function(){
1896                                                 $(this).dialog("close").remove();
1898                                                 if($.isFunction(callbackFn)) {
1899                                                     callbackFn.call(this, url);
1900                                                 }
1901                                             };
1902     button_options[PMA_messages['strCancel']] = function() {$(this).dialog("close").remove();}
1904     $('<div id="confirm_dialog"></div>')
1905     .prepend(question)
1906     .dialog({buttons: button_options});
1910  * jQuery function to sort a table's body after a new row has been appended to it.
1911  * Also fixes the even/odd classes of the table rows at the end.
1913  * @param   string      text_selector   string to select the sortKey's text
1915  * @return  jQuery Object for chaining purposes
1916  */
1917 jQuery.fn.PMA_sort_table = function(text_selector) {
1918     return this.each(function() {
1920         /**
1921          * @var table_body  Object referring to the table's <tbody> element
1922          */
1923         var table_body = $(this);
1924         /**
1925          * @var rows    Object referring to the collection of rows in {@link table_body}
1926          */
1927         var rows = $(this).find('tr').get();
1929         //get the text of the field that we will sort by
1930         $.each(rows, function(index, row) {
1931             row.sortKey = $.trim($(row).find(text_selector).text().toLowerCase());
1932         })
1934         //get the sorted order
1935         rows.sort(function(a,b) {
1936             if(a.sortKey < b.sortKey) {
1937                 return -1;
1938             }
1939             if(a.sortKey > b.sortKey) {
1940                 return 1;
1941             }
1942             return 0;
1943         })
1945         //pull out each row from the table and then append it according to it's order
1946         $.each(rows, function(index, row) {
1947             $(table_body).append(row);
1948             row.sortKey = null;
1949         })
1951         //Re-check the classes of each row
1952         $(this).find('tr:odd')
1953         .removeClass('even').addClass('odd')
1954         .end()
1955         .find('tr:even')
1956         .removeClass('odd').addClass('even');
1957     })
1961  * jQuery coding for 'Create Table'.  Used on db_operations.php,
1962  * db_structure.php and db_tracking.php (i.e., wherever
1963  * libraries/display_create_table.lib.php is used)
1964  * 
1965  * Attach Ajax Event handlers for Create Table
1966  */
1967 $(document).ready(function() {
1969     /**
1970      * Attach event handler to the submit action of the create table minimal form
1971      * and retrieve the full table form and display it in a dialog
1972      * 
1973      * @uses    PMA_ajaxShowMessage()
1974      */
1975     $("#create_table_form_minimal").live('submit', function(event) {
1976         event.preventDefault();
1978         /* @todo Validate this form! */
1980         /**
1981          *  @var    button_options  Object that stores the options passed to jQueryUI
1982          *                          dialog
1983          */
1984         var button_options = {};
1985         button_options[PMA_messages['strCancel']] = function() {$(this).dialog('close').remove();}
1987         PMA_ajaxShowMessage();
1988         $(this).append('<input type="hidden" name="ajax_request" value="true" />');
1990         $.get($(this).attr('action'), $(this).serialize(), function(data) {
1991             $('<div id="create_table_dialog"></div>')
1992             .append(data)
1993             .dialog({
1994                 title: top.frame_content.PMA_messages['strCreateTable'],
1995                 width: 900,
1996                 buttons : button_options
1997             }); // end dialog options
1998         }) // end $.get()
1999         
2000     });
2002     /**
2003      * Attach event handler for submission of create table form
2004      * 
2005      * @uses    PMA_ajaxShowMessage()
2006      * @uses    $.PMA_sort_table()
2007      * @uses    window.parent.refreshNavigation()
2008      */
2009     $("#create_table_form").find("input[name=submit_num_fields], input[name=do_save_data]").live('click', function(event) {
2010         event.preventDefault();
2012         /**
2013          *  @var    the_form    object referring to the create table form
2014          */
2015         var the_form = $("#create_table_form");
2017         PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2018         $(the_form).append('<input type="hidden" name="ajax_request" value="true" />');
2020         if($(this).attr('name') == 'submit_num_fields') {
2021             //User wants to add more fields to the table
2022             $.post($(the_form).attr('action'), $(the_form).serialize() + "&submit_num_fields=" + $(this).val(), function(data) {
2023                 $("#create_table_dialog").html(data);
2024             }) //end $.post()
2025         }
2026         else if($(this).attr('name') == 'do_save_data') {
2027             //User wants to submit the form
2028             $.post($(the_form).attr('action'), $(the_form).serialize() + "&do_save_data=" + $(this).val(), function(data) {
2029                 if(data.success == true) {
2030                     PMA_ajaxShowMessage(data.message);
2031                     $("#create_table_dialog").dialog("close").remove();
2033                     /**
2034                      * @var tables_table    Object referring to the <tbody> element that holds the list of tables
2035                      */
2036                     var tables_table = $("#tablesForm").find("tbody").not("#tbl_summary_row");
2038                     /**
2039                      * @var curr_last_row   Object referring to the last <tr> element in {@link tables_table}
2040                      */
2041                     var curr_last_row = $(tables_table).find('tr:last');
2042                     /**
2043                      * @var curr_last_row_index_string   String containing the index of {@link curr_last_row}
2044                      */
2045                     var curr_last_row_index_string = $(curr_last_row).find('input:checkbox').attr('id').match(/\d+/)[0];
2046                     /**
2047                      * @var curr_last_row_index Index of {@link curr_last_row}
2048                      */
2049                     var curr_last_row_index = parseFloat(curr_last_row_index_string);
2050                     /**
2051                      * @var new_last_row_index   Index of the new row to be appended to {@link tables_table}
2052                      */
2053                     var new_last_row_index = curr_last_row_index + 1;
2054                     /**
2055                      * @var new_last_row_id String containing the id of the row to be appended to {@link tables_table}
2056                      */
2057                     var new_last_row_id = 'checkbox_tbl_' + new_last_row_index;
2059                     //append to table
2060                     $(data.new_table_string)
2061                     .find('input:checkbox')
2062                     .val(new_last_row_id)
2063                     .end()
2064                     .appendTo(tables_table);
2066                     //Sort the table
2067                     $(tables_table).PMA_sort_table('th');
2069                     //Refresh navigation frame as a new table has been added
2070                     window.parent.refreshNavigation();
2071                 }
2072                 else {
2073                     PMA_ajaxShowMessage(data.error);
2074                 }
2075             }) // end $.post()
2076         } // end elseif()
2077     }) // end create table form submit button actions
2079 }, 'top.frame_content'); //end $(document).ready for 'Create Table'
2082  * Attach event handlers for Empty Table and Drop Table.  Used wherever libraries/
2083  * tbl_links.inc.php is used.
2084  */
2085 $(document).ready(function() {
2087     /**
2088      * Attach Ajax event handlers for Empty Table
2089      * 
2090      * @uses    PMA_ajaxShowMessage()
2091      * @uses    $.PMA_confirm()
2092      */
2093     $("#empty_table_anchor").live('click', function(event) {
2094         event.preventDefault();
2096         /**
2097          * @var question    String containing the question to be asked for confirmation
2098          */
2099         var question = 'TRUNCATE TABLE ' + window.parent.table;
2101         $(this).PMA_confirm(question, $(this).attr('href'), function(url) {
2103             PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2104             $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function(data) {
2105                 if(data.success == true) {
2106                     PMA_ajaxShowMessage(data.message);
2107                     $("#topmenucontainer")
2108                     .next('div')
2109                     .remove()
2110                     .end()
2111                     .after(data.sql_query);
2112                 }
2113                 else {
2114                     PMA_ajaxShowMessage(data.error);
2115                 }
2116             }) // end $.get
2117         }) // end $.PMA_confirm()
2118     }) // end Empty Table
2120     /**
2121      * Attach Ajax event handler for Drop Table
2122      * 
2123      * @uses    PMA_ajaxShowMessage()
2124      * @uses    $.PMA_confirm()
2125      * @uses    window.parent.refreshNavigation()
2126      */
2127     $("#drop_table_anchor").live('click', function(event) {
2128         event.preventDefault();
2130         /**
2131          * @var question    String containing the question to be asked for confirmation
2132          */
2133         var question = 'DROP TABLE/VIEW ' + window.parent.table;
2134         $(this).PMA_confirm(question, $(this).attr('href'), function(url) {
2136             PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2137             $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function(data) {
2138                 if(data.success == true) {
2139                     PMA_ajaxShowMessage(data.message);
2140                     $("#topmenucontainer")
2141                     .next('div')
2142                     .remove()
2143                     .end()
2144                     .after(data.sql_query);
2145                     window.parent.table = '';
2146                     window.parent.refreshNavigation();
2147                 }
2148                 else {
2149                     PMA_ajaxShowMessage(data.error);
2150                 }
2151             }) // end $.get
2152         }) // end $.PMA_confirm()
2153     }) // end $().live()
2154 }, 'top.frame_content'); //end $(document).ready() for libraries/tbl_links.inc.php
2157  * Attach Ajax event handlers for Drop Trigger.  Used on tbl_structure.php
2158  */
2159 $(document).ready(function() {
2161     $(".drop_trigger_anchor").live('click', function(event) {
2162         event.preventDefault();
2164         /**
2165          * @var curr_row    Object reference to the current trigger's <tr>
2166          */
2167         var curr_row = $(this).parents('tr');
2168         /**
2169          * @var question    String containing the question to be asked for confirmation
2170          */
2171         var question = 'DROP TRIGGER IF EXISTS `' + $(curr_row).children('td:first').text() + '`';
2173         $(this).PMA_confirm(question, $(this).attr('href'), function(url) {
2175             PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2176             $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function(data) {
2177                 if(data.success == true) {
2178                     PMA_ajaxShowMessage(data.message);
2179                     $("#topmenucontainer")
2180                     .next('div')
2181                     .remove()
2182                     .end()
2183                     .after(data.sql_query);
2184                     $(curr_row).hide("medium").remove();
2185                 }
2186                 else {
2187                     PMA_ajaxShowMessage(data.error);
2188                 }
2189             }) // end $.get()
2190         }) // end $.PMA_confirm()
2191     }) // end $().live()
2192 }, 'top.frame_content'); //end $(document).ready() for Drop Trigger
2195  * Attach Ajax event handlers for Drop Database. Moved here from db_structure.js 
2196  * as it was also required on db_create.php
2197  * 
2198  * @uses    $.PMA_confirm()
2199  * @uses    PMA_ajaxShowMessage()
2200  * @uses    window.parent.refreshNavigation()
2201  * @uses    window.parent.refreshMain()
2202  */
2203 $(document).ready(function() {
2204     $("#drop_db_anchor").live('click', function(event) {
2205         event.preventDefault();
2207         //context is top.frame_content, so we need to use window.parent.db to access the db var
2208         /**
2209          * @var question    String containing the question to be asked for confirmation
2210          */
2211         var question = PMA_messages['strDropDatabaseStrongWarning'] + '\n' + PMA_messages['strDoYouReally'] + ' :\n' + 'DROP DATABASE ' + window.parent.db;
2213         $(this).PMA_confirm(question, $(this).attr('href') ,function(url) {
2215             PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2216             $.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function(data) {
2217                 //Database deleted successfully, refresh both the frames
2218                 window.parent.refreshNavigation();
2219                 window.parent.refreshMain();
2220             }) // end $.get()
2221         }); // end $.PMA_confirm()
2222     }); //end of Drop Database Ajax action
2223 }) // end of $(document).ready() for Drop Database
2226  * Attach Ajax event handlers for 'Create Database'.  Used wherever libraries/
2227  * display_create_database.lib.php is used, ie main.php and server_databases.php
2229  * @uses    PMA_ajaxShowMessage()
2230  */
2231 $(document).ready(function() {
2233     $('#create_database_form').live('submit', function(event) {
2234         event.preventDefault();
2236         PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2237         $(this).append('<input type="hidden" name="ajax_request" value="true" />');
2239         $.post($(this).attr('action'), $(this).serialize(), function(data) {
2240             if(data.success == true) {
2241                 PMA_ajaxShowMessage(data.message);
2243                 //Append database's row to table
2244                 $("#tabledatabases")
2245                 .find('tbody')
2246                 .append(data.new_db_string)
2247                 .PMA_sort_table('.name')
2248                 .find('#db_summary_row')
2249                 .appendTo('#tabledatabases tbody')
2250                 .removeClass('odd even');
2251             }
2252             else {
2253                 PMA_ajaxShowMessage(data.error);
2254             }
2255         }) // end $.post()
2256     }) // end $().live()
2257 })  // end $(document).ready() for Create Database
2260  * Attach Ajax event handlers for 'Change Password' on main.php
2261  */
2262 $(document).ready(function() {
2264     /**
2265      * Attach Ajax event handler on the change password anchor
2266      */
2267     $('#change_password_anchor').live('click', function(event) {
2268         event.preventDefault();
2270         /**
2271          * @var button_options  Object containing options to be passed to jQueryUI's dialog
2272          */
2273         var button_options = {};
2275         button_options[PMA_messages['strCancel']] = function() {$(this).dialog('close').remove();}
2277         $.get($(this).attr('href'), {'ajax_request': true}, function(data) {
2278             $('<div id="change_password_dialog></div>')
2279             .dialog({
2280                 title: top.frame_content.PMA_messages['strChangePassword'],
2281                 width: 600,
2282                 buttons : button_options
2283             })
2284             .append(data);
2285         }) // end $.get()
2286     }) // end handler for change password anchor
2288     /**
2289      * Attach Ajax event handler for Change Password form submission
2290      * 
2291      * @uses    PMA_ajaxShowMessage()
2292      */
2293     $("#change_password_form").find('input[name=change_pw]').live('click', function(event) {
2294         event.preventDefault();
2296         /**
2297          * @var the_form    Object referring to the change password form
2298          */
2299         var the_form = $("#change_password_form");
2301         /**
2302          * @var this_value  String containing the value of the submit button.
2303          * Need to append this for the change password form on Server Privileges
2304          * page to work
2305          */
2306         var this_value = $(this).val();
2308         PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2309         $(the_form).append('<input type="hidden" name="ajax_request" value="true" />');
2311         $.post($(the_form).attr('action'), $(the_form).serialize() + '&change_pw='+ this_value, function(data) {
2312             if(data.success == true) {
2314                 PMA_ajaxShowMessage(data.message);
2315                 
2316                 $("#topmenucontainer").after(data.sql_query);
2318                 $("#change_password_dialog").hide().remove();
2319                 $("#edit_user_dialog").dialog("close").remove();
2320             }
2321             else {
2322                 PMA_ajaxShowMessage(data.error);
2323             }
2324         }) // end $.post()
2325     }) // end handler for Change Password form submission
2326 }) // end $(document).ready() for Change Password
2329  * Toggle the hiding/showing of the "Open in ENUM/SET editor" message when
2330  * the page loads and when the selected data type changes
2331  */
2332 $(document).ready(function() {
2333     $.each($("select[class='column_type']"), function() {
2334         toggle_enum_notice($(this));
2335     });
2336     $("select[class='column_type']").change(function() {
2337         toggle_enum_notice($(this));
2338     });
2342  * Closes the ENUM/SET editor and removes the data in it
2343  */
2344 function disable_popup() {
2345     $("#popup_background").fadeOut("fast");
2346     $("#enum_editor").fadeOut("fast");
2347     // clear the data from the text boxes
2348     $("#enum_editor #values input").remove();
2349     $("#enum_editor input[type='hidden']").remove();
2353  * Opens the ENUM/SET editor and controls its functions
2354  */
2355 $(document).ready(function() {
2356     $("a[class='open_enum_editor']").click(function() {
2357         // Center the popup
2358         var windowWidth = document.documentElement.clientWidth;
2359         var windowHeight = document.documentElement.clientHeight;
2360         var popupWidth = windowWidth/2;
2361         var popupHeight = windowHeight*0.8;
2362         var popupOffsetTop = windowHeight/2 - popupHeight/2;
2363         var popupOffsetLeft = windowWidth/2 - popupWidth/2;
2364         $("#enum_editor").css({"position":"absolute", "top": popupOffsetTop, "left": popupOffsetLeft, "width": popupWidth, "height": popupHeight});
2366         // Make it appear
2367         $("#popup_background").css({"opacity":"0.7"});
2368         $("#popup_background").fadeIn("fast");
2369         $("#enum_editor").fadeIn("fast");
2371         // Get the values
2372         var values = $(this).parent().prev("input").attr("value").split(",");
2373         $.each(values, function(index, val) {
2374             if(jQuery.trim(val) != "") {
2375                  // enclose the string in single quotes if it's not already
2376                  if(val.substr(0, 1) != "'") {
2377                       val = "'" + val;
2378                  }
2379                  if(val.substr(val.length-1, val.length) != "'") {
2380                       val = val + "'";
2381                  }
2382                 // escape the single quotes, except the mandatory ones enclosing the entire string
2383                 val = val.substr(1, val.length-2).replace(/'/g, "&#039;");
2384                 // escape the greater-than symbol
2385                 val = val.replace(/>/g, "&gt;");
2386                 $("#enum_editor #values").append("<input type='text' value=" + val + " />");
2387             }
2388         });
2389         // So we know which column's data is being edited
2390         $("#enum_editor").append("<input type='hidden' value='" + $(this).parent().prev("input").attr("id") + "' />");
2391         return false;
2392     });
2394     // If the "close" link is clicked, close the enum editor
2395     $("a[class='close_enum_editor']").click(function() {
2396         disable_popup();
2397     });
2399     // If the "cancel" link is clicked, close the enum editor
2400     $("a[class='cancel_enum_editor']").click(function() {
2401         disable_popup();
2402     });
2404     // When "add a new value" is clicked, append an empty text field
2405     $("a[class='add_value']").click(function() {
2406         $("#enum_editor #values").append("<input type='text' />");
2407     });
2409     // When the submit button is clicked, put the data back into the original form
2410     $("#enum_editor input[type='submit']").click(function() {
2411         var value_array = new Array();
2412         $.each($("#enum_editor #values input"), function(index, input_element) {
2413             val = jQuery.trim(input_element.value);
2414             if(val != "") {
2415                 value_array.push("'" + val + "'");
2416             }
2417         });
2418         // get the Length/Values text field where this value belongs
2419         var values_id = $("#enum_editor input[type='hidden']").attr("value");
2420         $("input[id='" + values_id + "']").attr("value", value_array.join(","));
2421         disable_popup();
2422      });
2424     /**
2425      * Hides certain table structure actions, replacing them with the word "More". They are displayed
2426      * in a dropdown menu when the user hovers over the word "More."
2427      */
2428     // Remove the actions from the table cells (they are available by default for JavaScript-disabled browsers)
2429     // if the table is not a view or information_schema (otherwise there is only one action to hide and there's no point)
2430     if($("input[type='hidden'][name='table_type']").attr("value") == "table") {
2431          $("table[id='tablestructure'] td[class='browse']").remove();
2432          $("table[id='tablestructure'] td[class='primary']").remove();
2433          $("table[id='tablestructure'] td[class='unique']").remove();
2434          $("table[id='tablestructure'] td[class='index']").remove();
2435          $("table[id='tablestructure'] td[class='fulltext']").remove();
2436          $("table[id='tablestructure'] th[class='action']").attr("colspan", 3);
2438          // Display the "more" text
2439          $("table[id='tablestructure'] td[class='more_opts']").show()
2441          // Position the dropdown
2442          $.each($(".structure_actions_dropdown"), function() {
2443               // The top offset must be set for IE even if it didn't change
2444              var cell_right_edge_offset = $(this).parent().offset().left + $(this).parent().innerWidth();
2445              var left_offset = cell_right_edge_offset - $(this).innerWidth();
2446              var top_offset = $(this).parent().offset().top + $(this).parent().innerHeight();
2447              $(this).offset({ top: top_offset, left: left_offset });
2448          });
2450          // A hack for IE6 to prevent the after_field select element from being displayed on top of the dropdown by
2451          // positioning an iframe directly on top of it
2452          $("iframe[class='IE_hack']").width($("select[name='after_field']").width());
2453          $("iframe[class='IE_hack']").height($("select[name='after_field']").height());
2454          $("iframe[class='IE_hack']").offset({ top: $("select[name='after_field']").offset().top, left: $("select[name='after_field']").offset().left });
2456          // When "more" is hovered over, show the hidden actions
2457          $("table[id='tablestructure'] td[class='more_opts']").mouseenter(
2458              function() {
2459                 if($.browser.msie && $.browser.version == "6.0") {
2460                     $("iframe[class='IE_hack']").show();
2461                     $("iframe[class='IE_hack']").width($("select[name='after_field']").width()+4);
2462                     $("iframe[class='IE_hack']").height($("select[name='after_field']").height()+4);
2463                     $("iframe[class='IE_hack']").offset({ top: $("select[name='after_field']").offset().top, left: $("select[name='after_field']").offset().left});
2464                 }
2465                 $(".structure_actions_dropdown").hide(); // Hide all the other ones that may be open
2466                 $(this).children(".structure_actions_dropdown").show();
2467                 // Need to do this again for IE otherwise the offset is wrong
2468                 if($.browser.msie) {
2469                     var left_offset_IE = $(this).offset().left + $(this).innerWidth() - $(this).children(".structure_actions_dropdown").innerWidth();
2470                     var top_offset_IE = $(this).offset().top + $(this).innerHeight();
2471                     $(this).children(".structure_actions_dropdown").offset({ top: top_offset_IE, left: left_offset_IE });
2472                 }
2473          });
2474          $(".structure_actions_dropdown").mouseleave(function() {
2475               $(this).hide();
2476               if($.browser.msie && $.browser.version == "6.0") {
2477                   $("iframe[class='IE_hack']").hide();
2478               }
2479          });
2480     }
2483 /* Displays tooltips */
2484 $(document).ready(function() {
2485     // Hide the footnotes from the footer (which are displayed for
2486     // JavaScript-disabled browsers) since the tooltip is sufficient
2487     $(".footnotes").hide();
2488     $(".footnotes span").each(function() {
2489         $(this).children("sup").remove();
2490     });
2491     // The border and padding must be removed otherwise a thin yellow box remains visible
2492     $(".footnotes").css("border", "none");
2493     $(".footnotes").css("padding", "0px");
2495     // Replace the superscripts with the help icon
2496     $("sup[class='footnotemarker']").hide();
2497     $("img[class='footnotemarker']").show();
2499     $("img[class='footnotemarker']").each(function() {
2500         var span_id = $(this).attr("id");
2501         span_id = span_id.split("_")[1];
2502         var tooltip_text = $(".footnotes span[id='footnote_" + span_id + "']").html();
2503         $(this).qtip({
2504             content: tooltip_text,
2505             show: { delay: 0 },
2506             hide: { when: 'unfocus', delay: 0 },
2507             style: { background: '#ffffcc' }
2508         });
2509     });
2512 function menuResize()
2514     var cnt = $('#topmenu');
2515     var wmax = cnt.width() - 5; // 5 px margin for jumping menu in Chrome
2516     var submenu = cnt.find('.submenu');
2517     var submenu_w = submenu.outerWidth(true);
2518     var submenu_ul = submenu.find('ul');
2519     var li = cnt.find('> li');
2520     var li2 = submenu_ul.find('li');
2521     var more_shown = li2.length > 0;
2522     var w = more_shown ? submenu_w : 0;
2524     // hide menu items
2525     var hide_start = 0;
2526     for (var i = 0; i < li.length-1; i++) { // li.length-1: skip .submenu element
2527         var el = $(li[i]);
2528         var el_width = el.outerWidth(true);
2529         el.data('width', el_width);
2530         w += el_width;
2531         if (w > wmax) {
2532             w -= el_width;
2533             if (w + submenu_w < wmax) {
2534                 hide_start = i;
2535             } else {
2536                 hide_start = i-1;
2537                 w -= $(li[i-1]).data('width');
2538             }
2539             break;
2540         }
2541     }
2543     if (hide_start > 0) {
2544         for (var i = hide_start; i < li.length-1; i++) {
2545             $(li[i])[more_shown ? 'prependTo' : 'appendTo'](submenu_ul);
2546         }
2547         submenu.show();
2548     } else if (more_shown) {
2549         w -= submenu_w;
2550         // nothing hidden, maybe something can be restored
2551         for (var i = 0; i < li2.length; i++) {
2552             //console.log(li2[i], submenu_w);
2553             w += $(li2[i]).data('width');
2554             // item fits or (it is the last item and it would fit if More got removed)
2555             if (w+submenu_w < wmax || (i == li2.length-1 && w < wmax)) {
2556                 $(li2[i]).insertBefore(submenu);
2557                 if (i == li2.length-1) {
2558                     submenu.hide();
2559                 }
2560                 continue;
2561             }
2562             break;
2563         }
2564     }
2565     if (submenu.find('.tabactive').length) {
2566         submenu.addClass('active').find('> a').removeClass('tab').addClass('tabactive');
2567     } else {
2568         submenu.removeClass('active').find('> a').addClass('tab').removeClass('tabactive');
2569     }
2572 $(function() {
2573     var topmenu = $('#topmenu');
2574     if (topmenu.length == 0) {
2575         return;
2576     }
2577     // create submenu container
2578     var link = $('<a />', {href: '#', 'class': 'tab'})
2579         .text(PMA_messages['strMore'])
2580         .click(function(e) {
2581             e.preventDefault();
2582         });
2583     var img = topmenu.find('li:first-child img');
2584     if (img.length) {
2585         img.clone().attr('src', img.attr('src').replace(/\/[^\/]+$/, '/b_more.png')).prependTo(link);
2586     }
2587     var submenu = $('<li />', {'class': 'submenu'})
2588         .append(link)
2589         .append($('<ul />'))
2590         .mouseenter(function() {
2591             if ($(this).find('ul .tabactive').length == 0) {
2592                 $(this).addClass('submenuhover').find('> a').addClass('tabactive');
2593             }
2594         })
2595         .mouseleave(function() {
2596             if ($(this).find('ul .tabactive').length == 0) {
2597                 $(this).removeClass('submenuhover').find('> a').removeClass('tabactive');
2598             }
2599         })
2600         .hide();
2601     topmenu.append(submenu);
2603     // populate submenu and register resize event
2604     $(window).resize(menuResize);
2605     menuResize();