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