1
var $table_clone=false;var sql_box_locked=false;var only_once_elements=[];var ajax_message_count=0;var codemirror_editor=false;var codemirror_inline_editor=false;var chart_activeTimeouts={};$.ajaxPrefilter(function(a,d,c){var b=new Date().getTime()+""+Math.floor(Math.random()*1000000);if(typeof a.data=="string"){a.data+="&_nocache="+b}else{if(typeof a.data=="object"){a.data=$.extend(d.data,{_nocache:b})}}});function PMA_prepareForAjaxRequest(a){if(!a.find("input:hidden").is("#ajax_request_hidden")){a.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />')}}function suggestPassword(a){var d="abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";var e=16;var b=a.generated_pw;b.value="";for(var c=0;c<e;c++){b.value+=d.charAt(Math.floor(Math.random()*d.length))}a.text_pma_pw.value=b.value;a.text_pma_pw2.value=b.value;return true}function parseVersionString(h){if(typeof(h)!="string"){return false}var g=0;var f=h.split("-");if(f.length>=2){if(f[1].substr(0,2)=="rc"){g=-20-parseInt(f[1].substr(2))}else{if(f[1].substr(0,4)=="beta"){g=-40-parseInt(f[1].substr(4))}else{if(f[1].substr(0,5)=="alpha"){g=-60-parseInt(f[1].substr(5))}else{if(f[1].substr(0,3)=="dev"){g=0}}}}}var a=h.split(".");var c=parseInt(a[0])||0;var d=parseInt(a[1])||0;var b=parseInt(a[2])||0;var e=parseInt(a[3])||0;return c*100000000+d*1000000+b*10000+e*100+g}function PMA_current_version(d){if(d&&d.version&&d.date){var e=parseVersionString(pmaversion);var b=parseVersionString(d.version);var f=PMA_messages.strLatestAvailable+" "+escapeHtml(d.version);if(b>e){var c=$.sprintf(PMA_messages.strNewerVersion,escapeHtml(d.version),escapeHtml(d.date));if(Math.floor(b/10000)===Math.floor(e/10000)){var a="error"}else{var a="notice"}$("#maincontainer").after('<div class="'+a+'">'+c+"</div>")}if(b===e){f=" ("+PMA_messages.strUpToDate+")"}$("#li_pma_version").append(f)}}function PMA_display_git_revision(){$("#is_git_revision").remove();$.get("index.php",{server:PMA_commonParams.get("server"),token:PMA_commonParams.get("token"),git_revision:true,ajax_request:true},function(a){if(a.success==true){$(a.message).insertAfter("#li_pma_version")}})}function displayPasswordGenerateButton(){$("#tr_element_before_generate_password").parent().append('<tr class="vmiddle"><td>'+PMA_messages.strGeneratePassword+'</td><td><input type="button" class="button" id="button_generate_password" value="'+PMA_messages.strGenerate+'" onclick="suggestPassword(this.form)" /><input type="text" name="generated_pw" id="generated_pw" /></td></tr>');$("#div_element_before_generate_password").parent().append('<div class="item"><label for="button_generate_password">'+PMA_messages.strGeneratePassword+':</label><span class="options"><input type="button" class="button" id="button_generate_password" value="'+PMA_messages.strGenerate+'" onclick="suggestPassword(this.form)" /></span><input type="text" name="generated_pw" id="generated_pw" /></div>')}function PMA_addDatepicker(d,b){var c=false;if(d.is(".datetimefield")){c=true}var a={showOn:"button",buttonImage:themeCalendarImage,buttonImageOnly:true,stepMinutes:1,stepHours:1,showSecond:true,showTimepicker:c,showButtonPanel:false,dateFormat:"yy-mm-dd",timeFormat:"HH:mm:ss",altFieldTimeOnly:false,showAnim:"",beforeShow:function(e,f){d.data("comes_from","datepicker");setTimeout(function(){$("#ui-timepicker-div").css("z-index",$("#ui-datepicker-div").css("z-index"))},0)},onClose:function(f,e){d.data("comes_from","")}};if(c||(typeof(b)!="undefined"&&b.showTimepicker)){d.datetimepicker($.extend(a,b))}else{d.datepicker($.extend(a,b))}}function selectContent(b,a,c){if(c&&only_once_elements[b.name]){return}only_once_elements[b.name]=true;if(a){return}b.select()}function confirmLink(d,b){if(PMA_messages.strDoYouReally==""||typeof(window.opera)!="undefined"){return true}var a=confirm($.sprintf(PMA_messages.strDoYouReally,b));if(a){if($(d).hasClass("formLinkSubmit")){var c="is_js_confirmed";if($(d).attr("href").indexOf("usesubform")!=-1){c="subform["+$(d).attr("href").substr("#").match(/usesubform\[(\d+)\]/i)[1]+"][is_js_confirmed]"}$(d).parents("form").append('<input type="hidden" name="'+c+'" value="1" />')}else{if(typeof(d.href)!="undefined"){d.href+="&is_js_confirmed=1"}else{if(typeof(d.form)!="undefined"){d.form.action+="?is_js_confirmed=1"}}}}return a}function confirmQuery(d,e){if(PMA_messages.strDoYouReally==""){return true}if(PMA_messages.strNoDropDatabases!=""){var f=new RegExp("(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s","i");if(f.test(e.value)){alert(PMA_messages.strNoDropDatabases);d.reset();e.focus();return false}}var b=new RegExp("^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s","i");var a=new RegExp("^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s","i");var h=new RegExp("^\\s*DELETE\\s+FROM\\s","i");var g=new RegExp("^\\s*TRUNCATE\\s","i");if(b.test(e.value)||a.test(e.value)||h.test(e.value)||g.test(e.value)){var i=(e.value.length>100)?e.value.substr(0,100)+"\n ...":e.value;var c=confirm($.sprintf(PMA_messages.strDoYouReally,i));if(c){d.elements.is_js_confirmed.value=1;return true}else{window.focus();e.focus();return false}}return true}function checkSqlQuery(d){if(codemirror_editor){d.elements.sql_query.value=codemirror_editor.getValue()}var b=d.elements.sql_query;var c=1;var a=new RegExp("\\s+");if(typeof(d.elements.sql_file)!="undefined"&&d.elements.sql_file.value.replace(a,"")!=""){return true}if(typeof(d.elements.sql_localfile)!="undefined"&&d.elements.sql_localfile.value.replace(a,"")!=""){return true}if(c&&typeof(d.elements.id_bookmark)!="undefined"&&(d.elements.id_bookmark.value!=null||d.elements.id_bookmark.value!="")&&d.elements.id_bookmark.selectedIndex!=0){return true}if(b.value.replace(a,"")!=""){if(confirmQuery(d,b)){return true}else{return false}}d.reset();c=1;if(c){b.select();alert(PMA_messages.strFormEmpty);b.focus();return false}return true}function emptyCheckTheField(d,b){var a=d.elements[b];var c=new RegExp("\\s+");return(a.value.replace(c,"")=="")?1:0}function emptyFormElements(d,b){var a=d.elements[b];var c=emptyCheckTheField(d,b);return c}function checkFormElementInRange(g,d,e,c,b){var a=g.elements[d];var f=parseInt(a.value);if(typeof(c)=="undefined"){c=0}if(typeof(b)=="undefined"){b=Number.MAX_VALUE}if(isNaN(f)){a.select();alert(PMA_messages.strNotNumber);a.focus();return false}else{if(f<c||f>b){a.select();alert($.sprintf(e,f));a.focus();return false}else{a.value=f}}return true}function checkTableEditForm(g,j){var f=0;var e,h,a,k,d,c;for(e=0;e<j;e++){c="#field_"+e+"_2";h=$(c);d=h.val();if(d=="VARCHAR"||d=="CHAR"||d=="BIT"||d=="VARBINARY"||d=="BINARY"){a=$("#field_"+e+"_3");d=parseInt(a.val());k=$("#field_"+e+"_1");if(isNaN(d)&&k.val()!=""){a.select();alert(PMA_messages.strNotNumber);a.focus();return false}}if(f==0){c="field_"+e+"_1";if(!emptyCheckTheField(g,c)){f=1}}}if(f==0){var b=g.elements.field_0_1;alert(PMA_messages.strFormEmpty);b.focus();return false}if($("input.textfield[name='table']").val()==""){alert(PMA_messages.strFormEmpty);$("input.textfield[name='table']").focus();return false}return true}AJAX.registerTeardown("functions.js",function(){$("input:checkbox.checkall").die("click")});AJAX.registerOnload("functions.js",function(){$("input:checkbox.checkall").live("click",function(g){var d=$(this).closest("tr");if(!g.shiftKey||last_clicked_row==-1){var b=d.find(":checkbox");if(b.length){var c=b.prop("checked");if(!$(g.target).is(":checkbox, label")){c=!c;b.prop("checked",c).trigger("change")}if(c){d.addClass("marked")}else{d.removeClass("marked")}last_click_checked=c}else{d.toggleClass("marked");last_click_checked=false}last_clicked_row=last_click_checked?$("tr.odd:not(.noclick), tr.even:not(.noclick)").index(d):-1;last_shift_clicked_row=-1}else{PMA_clearSelection();var h,a;if(last_shift_clicked_row>=0){if(last_shift_clicked_row>=last_clicked_row){h=last_clicked_row;a=last_shift_clicked_row}else{h=last_shift_clicked_row;a=last_clicked_row}d.parent().find("tr.odd:not(.noclick), tr.even:not(.noclick)").slice(h,a+1).removeClass("marked").find(":checkbox").prop("checked",false).trigger("change")}var f=$("tr.odd:not(.noclick), tr.even:not(.noclick)").index(d);if(f>=last_clicked_row){h=last_clicked_row;a=f}else{h=f;a=last_clicked_row}d.parent().find("tr.odd:not(.noclick), tr.even:not(.noclick)").slice(h,a+1).addClass("marked").find(":checkbox").prop("checked",true).trigger("change");last_shift_clicked_row=f}});addDateTimePicker();if(navigator.userAgent.match(/(iphone|ipod|ipad)/i)){$("input[type=text]").attr("autocapitalize","off").attr("autocorrect","off")}});var last_click_checked=false;var last_clicked_row=-1;var last_shift_clicked_row=-1;var marked_row=[];function markAllRows(a){$("#"+a).find("input:checkbox:enabled").prop("checked",true).trigger("change").parents("tr").addClass("marked");return true}function unMarkAllRows(a){$("#"+a).find("input:checkbox:enabled").prop("checked",false).trigger("change").parents("tr").removeClass("marked");return true}function setCheckboxes(b,a){$("#"+b).find("input:checkbox").prop("checked",a);return true}function setSelectOptions(b,a,c){$("form[name='"+b+"'] select[name='"+a+"']").find("option").prop("selected",c);return true}function setQuery(a){if(codemirror_editor){codemirror_editor.setValue(a);codemirror_editor.focus()}else{document.sqlform.sql_query.value=a;document.sqlform.sql_query.focus()}}function insertQuery(c){if(c=="clear"){setQuery("");return}var f="";var a=document.sqlform.dummy;var h=document.sqlform.table.value;if(a.options.length>0){sql_box_locked=true;var b="";var g="";var e="";var j=0;for(var d=0;d<a.options.length;d++){j++;if(j>1){b+=", ";g+=",";e+=","}b+=a.options[d].value;g+="[value-"+j+"]";e+=a.options[d].value+"=[value-"+j+"]"}if(c=="selectall"){f="SELECT * FROM `"+h+"` WHERE 1"}else{if(c=="select"){f="SELECT "+b+" FROM `"+h+"` WHERE 1"}else{if(c=="insert"){f="INSERT INTO `"+h+"`("+b+") VALUES ("+g+")"}else{if(c=="update"){f="UPDATE `"+h+"` SET "+e+" WHERE 1"}else{if(c=="delete"){f="DELETE FROM `"+h+"` WHERE 1"}}}}}setQuery(f);sql_box_locked=false}}function insertValueQuery(){var h=document.sqlform.sql_query;var d=document.sqlform.dummy;if(d.options.length>0){sql_box_locked=true;var e="";var j=0;for(var f=0;f<d.options.length;f++){if(d.options[f].selected){j++;if(j>1){e+=", "}e+=d.options[f].value}}if(codemirror_editor){codemirror_editor.replaceSelection(e)}else{if(document.selection){h.focus();var c=document.selection.createRange();c.text=e;document.sqlform.insert.focus()}else{if(document.sqlform.sql_query.selectionStart||document.sqlform.sql_query.selectionStart=="0"){var g=document.sqlform.sql_query.selectionStart;var b=document.sqlform.sql_query.selectionEnd;var a=document.sqlform.sql_query.value;h.value=a.substring(0,g)+e+a.substring(b,a.length)}else{h.value+=e}}}sql_box_locked=false}}function addDateTimePicker(){if($.timepicker!=undefined){$("input.datefield, input.datetimefield").each(function(){PMA_addDatepicker($(this))})}}function refreshLayout(){var c=$("#pdflayout");var d=$("#orientation_opt").val();if($("#paper_opt").length==1){var e=$("#paper_opt").val()}else{var e="A4"}if(d=="P"){var b="x";var a="y"}else{var b="y";var a="x"}c.css("width",pdfPaperSize(e,b)+"px");c.css("height",pdfPaperSize(e,a)+"px")}function TableDragInit(){$(".pdflayout_table").each(function(){var c=$(this);var b=c.data("number");var a=$("#c_table_"+b+"_x").val();var d=$("#c_table_"+b+"_y").val();c.css("left",a+"px");c.css("top",d+"px");c.draggable({containment:"parent",drag:function(e,g){var f=c.data("number");$("#c_table_"+f+"_x").val(parseInt(g.position.left));$("#c_table_"+f+"_y").val(parseInt(g.position.top))}})})}function resetDrag(){$(".pdflayout_table").each(function(){var b=$(this);var a=b.data("x");var c=b.data("y");b.css("left",a+"px");b.css("top",c+"px")})}$(function(){$(".position-change").live("change",function(){var b=$(this);var a=$("#table_"+b.data("number"));a.css(b.data("axis"),b.val()+"px")});$(".paper-change").live("change",function(){var a=$("#pdflayout");if(a.css("visibility")=="visible"){refreshLayout();TableDragInit()}});$("#toggle-dragdrop").live("click",function(){var a=$("#pdflayout");if(a.css("visibility")=="hidden"){refreshLayout();TableDragInit();a.css("visibility","visible");a.css("display","block");$("#showwysiwyg").val("1")}else{a.css("visibility","hidden");a.css("display","none");$("#showwysiwyg").val("0")}});$("#reset-dragdrop").live("click",function(){resetDrag()})});function pdfPaperSize(b,a){switch(b.toUpperCase()){case"4A0":if(a=="x"){return 4767.87}else{return 6740.79}break;case"2A0":if(a=="x"){return 3370.39}else{return 4767.87}break;case"A0":if(a=="x"){return 2383.94}else{return 3370.39}break;case"A1":if(a=="x"){return 1683.78}else{return 2383.94}break;case"A2":if(a=="x"){return 1190.55}else{return 1683.78}break;case"A3":if(a=="x"){return 841.89}else{return 1190.55}break;case"A4":if(a=="x"){return 595.28}else{return 841.89}break;case"A5":if(a=="x"){return 419.53}else{return 595.28}break;case"A6":if(a=="x"){return 297.64}else{return 419.53}break;case"A7":if(a=="x"){return 209.76}else{return 297.64}break;case"A8":if(a=="x"){return 147.4}else{return 209.76}break;case"A9":if(a=="x"){return 104.88}else{return 147.4}break;case"A10":if(a=="x"){return 73.7}else{return 104.88}break;case"B0":if(a=="x"){return 2834.65}else{return 4008.19}break;case"B1":if(a=="x"){return 2004.09}else{return 2834.65}break;case"B2":if(a=="x"){return 1417.32}else{return 2004.09}break;case"B3":if(a=="x"){return 1000.63}else{return 1417.32}break;case"B4":if(a=="x"){return 708.66}else{return 1000.63}break;case"B5":if(a=="x"){return 498.9}else{return 708.66}break;case"B6":if(a=="x"){return 354.33}else{return 498.9}break;case"B7":if(a=="x"){return 249.45}else{return 354.33}break;case"B8":if(a=="x"){return 175.75}else{return 249.45}break;case"B9":if(a=="x"){return 124.72}else{return 175.75}break;case"B10":if(a=="x"){return 87.87}else{return 124.72}break;case"C0":if(a=="x"){return 2599.37}else{return 3676.54}break;case"C1":if(a=="x"){return 1836.85}else{return 2599.37}break;case"C2":if(a=="x"){return 1298.27}else{return 1836.85}break;case"C3":if(a=="x"){return 918.43}else{return 1298.27}break;case"C4":if(a=="x"){return 649.13}else{return 918.43}break;case"C5":if(a=="x"){return 459.21}else{return 649.13}break;case"C6":if(a=="x"){return 323.15}else{return 459.21}break;case"C7":if(a=="x"){return 229.61}else{return 323.15}break;case"C8":if(a=="x"){return 161.57}else{return 229.61}break;case"C9":if(a=="x"){return 113.39}else{return 161.57}break;case"C10":if(a=="x"){return 79.37}else{return 113.39}break;case"RA0":if(a=="x"){return 2437.8}else{return 3458.27}break;case"RA1":if(a=="x"){return 1729.13}else{return 2437.8}break;case"RA2":if(a=="x"){return 1218.9}else{return 1729.13}break;case"RA3":if(a=="x"){return 864.57}else{return 1218.9}break;case"RA4":if(a=="x"){return 609.45}else{return 864.57}break;case"SRA0":if(a=="x"){return 2551.18}else{return 3628.35}break;case"SRA1":if(a=="x"){return 1814.17}else{return 2551.18}break;case"SRA2":if(a=="x"){return 1275.59}else{return 1814.17}break;case"SRA3":if(a=="x"){return 907.09}else{return 1275.59}break;case"SRA4":if(a=="x"){return 637.8}else{return 907.09}break;case"LETTER":if(a=="x"){return 612}else{return 792}break;case"LEGAL":if(a=="x"){return 612}else{return 1008}break;case"EXECUTIVE":if(a=="x"){return 521.86}else{return 756}break;case"FOLIO":if(a=="x"){return 612}else{return 936}break}return 0}AJAX.registerTeardown("functions.js",function(){$("a.inline_edit_sql").die("click");$("input#sql_query_edit_save").die("click");$("input#sql_query_edit_discard").die("click");$("input.sqlbutton").unbind("click");$("#export_type").unbind("change");$("#sqlquery").unbind("keydown");$("#sql_query_edit").unbind("keydown");if(codemirror_inline_editor){$("#sql_query_edit").text(codemirror_inline_editor.getValue());$(codemirror_inline_editor.getWrapperElement()).unbind("keydown");codemirror_inline_editor.toTextArea();codemirror_inline_editor=false}if(codemirror_editor){$(codemirror_editor.getWrapperElement()).unbind("keydown")}});AJAX.registerOnload("functions.js",function(){bindCodeMirrorToInlineEditor();$("a.inline_edit_sql").live("click",function(){if($("#sql_query_edit").length){return false}var a=$(this).prev("form");var f=a.find("input[name='sql_query']").val();var e=$(this).parent().prev().find(".inner_sql");var d=e.html();var c='<textarea name="sql_query_edit" id="sql_query_edit">'+f+"</textarea>\n";c+='<input type="submit" id="sql_query_edit_save" class="button btnSave" value="'+PMA_messages.strGo+'"/>\n';c+='<input type="button" id="sql_query_edit_discard" class="button btnDiscard" value="'+PMA_messages.strCancel+'"/>\n';var b=$("div#inline_editor");if(b.length==0){b=$('<div id="inline_editor_outer"></div>');b.insertBefore(e)}b.html(c);e.hide();bindCodeMirrorToInlineEditor();return false});$("input#sql_query_edit_save").live("click",function(){if(codemirror_inline_editor){var b=codemirror_inline_editor.getValue()}else{var b=$(this).prev().val()}var a=$("a.inline_edit_sql").prev("form");var c=$("<form>",{action:"import.php",method:"post"}).append(a.find("input[name=server], input[name=db], input[name=table], input[name=token]").clone()).append($("<input/>",{type:"hidden",name:"show_query",value:1})).append($("<input/>",{type:"hidden",name:"sql_query",value:b}));c.appendTo($("body")).submit()});$("input#sql_query_edit_discard").live("click",function(){$("div#inline_editor_outer").empty().siblings(".inner_sql").show()});$("input.sqlbutton").click(function(a){insertQuery(a.target.id);return false});$("#export_type").change(function(){if($("#export_type").val()=="svg"){$("#show_grid_opt").prop("disabled",true);$("#orientation_opt").prop("disabled",true);$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").removeProp("disabled");$("#all_tables_same_width").removeProp("disabled");$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled")}else{if($("#export_type").val()=="dia"){$("#show_grid_opt").prop("disabled",true);$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").prop("disabled",true);$("#all_tables_same_width").prop("disabled",true);$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled");$("#orientation_opt").removeProp("disabled")}else{if($("#export_type").val()=="eps"){$("#show_grid_opt").prop("disabled",true);$("#orientation_opt").removeProp("disabled");$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").prop("disabled",true);$("#all_tables_same_width").prop("disabled",true);$("#paper_opt").prop("disabled",true);$("#show_color_opt").prop("disabled",true)}else{if($("#export_type").val()=="pdf"){$("#show_grid_opt").removeProp("disabled");$("#orientation_opt").removeProp("disabled");$("#with_doc").removeProp("disabled");$("#show_table_dim_opt").removeProp("disabled");$("#all_tables_same_width").removeProp("disabled");$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled")}else{}}}}});if($("#input_username")){if($("#input_username").val()==""){$("#input_username").focus()}else{$("#input_password").focus()}}});function bindCodeMirrorToInlineEditor(){var b=$("#sql_query_edit");if(b.length>0){if(typeof CodeMirror!=="undefined"){var a=$("#sql_query_edit").css("height");codemirror_inline_editor=CodeMirror.fromTextArea(b[0],{lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql",lineWrapping:true});codemirror_inline_editor.getScrollerElement().style.height=a;codemirror_inline_editor.refresh();codemirror_inline_editor.focus();$(codemirror_inline_editor.getWrapperElement()).bind("keydown",catchKeypressesFromSqlTextboxes)}else{b.focus().bind("keydown",catchKeypressesFromSqlTextboxes)}}}function catchKeypressesFromSqlTextboxes(a){if(a.ctrlKey&&(a.keyCode==13||a.keyCode==10)){if($("#sql_query_edit").length>0){$("#sql_query_edit_save").trigger("click")}else{if($("#sqlquery").length>0){$("#button_submit_query").trigger("click")}}}}function PMA_ajaxShowMessage(c,d){var b=true;var e=true;if(c==""){return true}else{if(!c){c=PMA_messages.strLoading;e=false;b=false}else{if(c==PMA_messages.strProcessingRequest){e=false;b=false}}}if(d==undefined){d=5000}else{if(d===false){b=false}}if($("#loading_parent").length==0){$('<div id="loading_parent"></div>').prependTo("body")}ajax_message_count++;$("span.ajax_notification[id^=ajax_message_num]").remove();var a=$('<span class="ajax_notification" id="ajax_message_num_'+ajax_message_count+'"></span>').hide().appendTo("#loading_parent").html(c).show();if(b){a.delay(d).fadeOut("medium",function(){if($(this).is(".dismissable")){$(this).tooltip("destroy")}$(this).remove()})}if(e){a.addClass("dismissable").css("cursor","pointer");PMA_tooltip(a,"span",PMA_messages.strDismiss)}return a}function PMA_ajaxRemoveMessage(a){if(a!=undefined&&a instanceof jQuery){a.stop(true,true).fadeOut("medium");if(a.is(".dismissable")){if($.isFunction(a.tooltip)){a.tooltip("destroy")}}else{a.remove()}}}$(function(){$("span.ajax_notification.dismissable").live("click",function(){PMA_ajaxRemoveMessage($(this))});$("span.ajax_notification a, span.ajax_notification button, span.ajax_notification input").live("mouseover",function(){$(this).parents("span.ajax_notification").tooltip("disable")}).live("mouseout",function(){$(this).parents("span.ajax_notification").tooltip("enable")})});function PMA_showNoticeForEnum(a){var b=a.attr("id").split("_")[1];b+="_"+(parseInt(a.attr("id").split("_")[2])+1);var c=a.val();if(c=="ENUM"||c=="SET"){$("p#enum_notice_"+b).show()}else{$("p#enum_notice_"+b).hide()}}function PMA_createProfilingChartJqplot(b,a){return $.jqplot(b,[a],{seriesDefaults:{renderer:$.jqplot.PieRenderer,rendererOptions:{showDataLabels:true}},legend:{show:true,location:"e"},seriesColors:["#fce94f","#fcaf3e","#e9b96e","#8ae234","#729fcf","#ad7fa8","#ef2929","#eeeeec","#888a85","#c4a000","#ce5c00","#8f5902","#4e9a06","#204a87","#5c3566","#a40000","#babdb6","#2e3436"]})}function PMA_prettyProfilingNum(a,b){if(!b){b=2}b=Math.pow(10,b);if(a*1000<0.1){a=Math.round(b*(a*1000*1000))/b+"µ"}else{if(a<0.1){a=Math.round(b*(a*1000))/b+"m"}else{a=Math.round(b*a)/b}}return a+"s"}function PMA_SQLPrettyPrint(a){if(typeof CodeMirror=="undefined"){return a}var l=CodeMirror.getMode({},"text/x-mysql");var e=new CodeMirror.StringStream(a);var d=l.startState();var g,m=[];var h="";var t=function(y){var w="";for(var x=0;x<4*y;x++){w+=" "}return w};var u={select:["select","from","on","where","having","limit","order by","group by"],update:["update","set","where"],"insert into":["insert into","values"]};var k={";":true,",":true,".":true,"(":true};var n={".":true};var o="";while(!e.eol()){e.start=e.pos;g=l.token(e,d);if(g!=null){m.push([g,e.current().toLowerCase()])}}var q=m[0][1];if(!u[q]){return a}var s=[];var f;var b,c;var p=0;var j,v=u[q][0];s.unshift("statement");for(var r=0;r<m.length;r++){f=s[0];if(m[r][1]=="("){if(r<m.length-1&&m[r+1][0]=="statement-verb"){s.unshift(b="statement")}else{if(r>0&&m[r-1][0]=="builtin"){s.unshift(b="function")}else{s.unshift(b="generic")}}}else{b=null}if(m[r][1]==")"){c=s[0];s.shift()}else{c=null}if(r>0&&b=="statement"){p++;h+="\n"+t(p)+m[r][1]+" "+m[r+1][1].toUpperCase()+"\n"+t(p+1);q=m[r+1][1];r++;continue}if(c=="statement"&&p>0){h+="\n"+t(p);p--}j=u[q].indexOf(m[r][1]);if(j!=-1){if(r>0){h+="\n"}h+=t(p)+m[r][1].toUpperCase();h+="\n"+t(p+1);v=m[r][1]}else{if(!k[m[r][1]]&&!(r>0&&n[m[r-1][1]])&&h.charAt(h.length-1)!=" "){h+=" "}if(m[r][0]=="keyword"){h+=m[r][1].toUpperCase()}else{h+=m[r][1]}}if((v=="select"||v=="where"||v=="set")&&m[r][1]==","&&s[0]=="statement"){h+="\n"+t(p+1)}if(v=="where"&&(m[r][1]=="and"||m[r][1]=="or"||m[r][1]=="xor")){if(s[0]=="statement"){h+="\n"+t(p+1)}}}return h}jQuery.fn.PMA_confirm=function(b,d,a){var e=PMA_commonParams.get("confirm");if(e===""||e==="1"){if($.isFunction(a)){a.call(this,d);return true}}if(PMA_messages.strDoYouReally==""){return true}var c={};c[PMA_messages.strOK]=function(){$(this).dialog("close");if($.isFunction(a)){a.call(this,d)}};c[PMA_messages.strCancel]=function(){$(this).dialog("close")};$("<div/>",{id:"confirm_dialog"}).prepend(b).dialog({buttons:c,close:function(){$(this).remove()},modal:true})};jQuery.fn.PMA_sort_table=function(a){return this.each(function(){var c=$(this);var b=$(this).find("tr").get();$.each(b,function(d,e){e.sortKey=$.trim($(e).find(a).text().toLowerCase())});b.sort(function(e,d){if(e.sortKey<d.sortKey){return -1}if(e.sortKey>d.sortKey){return 1}return 0});$.each(b,function(d,e){$(c).append(e);e.sortKey=null});$(this).find("tr:odd").removeClass("even").addClass("odd").end().find("tr:even").removeClass("odd").addClass("even")})};AJAX.registerTeardown("functions.js",function(){$("#create_table_form_minimal.ajax").die("submit");$("form.create_table_form.ajax").die("submit");$("form.create_table_form.ajax input[name=submit_num_fields]").die("click");$("form.create_table_form.ajax input").die("keyup")});AJAX.registerOnload("functions.js",function(){$("form.create_table_form.ajax").live("submit",function(b){b.preventDefault();var a=$(this);if(checkTableEditForm(a[0],a.find("input[name=orig_num_fields]").val())){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&do_save_data=1",function(i){if(i.success==true){$("#properties_message").removeClass("error").html("");PMA_ajaxShowMessage(i.message);if($("#create_table_dialog").length>0){$("#create_table_dialog").dialog("close").remove()}$("#tableslistcontainer").before(i.formatted_sql);var f=$("#tablesForm").find("tbody").not("#tbl_summary_row");if(f.length==0){PMA_commonActions.refreshMain(PMA_commonParams.get("opendb_url"))}else{var h=$(f).find("tr:last");var g=$(h).find("input:checkbox").attr("id").match(/\d+/)[0];var d=parseFloat(g);var c=d+1;var e="checkbox_tbl_"+c;i.new_table_string=i.new_table_string.replace(/checkbox_tbl_/,e);$(i.new_table_string).appendTo(f);$(f).PMA_sort_table("th");PMA_adjustTotals()}PMA_reloadNavigation()}else{PMA_ajaxShowMessage('<div class="error">'+i.error+"</div>",false)}})}});$("form.create_table_form.ajax input[name=submit_num_fields]").live("click",function(b){b.preventDefault();var a=$(this).closest("form");var c=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&submit_num_fields=1",function(d){if(d.success){$("#page_content").html(d.message);PMA_verifyColumnsProperties();PMA_ajaxRemoveMessage(c)}else{PMA_ajaxShowMessage(d.error)}})});$("form.create_table_form.ajax input").live("keydown",function(a){if(a.keyCode==13){a.preventDefault();a.stopImmediatePropagation();$(this).closest("form").append('<input type="hidden" name="do_save_data" value="1" />').submit()}})});AJAX.registerTeardown("functions.js",function(){$("#copyTable.ajax").die("submit");$("#moveTableForm").die("submit");$("#tableOptionsForm").die("submit");$("#tbl_maintenance li a.maintain_action.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#copyTable.ajax").live("submit",function(b){b.preventDefault();var a=$(this);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&submit_copy=Go",function(c){if(c.success==true){if(a.find("input[name='switch_to_new']").prop("checked")){PMA_commonParams.set("db",c.db);PMA_commonParams.set("table",a.find("input[name='new_name']").val());PMA_commonActions.refreshMain(false,function(){PMA_ajaxShowMessage(c.message)})}else{PMA_ajaxShowMessage(c.message)}PMA_reloadNavigation()}else{PMA_ajaxShowMessage(c.error,false)}})});$("#moveTableForm").live("submit",function(c){c.preventDefault();var b=$(this);var a=b.find("select[name=target_db]").val();var d=b.find("input[name=new_name]").val();PMA_prepareForAjaxRequest(b);$.post(b.attr("action"),b.serialize()+"&submit_move=1",function(e){if(e.success==true){PMA_commonParams.set("db",a);PMA_commonParams.set("table",d);PMA_commonActions.refreshMain(false,function(){PMA_ajaxShowMessage(e.message)});PMA_reloadNavigation()}else{PMA_ajaxShowMessage(e.error,false)}})});$("#tableOptionsForm").live("submit",function(c){c.preventDefault();c.stopPropagation();var b=$(this);var a=b.find("input[name=new_name]");if(a.val()!==a[0].defaultValue){PMA_prepareForAjaxRequest(b);var d=a.val();$.post(b.attr("action"),b.serialize(),function(e){if(e.success==true){PMA_commonParams.set("table",d);PMA_commonActions.refreshMain(false,function(){$("#page_content").html(e.message)})}else{PMA_ajaxShowMessage(e.error,false)}})}else{b.removeClass("ajax").submit().addClass("ajax")}});$("#tbl_maintenance li a.maintain_action.ajax").live("click",function(a){a.preventDefault();if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if($("#result_query").length!=0){$("#result_query").remove()}$.post($(this).attr("href"),{ajax_request:1},function(f){function d(){$("html, body").animate({scrollTop:0})}if(f.success==true&&f.sql_query!=undefined){PMA_ajaxShowMessage(f.message);$("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");$("#sqlqueryresults").html(f.sql_query);d()}else{if(f.success==true){var c=$("<div id='temp_div'></div>");c.html(f.message);var e=c.find("#result_query .success");PMA_ajaxShowMessage(e);$("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");$("#sqlqueryresults").html(f.message);PMA_init_slider();$("#sqlqueryresults").children("fieldset,br").remove();d()}else{var c=$("<div id='temp_div'></div>");c.html(f.error);var b=c.find("code").addClass("error");PMA_ajaxShowMessage(b,false)}}})})});AJAX.registerTeardown("functions.js",function(){$("#drop_db_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#drop_db_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strDropDatabaseStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"DROP DATABASE "+escapeHtml(PMA_commonParams.get("db")));$(this).PMA_confirm(a,$(this).attr("href"),function(c){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(d){if(d.success){PMA_reloadNavigation();PMA_commonParams.set("db","");PMA_commonActions.refreshMain("server_databases.php",function(){PMA_ajaxShowMessage(d.message)})}else{PMA_ajaxShowMessage(d.error,false)}})})})});function PMA_checkPassword(e){if(e.find("#nopass_1").is(":checked")){return true}else{var d=e.find("#select_pred_password");if(d.length&&(d.val()=="none"||d.val()=="keep")){return true}}var a=e.find("input[name=pma_pw]");var c=e.find("input[name=pma_pw2]");var b=false;if(a.val()==""){b=PMA_messages.strPasswordEmpty}else{if(a.val()!=c.val()){b=PMA_messages.strPasswordNotSame}}if(b){alert(b);a.val("");c.val("");a.focus();return false}return true}AJAX.registerTeardown("functions.js",function(){$("#change_password_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#change_password_anchor.ajax").live("click",function(b){b.preventDefault();var c=PMA_ajaxShowMessage();var a={};a[PMA_messages.strGo]=function(){b.preventDefault();var f=$("#change_password_form");if(!PMA_checkPassword(f)){return false}var d=$(this).val();var e=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);f.append('<input type="hidden" name="ajax_request" value="true" />');$.post(f.attr("action"),f.serialize()+"&change_pw="+d,function(g){if(g.success==true){$("#page_content").prepend(g.message);$("#change_password_dialog").hide().remove();$("#edit_user_dialog").dialog("close").remove();PMA_ajaxRemoveMessage(e)}else{PMA_ajaxShowMessage(g.error,false)}})};a[PMA_messages.strCancel]=function(){$(this).dialog("close")};$.get($(this).attr("href"),{ajax_request:true},function(d){if(d.success){$('<div id="change_password_dialog"></div>').dialog({title:PMA_messages.strChangePassword,width:600,close:function(e,f){$(this).remove()},buttons:a,modal:true}).append(d.message);$("fieldset#fieldset_change_password").find("legend").remove().end().find("table.noclick").unwrap().addClass("some-margin").find("input#text_pma_pw").focus();displayPasswordGenerateButton();$("#fieldset_change_password_footer").hide();PMA_ajaxRemoveMessage(c);$("#change_password_form").bind("submit",function(f){f.preventDefault();$(this).closest(".ui-dialog").find(".ui-dialog-buttonpane .ui-button").first().click()})}else{PMA_ajaxShowMessage(d.error,false)}})})});AJAX.registerTeardown("functions.js",function(){$("select.column_type").die("change");$("select.default_type").die("change");$("input.allow_null").die("change")});AJAX.registerOnload("functions.js",function(){PMA_verifyColumnsProperties();$("select.column_type").live("change",function(){PMA_showNoticeForEnum($(this))});$("select.default_type").live("change",function(){PMA_hideShowDefaultValue($(this))});$("input.allow_null").live("change",function(){PMA_validateDefaultValue($(this))})});function PMA_verifyColumnsProperties(){$("select.column_type").each(function(){PMA_showNoticeForEnum($(this))});$("select.default_type").each(function(){PMA_hideShowDefaultValue($(this))})}function PMA_hideShowDefaultValue(b){if(b.val()=="USER_DEFINED"){b.siblings(".default_value").show().focus()}else{b.siblings(".default_value").hide();if(b.val()=="NULL"){var a=b.closest("tr").find(".allow_null");a.prop("checked",true)}}}function PMA_validateDefaultValue(b){if(!b.prop("checked")){var a=b.closest("tr").find(".default_type");if(a.val()=="NULL"){a.val("NONE")}}}AJAX.registerTeardown("functions.js",function(){$("a.open_enum_editor").die("click");$("input.add_value").die("click");$("#enum_editor td.drop").die("click")});var $enum_editor_dialog=null;AJAX.registerOnload("functions.js",function(){$("a.open_enum_editor").live("click",function(){var e=$(this).closest("tr").find("input:first").val();if(e.length<1){var m=PMA_messages.enum_newColumnVals}else{var m=PMA_messages.enum_columnVals.replace(/%s/,'"'+decodeURIComponent(e)+'"')}var k=$(this).closest("td").find("input").val();k=$("<div/>").text(k).html();var n=[];var j=false;var o,f,c="";for(var d=0;d<k.length;d++){o=k.charAt(d);f=d==k.length?"":k.charAt(d+1);if(!j&&o=="'"){j=true}else{if(j&&o=="\\"&&f=="\\"){c+="\";d++}else{if(j&&f=="'"&&(o=="'"||o=="\\")){c+="'";d++}else{if(j&&o=="'"){j=false;n.push(c);c=""}else{if(j){c+=o}}}}}}if(c.length>0){n.push(c)}var g="";if(n.length==0){n.push("","","","")}var l=PMA_getImage("b_drop.png");for(var d=0;d<n.length;d++){g+="<tr><td><input type='text' value='"+n[d]+"'/></td><td class='drop'>"+l+"</td></tr>"}var h="<div id='enum_editor'><fieldset><legend>"+m+"</legend><p>"+PMA_getImage("s_notice.png")+PMA_messages.enum_hint+"</p><table class='values'>"+g+"</table></fieldset><fieldset class='tblFooters'><table class='add'><tr><td><div class='slider'></div></td><td><form><div><input type='submit' class='add_value' value='"+$.sprintf(PMA_messages.enum_addValue,1)+"'/></div></form></td></tr></table><input type='hidden' value='"+$(this).closest("td").find("input").attr("id")+"' /></fieldset></div>";var b={};b[PMA_messages.strGo]=function(){var i=[];$(this).find(".values input").each(function(q,s){var r=s.value.replace(/\\/g,"\\\\").replace(/'/g,"''");i.push("'"+r+"'")});var p=$(this).find("input[type='hidden']").val();$("input#"+p).val(i.join(","));$(this).dialog("close")};b[PMA_messages.strClose]=function(){$(this).dialog("close")};var a=parseInt((parseInt($("html").css("font-size"),10)/13)*340,10);if(!a){a=340}$enum_editor_dialog=$(h).dialog({minWidth:a,modal:true,title:PMA_messages.enum_editor,buttons:b,open:function(){$(this).closest(".ui-dialog").find(".ui-dialog-buttonpane button:first").focus()},close:function(){$(this).remove()}});$enum_editor_dialog.find(".slider").slider({animate:true,range:"min",value:1,min:1,max:9,slide:function(i,p){$(this).closest("table").find("input[type=submit]").val($.sprintf(PMA_messages.enum_addValue,p.value))}});$("a.ui-slider-handle").addClass("ui-state-focus");return false});$("input.add_value").live("click",function(a){a.preventDefault();var b=$enum_editor_dialog.find("div.slider").slider("value");while(b--){$enum_editor_dialog.find(".values").append("<tr style='display: none;'><td><input type='text' /></td><td class='drop'>"+PMA_getImage("b_drop.png")+"</td></tr>").find("tr:last").show("fast")}});$("#enum_editor td.drop").live("click",function(){$(this).closest("tr").hide("fast",function(){$(this).remove()})})});function checkIndexName(b){if($("#"+b).length==0){return false}var a=$("#input_index_name");var c=$("#select_index_type");if(c.find("option:selected").val()=="PRIMARY"){a.val("PRIMARY");a.prop("disabled",true)}else{if(a.val()=="PRIMARY"){a.val("")}a.prop("disabled",false)}return true}AJAX.registerTeardown("functions.js",function(){$("#index_frm input[type=submit]").die("click")});AJAX.registerOnload("functions.js",function(){$("#index_frm input[type=submit]").live("click",function(a){a.preventDefault();var b=$(this).closest("fieldset").find(".slider").slider("value");while(b--){var c=$("#index_columns").find("tbody > tr:first").clone().appendTo($("#index_columns").find("tbody"));c.find(":input").each(function(){$(this).val("")});c.find("select").change(function(){if($(this).find("option:selected").val()==""){return true}$(this).closest("tr").find("input").focus()})}})});function indexEditorDialog(d,g,f,b){if($("#edit_index_dialog").length!=0){$("#edit_index_dialog").remove()}var a=$('<div id="edit_index_dialog"></div>');var c={};c[PMA_messages.strGo]=function(){var h=$("#index_frm");PMA_prepareForAjaxRequest(h);$.post(h.attr("action"),h.serialize()+"&do_save_data=1",function(k){if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if(k.success==true){PMA_ajaxShowMessage(k.message);if($("#result_query").length){$("#result_query").remove()}if(k.sql_query){$('<div id="result_query"></div>').html(k.sql_query).prependTo("#page_content")}$("#result_query .notice").remove();$("#result_query").prepend(k.message);$("#table_index").remove();var j=$("<div id='temp_div'><div>").append(k.index_table);j.find("#table_index").insertAfter("#index_header");if($("#edit_index_dialog").length>0){$("#edit_index_dialog").dialog("close")}$("div.no_indexes_defined").hide();if(f){f()}PMA_reloadNavigation()}else{var j=$("<div id='temp_div'><div>").append(k.error);if(j.find(".error code").length!=0){var i=j.find(".error code").addClass("error")}else{var i=j}if(b){b()}PMA_ajaxShowMessage(i,false)}})};c[PMA_messages.strCancel]=function(){$(this).dialog("close")};var e=PMA_ajaxShowMessage();$.get("tbl_indexes.php",d,function(i){if(i.success==false){PMA_ajaxShowMessage(i.error,false)}else{PMA_ajaxRemoveMessage(e);a.append(i.message).dialog({title:g,width:450,open:PMA_verifyColumnsProperties,modal:true,buttons:c,close:function(){$(this).remove()}});checkIndexType();checkIndexName("index_frm");PMA_showHints(a);a.find(".slider").slider({animate:true,value:1,min:1,max:16,slide:function(j,k){$(this).closest("fieldset").find("input[type=submit]").val($.sprintf(PMA_messages.strAddToIndex,k.value))}});a.find("table#index_columns select").change(function(){if($(this).find("option:selected").val()==""){return true}$(this).closest("tr").find("input").focus()});$("a.ui-slider-handle").addClass("ui-state-focus");var h=a.find("input#input_index_name");h.val()||h.focus()}})}function PMA_showHints(a){if(a==undefined||!a instanceof jQuery||a.length==0){a=$("body")}a.find(".pma_hint").each(function(){PMA_tooltip($(this).children("img"),"img",$(this).children("span").html())})}AJAX.registerOnload("functions.js",function(){PMA_showHints()});function PMA_mainMenuResizerCallback(){return $(document.body).width()-5}$(function(){$("#topmenu").menuResizer(PMA_mainMenuResizerCallback);$(window).resize(function(){$("#topmenu").menuResizer("resize")})});function PMA_getRowNumber(a){return parseInt(a.split(/\s+row_/)[1])}function PMA_set_status_label(a){var b=a.css("display")=="none"?"+ ":"- ";a.closest(".slide-wrapper").prev().find("span").text(b)}var toggleButton=function($obj){if($("span.text_direction",$obj).text()=="ltr"){var right="right"}else{var right="left"}var h=$obj.height();$("img",$obj).height(h);$("table",$obj).css("bottom",h-1);var on=$("td.toggleOn",$obj).width();var off=$("td.toggleOff",$obj).width();$("td.toggleOn > div",$obj).width(Math.max(on,off)+2);$("td.toggleOff > div",$obj).width(Math.max(on,off)+2);var w=parseInt(($("img",$obj).height()/16)*22,10);$("table td:nth-child(2) > div",$obj).width(w);var imgw=$("img",$obj).width();var tblw=$("table",$obj).width();var offset=parseInt(((imgw-tblw)/2),10);$obj.find("img").css(right,offset);var offw=$("td.toggleOff",$obj).outerWidth();var btnw=$("table td:nth-child(2)",$obj).outerWidth();$obj.width(offw+btnw+2);var move=$("td.toggleOff",$obj).outerWidth();if($("div.container",$obj).hasClass("off")){if(right=="right"){$("div.container",$obj).animate({left:"-="+move+"px"},0)}else{$("div.container",$obj).animate({left:"+="+move+"px"},0)}}$("div.container",$obj).click(function(){if($(this).hasClass("isActive")){return false}else{$(this).addClass("isActive")}var $msg=PMA_ajaxShowMessage();var $container=$(this);var callback=$("span.callback",this).text();if($(this).hasClass("on")){if(right=="right"){var operator="-="}else{var operator="+="}var url=$(this).find("td.toggleOff > span").text();var removeClass="on";var addClass="off"}else{if(right=="right"){var operator="+="}else{var operator="-="}var url=$(this).find("td.toggleOn > span").text();var removeClass="off";var addClass="on"}$.post(url,{ajax_request:true},function(data){if(data.success==true){PMA_ajaxRemoveMessage($msg);$container.removeClass(removeClass).addClass(addClass).animate({left:operator+move+"px"},function(){$container.removeClass("isActive")});eval(callback)}else{PMA_ajaxShowMessage(data.error,false);$container.removeClass("isActive")}})})};AJAX.registerTeardown("functions.js",function(){$("div.container").unbind("click")});AJAX.registerOnload("functions.js",function(){$("div.toggleAjax").each(function(){var a=$(this).show();a.find("img").each(function(){if(this.complete){toggleButton(a)}else{$(this).load(function(){toggleButton(a)})}})})});AJAX.registerTeardown("functions.js",function(){$(".vpointer").die("hover");$(".vmarker").die("click");$("#pageselector").die("change");$("a.formLinkSubmit").die("click");$("#update_recent_tables").unbind("ready")});AJAX.registerOnload("functions.js",function(){$(".vpointer").live("hover",function(c){var a=$(this);var b=PMA_getRowNumber(a.attr("class"));$(".vpointer").filter(".row_"+b).toggleClass("hover")});$(".vmarker").live("click",function(f){if($(f.target).is("a, img, a *")){return}var c=$(this);var d=PMA_getRowNumber(c.attr("class"));var a=$(".vmarker").filter(".row_"+d+":first").find(":checkbox");if(a.length){var b=a.prop("checked");if(!$(f.target).is(":checkbox, label")){b=!b;a.prop("checked",b)}if(b){$(".vmarker").filter(".row_"+d).addClass("marked")}else{$(".vmarker").filter(".row_"+d).removeClass("marked")}}else{$(".vmarker").filter(".row_"+d).toggleClass("marked")}});$("select.pageselector").live("change",function(a){a.stopPropagation();if($(this).closest("#pma_navigation").length==0){$(this).closest("form").submit()}else{PMA_navigationTreePagination($(this))}});if($("li.jsversioncheck").length>0){$.getJSON("version_check.php",{},PMA_current_version)}if($("#is_git_revision").length>0){setTimeout(PMA_display_git_revision,10)}PMA_init_slider();$("a.formLinkSubmit").live("click",function(b){if($(this).attr("href").indexOf("=")!=-1){var a=$(this).attr("href").substr($(this).attr("href").indexOf("#")+1).split("=",2);$(this).parents("form").append('<input type="hidden" name="'+a[0]+'" value="'+a[1]+'"/>')}$(this).parents("form").submit();return false});if($("#update_recent_tables").length){$.get($("#update_recent_tables").attr("href"),function(a){if(a.success==true){$("#recentTable").html(a.options)}})}});function PMA_init_slider(){$("div.pma_auto_slider").each(function(){var b=$(this);if(b.data("slider_init_done")){return}var a=$("<div>",{"class":"slide-wrapper"});a.toggle(b.is(":visible"));$("<a>",{href:"#"+this.id,"class":"ajax"}).text(this.title).prepend($("<span>")).insertBefore(b).click(function(){var c=b.closest(".slide-wrapper");var d=b.is(":visible");if(!d){c.show()}b[d?"hide":"show"]("blind",function(){c.toggle(!d);PMA_set_status_label(b)});return false});b.wrap(a);PMA_set_status_label(b);b.data("slider_init_done",1)})}AJAX.registerOnload("functions.js",function(){PMA_init_slider()});AJAX.registerTeardown("functions.js",function(){$("div.pma_auto_slider").each(function(){var a=$(this);a.removeData();a.parent().replaceWith(a);a.parent().children("a").remove()})});function PMA_slidingMessage(b,c){if(b==undefined||b.length==0){return false}if(c==undefined||!c instanceof jQuery||c.length==0){if($("#PMA_slidingMessage").length==0){$("#page_content").prepend('<span id="PMA_slidingMessage" style="display: inline-block;"></span>')}c=$("#PMA_slidingMessage")}if(c.has("div").length>0){c.find("div").first().fadeOut(function(){c.children().remove();c.append('<div style="display: none;">'+b+"</div>").animate({height:c.find("div").first().height()}).find("div").first().fadeIn()})}else{var a=c.width("100%").html('<div style="display: none;">'+b+"</div>").find("div").first().height();c.find("div").first().css("height",0).show().animate({height:a},function(){c.height(c.find("div").first().height())})}return true}AJAX.registerTeardown("functions.js",function(){$("#drop_tbl_anchor.ajax").die("click");$("#truncate_tbl_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#drop_tbl_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strDropTableStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"DROP TABLE "+PMA_commonParams.get("table"));$(this).PMA_confirm(a,$(this).attr("href"),function(c){var d=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(e){if(e.success==true){PMA_ajaxRemoveMessage(d);PMA_reloadNavigation();PMA_commonParams.set("table","");PMA_commonActions.refreshMain(PMA_commonParams.get("opendb_url"),function(){PMA_ajaxShowMessage(e.message)})}else{PMA_ajaxShowMessage(e.error,false)}})})});$("#truncate_tbl_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strTruncateTableStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"TRUNCATE "+PMA_commonParams.get("table"));$(this).PMA_confirm(a,$(this).attr("href"),function(c){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(d){if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if($("#result_query").length!=0){$("#result_query").remove()}if(d.success==true){PMA_ajaxShowMessage(d.message);$("<div id='sqlqueryresults'></div>").prependTo("#page_content");$("#sqlqueryresults").html(d.sql_query)}else{PMA_ajaxShowMessage(d.error,false)}})})})});AJAX.registerOnload("functions.js",function(){var a=$("#sqlquery");if(a.length>0){if(typeof CodeMirror!="undefined"){codemirror_editor=CodeMirror.fromTextArea(a[0],{lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql",lineWrapping:true});codemirror_editor.focus();$(codemirror_editor.getWrapperElement()).bind("keydown",catchKeypressesFromSqlTextboxes)}else{a.focus().bind("keydown",catchKeypressesFromSqlTextboxes)}}});AJAX.registerTeardown("functions.js",function(){if(codemirror_editor){$("#sqlquery").text(codemirror_editor.getValue());codemirror_editor.toTextArea();codemirror_editor=false}});(function(a){a.fn.noSelect=function(c){var b=(c==null)?true:c;if(b){return this.each(function(){if(a.browser.msie||a.browser.safari){a(this).bind("selectstart",function(){return false})}else{if(a.browser.mozilla){a(this).css("MozUserSelect","none");a("body").trigger("focus")}else{if(a.browser.opera){a(this).bind("mousedown",function(){return false})}else{a(this).attr("unselectable","on")}}}})}else{return this.each(function(){if(a.browser.msie||a.browser.safari){a(this).unbind("selectstart")}else{if(a.browser.mozilla){a(this).css("MozUserSelect","inherit")}else{if(a.browser.opera){a(this).unbind("mousedown")}else{a(this).removeAttr("unselectable")}}}})}}})(jQuery);(function(a){a.fn.filterByValue=function(b){return this.filter(function(){return a(this).val()===b})}})(jQuery);function PMA_tooltip(d,e,c,b){if($("#no_hint").length>0){return}var a={content:c,items:e,tooltipClass:"tooltip",track:true,show:false,hide:false};d.tooltip($.extend(true,a,b))}function PMA_getCellValue(b){var a=$(b);if(a.is(".null")){return""}else{if(!a.is(".to_be_saved")&&a.data("original_data")){return a.data("original_data")}else{return a.text()}}}AJAX.registerTeardown("functions.js",function(){$("a.themeselect").die("click");$(".autosubmit").die("change");$("a.take_theme").unbind("click")});AJAX.registerOnload("functions.js",function(){$("a.themeselect").live("click",function(a){window.open(a.target,"themes","left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes");return false});$(".autosubmit").live("change",function(a){$(this).closest("form").submit()});$("a.take_theme").click(function(b){var a=this.name;if(window.opener&&window.opener.document.forms.setTheme.elements.set_theme){window.opener.document.forms.setTheme.elements.set_theme.value=a;window.opener.document.forms.setTheme.submit();window.close();return false}return true})});function PMA_clearSelection(){if(document.selection&&document.selection.empty){document.selection.empty()}else{if(window.getSelection){var a=window.getSelection();if(a.empty){a.empty()}if(a.removeAllRanges){a.removeAllRanges()}}}}function escapeHtml(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function printPage(){if(typeof(window.print)!="undefined"){window.print()}}AJAX.registerTeardown("functions.js",function(){$("input#print").unbind("click");$("span a.create_view.ajax").die("click");$("#createViewDialog").find("input, select").die("keydown")});AJAX.registerOnload("functions.js",function(){$("input#print").click(printPage);$("span a.create_view.ajax").live("click",function(a){a.preventDefault();PMA_createViewDialog($(this))});$("#createViewDialog").find("input, select").live("keydown",function(a){if(a.which===13){a.preventDefault();$(this).closest(".ui-dialog").find(".ui-button:first").click()}})});function PMA_createViewDialog(c){var a=PMA_ajaxShowMessage();var b=null;$.get(c.attr("href")+"&ajax_request=1",function(g){if(g.success==true){PMA_ajaxRemoveMessage(a);var h={};h[PMA_messages.strGo]=function(){if(typeof CodeMirror!=="undefined"){b.save()}a=PMA_ajaxShowMessage();$.get("view_create.php",$("#createViewDialog").find("form").serialize(),function(i){PMA_ajaxRemoveMessage(a);if(i.success===true){$("#createViewDialog").dialog("close");$("#result_query").html(i.message);PMA_reloadNavigation()}else{PMA_ajaxShowMessage(i.error,false)}})};h[PMA_messages.strClose]=function(){$(this).dialog("close")};var f=$("<div/>").attr("id","createViewDialog").append(g.message).dialog({width:500,minWidth:300,maxWidth:620,modal:true,buttons:h,title:$("legend",$(g.message)).html(),close:function(){$(this).remove()}});f.find("legend").remove();if(typeof CodeMirror!=="undefined"){var d=f.find("textarea");var e={lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql"};b=CodeMirror.fromTextArea(d[0],e)}$("input:visible[type=text]",f).first().focus()}else{PMA_ajaxShowMessage(g.error)}})}$(function(){if($("#floating_menubar").length&&$("#PMA_disable_floating_menubar").length==0){var a=$("html").attr("dir")=="ltr"?"left":"right";$("#floating_menubar").css("margin-"+a,$("#pma_navigation").width()+$("#pma_navigation_resizer").width()).css(a,0).css({position:"fixed",top:0,width:"100%","z-index":500}).append($("#serverinfo")).append($("#topmenucontainer"));setTimeout(function(){$("body").css("padding-top",$("#floating_menubar").outerHeight(true));$("#topmenu").menuResizer("resize")},4)}});$(function(){$(document).delegate("#serverinfo, #goto_pagetop","click",function(a){a.preventDefault();$("html, body").animate({scrollTop:0},"fast")})});var checkboxes_sel="input.checkall:checkbox:enabled";$(checkboxes_sel).live("change",function(){var a=$(this.form);var c=a.find(checkboxes_sel).length;var d=a.find(checkboxes_sel+":checked").length;var b=a.find("input#checkall");if(c==d){b.prop({checked:true,indeterminate:false})}else{if(d>0){b.prop({checked:true,indeterminate:true})}else{b.prop({checked:false,indeterminate:false})}}});$("input#checkall").live("change",function(){var a=$(this).is(":checked");$(this.form).find(checkboxes_sel).prop("checked",a).parents("tr").toggleClass("marked",a)});function toggleRowColors(b){for(var a=b;a.length>0;a=a.next()){if(a.hasClass("odd")){a.removeClass("odd").addClass("even")}else{if(a.hasClass("even")){a.removeClass("even").addClass("odd")}}}}function formatBytes(b,f,a){if(!f){var f=0}if(!a){var a="."}var c=["B","KiB","MiB","GiB"];for(var e=0;b>1024&&e<c.length;e++){b/=1024}var d=Math.pow(10,f);b=Math.round(b*d)/d;b=b.toString().split(".").join(a);return b+" "+c[e]}AJAX.registerOnload("functions.js",function(){$("a._blank").prop("target","_blank");var a=$("#loginform");if(a.length){a.find(".js-show").show();if($("#input_username").val()){$("#input_password").focus()}else{$("#input_username").focus()}}});$("a.login-link").live("click",function(a){a.preventDefault();window.location.reload(true)});
b'\\ No newline at end of file'
1
/* vim: set expandtab sw=4 ts=4 sts=4: */
3
* general function, usually for data manipulation pages
8
* @var $table_clone reference to the action links on the tbl_structure page
10
var $table_clone = false;
13
* @var sql_box_locked lock for the sqlbox textarea in the querybox/querywindow
15
var sql_box_locked = false;
18
* @var array holds elements which content should only selected once
20
var only_once_elements = [];
23
* @var int ajax_message_count Number of AJAX messages shown since page load
25
var ajax_message_count = 0;
28
* @var codemirror_editor object containing CodeMirror editor of the query editor in SQL tab
30
var codemirror_editor = false;
33
* @var codemirror_editor object containing CodeMirror editor of the inline query editor
35
var codemirror_inline_editor = false;
38
* @var chart_activeTimeouts object active timeouts that refresh the charts. When disabling a realtime chart, this can be used to stop the continuous ajax requests
40
var chart_activeTimeouts = {};
43
* Make sure that ajax requests will not be cached
44
* by appending a random variable to their parameters
46
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
47
var nocache = new Date().getTime() + "" + Math.floor(Math.random() * 1000000);
48
if (typeof options.data == "string") {
49
options.data += "&_nocache=" + nocache;
50
} else if (typeof options.data == "object") {
51
options.data = $.extend(originalOptions.data, {'_nocache':nocache});
56
* Add a hidden field to the form to indicate that this will be an
57
* Ajax request (only if this hidden field does not exist)
59
* @param object the form
61
function PMA_prepareForAjaxRequest($form)
63
if (! $form.find('input:hidden').is('#ajax_request_hidden')) {
64
$form.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />');
69
* Generate a new password and copy it to the password input areas
71
* @param object the form that holds the password fields
73
* @return boolean always true
75
function suggestPassword(passwd_form)
77
// restrict the password to just letters and numbers to avoid problems:
78
// "editors and viewers regard the password as multiple words and
79
// things like double click no longer work"
80
var pwchars = "abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";
81
var passwordlength = 16; // do we want that to be dynamic? no, keep it simple :)
82
var passwd = passwd_form.generated_pw;
85
for (var i = 0; i < passwordlength; i++ ) {
86
passwd.value += pwchars.charAt( Math.floor( Math.random() * pwchars.length ) );
88
passwd_form.text_pma_pw.value = passwd.value;
89
passwd_form.text_pma_pw2.value = passwd.value;
94
* Version string to integer conversion.
96
function parseVersionString (str)
98
if (typeof(str) != 'string') { return false; }
100
// Parse possible alpha/beta/rc/
101
var state = str.split('-');
102
if (state.length >= 2) {
103
if (state[1].substr(0, 2) == 'rc') {
104
add = - 20 - parseInt(state[1].substr(2));
105
} else if (state[1].substr(0, 4) == 'beta') {
106
add = - 40 - parseInt(state[1].substr(4));
107
} else if (state[1].substr(0, 5) == 'alpha') {
108
add = - 60 - parseInt(state[1].substr(5));
109
} else if (state[1].substr(0, 3) == 'dev') {
110
/* We don't handle dev, it's git snapshot */
115
var x = str.split('.');
116
// Use 0 for non existing parts
117
var maj = parseInt(x[0]) || 0;
118
var min = parseInt(x[1]) || 0;
119
var pat = parseInt(x[2]) || 0;
120
var hotfix = parseInt(x[3]) || 0;
121
return maj * 100000000 + min * 1000000 + pat * 10000 + hotfix * 100 + add;
125
* Indicates current available version on main page.
127
function PMA_current_version(data)
129
if (data && data.version && data.date) {
130
var current = parseVersionString(pmaversion);
131
var latest = parseVersionString(data['version']);
132
var version_information_message = PMA_messages['strLatestAvailable'] + ' ' + escapeHtml(data['version']);
133
if (latest > current) {
134
var message = $.sprintf(
135
PMA_messages['strNewerVersion'],
136
escapeHtml(data['version']),
137
escapeHtml(data['date'])
139
if (Math.floor(latest / 10000) === Math.floor(current / 10000)) {
140
/* Security update */
143
var klass = 'notice';
145
$('#maincontainer').after('<div class="' + klass + '">' + message + '</div>');
147
if (latest === current) {
148
version_information_message = ' (' + PMA_messages['strUpToDate'] + ')';
150
$('#li_pma_version').append(version_information_message);
155
* Loads Git revision data from ajax for index.php
157
function PMA_display_git_revision()
159
$('#is_git_revision').remove();
163
"server": PMA_commonParams.get('server'),
164
"token": PMA_commonParams.get('token'),
165
"git_revision": true,
169
if (data.success == true) {
170
$(data.message).insertAfter('#li_pma_version');
177
* for libraries/display_change_password.lib.php
178
* libraries/user_password.php
182
function displayPasswordGenerateButton()
184
$('#tr_element_before_generate_password').parent().append('<tr class="vmiddle"><td>' + PMA_messages['strGeneratePassword'] + '</td><td><input type="button" class="button" id="button_generate_password" value="' + PMA_messages['strGenerate'] + '" onclick="suggestPassword(this.form)" /><input type="text" name="generated_pw" id="generated_pw" /></td></tr>');
185
$('#div_element_before_generate_password').parent().append('<div class="item"><label for="button_generate_password">' + PMA_messages['strGeneratePassword'] + ':</label><span class="options"><input type="button" class="button" id="button_generate_password" value="' + PMA_messages['strGenerate'] + '" onclick="suggestPassword(this.form)" /></span><input type="text" name="generated_pw" id="generated_pw" /></div>');
189
* Adds a date/time picker to an element
191
* @param object $this_element a jQuery object pointing to the element
193
function PMA_addDatepicker($this_element, options)
195
var showTimeOption = false;
196
if ($this_element.is('.datetimefield')) {
197
showTimeOption = true;
200
var defaultOptions = {
202
buttonImage: themeCalendarImage, // defined in js/messages.php
203
buttonImageOnly: true,
207
showTimepicker: showTimeOption,
208
showButtonPanel: false,
209
dateFormat: 'yy-mm-dd', // yy means year with four digits
210
timeFormat: 'HH:mm:ss',
211
altFieldTimeOnly: false,
213
beforeShow: function(input, inst) {
214
// Remember that we came from the datepicker; this is used
215
// in tbl_change.js by verificationsAfterFieldChange()
216
$this_element.data('comes_from', 'datepicker');
218
// Fix wrong timepicker z-index, doesn't work without timeout
219
setTimeout(function() {
220
$('#ui-timepicker-div').css('z-index',$('#ui-datepicker-div').css('z-index'));
223
onClose: function(dateText, dp_inst) {
224
// The value is no more from the date picker
225
$this_element.data('comes_from', '');
228
if ( showTimeOption || (typeof(options) != 'undefined' && options.showTimepicker) ) {
229
$this_element.datetimepicker($.extend(defaultOptions, options));
231
$this_element.datepicker($.extend(defaultOptions, options));
236
* selects the content of a given object, f.e. a textarea
238
* @param object element element of which the content will be selected
239
* @param var lock variable which holds the lock for this element
240
* or true, if no lock exists
241
* @param boolean only_once if true this is only done once
242
* f.e. only on first focus
244
function selectContent( element, lock, only_once )
246
if ( only_once && only_once_elements[element.name] ) {
250
only_once_elements[element.name] = true;
260
* Displays a confirmation box before submitting a "DROP/DELETE/ALTER" query.
261
* This function is called while clicking links
263
* @param object the link
264
* @param object the sql query to submit
266
* @return boolean whether to run the query or not
268
function confirmLink(theLink, theSqlQuery)
270
// Confirmation is not required in the configuration file
271
// or browser is Opera (crappy js implementation)
272
if (PMA_messages['strDoYouReally'] == '' || typeof(window.opera) != 'undefined') {
276
var is_confirmed = confirm($.sprintf(PMA_messages['strDoYouReally'], theSqlQuery));
278
if ( $(theLink).hasClass('formLinkSubmit') ) {
279
var name = 'is_js_confirmed';
280
if ($(theLink).attr('href').indexOf('usesubform') != -1) {
281
name = 'subform[' + $(theLink).attr('href').substr('#').match(/usesubform\[(\d+)\]/i)[1] + '][is_js_confirmed]';
284
$(theLink).parents('form').append('<input type="hidden" name="' + name + '" value="1" />');
285
} else if ( typeof(theLink.href) != 'undefined' ) {
286
theLink.href += '&is_js_confirmed=1';
287
} else if ( typeof(theLink.form) != 'undefined' ) {
288
theLink.form.action += '?is_js_confirmed=1';
293
} // end of the 'confirmLink()' function
296
* Displays an error message if a "DROP DATABASE" statement is submitted
297
* while it isn't allowed, else confirms a "DROP/DELETE/ALTER" query before
298
* sumitting it if required.
299
* This function is called by the 'checkSqlQuery()' js function.
301
* @param object the form
302
* @param object the sql query textarea
304
* @return boolean whether to run the query or not
306
* @see checkSqlQuery()
308
function confirmQuery(theForm1, sqlQuery1)
310
// Confirmation is not required in the configuration file
311
if (PMA_messages['strDoYouReally'] == '') {
315
// "DROP DATABASE" statement isn't allowed
316
if (PMA_messages['strNoDropDatabases'] != '') {
317
var drop_re = new RegExp('(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i');
318
if (drop_re.test(sqlQuery1.value)) {
319
alert(PMA_messages['strNoDropDatabases']);
326
// Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement
328
// TODO: find a way (if possible) to use the parser-analyser
329
// for this kind of verification
330
// For now, I just added a ^ to check for the statement at
331
// beginning of expression
333
var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s', 'i');
334
var do_confirm_re_1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
335
var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
336
var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
338
if (do_confirm_re_0.test(sqlQuery1.value)
339
|| do_confirm_re_1.test(sqlQuery1.value)
340
|| do_confirm_re_2.test(sqlQuery1.value)
341
|| do_confirm_re_3.test(sqlQuery1.value)) {
342
var message = (sqlQuery1.value.length > 100)
343
? sqlQuery1.value.substr(0, 100) + '\n ...'
345
var is_confirmed = confirm($.sprintf(PMA_messages['strDoYouReally'], message));
346
// statement is confirmed -> update the
347
// "is_js_confirmed" form field so the confirm test won't be
348
// run on the server side and allows to submit the form
350
theForm1.elements['is_js_confirmed'].value = 1;
353
// statement is rejected -> do not submit the form
358
} // end if (handle confirm box result)
359
} // end if (display confirm box)
362
} // end of the 'confirmQuery()' function
365
* Displays an error message if the user submitted the sql query form with no
366
* sql query, else checks for "DROP/DELETE/ALTER" statements
368
* @param object the form
370
* @return boolean always false
372
* @see confirmQuery()
374
function checkSqlQuery(theForm)
377
// First check if codemirror is active.
378
if (codemirror_editor) {
379
theForm.elements['sql_query'].value = codemirror_editor.getValue();
382
var sqlQuery = theForm.elements['sql_query'];
386
var space_re = new RegExp('\\s+');
387
if (typeof(theForm.elements['sql_file']) != 'undefined' &&
388
theForm.elements['sql_file'].value.replace(space_re, '') != '') {
391
if (typeof(theForm.elements['sql_localfile']) != 'undefined' &&
392
theForm.elements['sql_localfile'].value.replace(space_re, '') != '') {
395
if (isEmpty && typeof(theForm.elements['id_bookmark']) != 'undefined' &&
396
(theForm.elements['id_bookmark'].value != null || theForm.elements['id_bookmark'].value != '') &&
397
theForm.elements['id_bookmark'].selectedIndex != 0
401
// Checks for "DROP/DELETE/ALTER" statements
402
if (sqlQuery.value.replace(space_re, '') != '') {
403
if (confirmQuery(theForm, sqlQuery)) {
414
alert(PMA_messages['strFormEmpty']);
420
} // end of the 'checkSqlQuery()' function
423
* Check if a form's element is empty.
424
* An element containing only spaces is also considered empty
426
* @param object the form
427
* @param string the name of the form field to put the focus on
429
* @return boolean whether the form field is empty or not
431
function emptyCheckTheField(theForm, theFieldName)
433
var theField = theForm.elements[theFieldName];
434
var space_re = new RegExp('\\s+');
435
return (theField.value.replace(space_re, '') == '') ? 1 : 0;
436
} // end of the 'emptyCheckTheField()' function
440
* Check whether a form field is empty or not
442
* @param object the form
443
* @param string the name of the form field to put the focus on
445
* @return boolean whether the form field is empty or not
447
function emptyFormElements(theForm, theFieldName)
449
var theField = theForm.elements[theFieldName];
450
var isEmpty = emptyCheckTheField(theForm, theFieldName);
454
} // end of the 'emptyFormElements()' function
458
* Ensures a value submitted in a form is numeric and is in a range
460
* @param object the form
461
* @param string the name of the form field to check
462
* @param integer the minimum authorized value
463
* @param integer the maximum authorized value
465
* @return boolean whether a valid number has been submitted or not
467
function checkFormElementInRange(theForm, theFieldName, message, min, max)
469
var theField = theForm.elements[theFieldName];
470
var val = parseInt(theField.value);
472
if (typeof(min) == 'undefined') {
475
if (typeof(max) == 'undefined') {
476
max = Number.MAX_VALUE;
482
alert(PMA_messages['strNotNumber']);
486
// It's a number but it is not between min and max
487
else if (val < min || val > max) {
489
alert($.sprintf(message, val));
493
// It's a valid number
495
theField.value = val;
499
} // end of the 'checkFormElementInRange()' function
502
function checkTableEditForm(theForm, fieldsCnt)
504
// TODO: avoid sending a message if user just wants to add a line
505
// on the form but has not completed at least one field name
507
var atLeastOneField = 0;
508
var i, elm, elm2, elm3, val, id;
510
for (i=0; i<fieldsCnt; i++)
512
id = "#field_" + i + "_2";
515
if (val == 'VARCHAR' || val == 'CHAR' || val == 'BIT' || val == 'VARBINARY' || val == 'BINARY') {
516
elm2 = $("#field_" + i + "_3");
517
val = parseInt(elm2.val());
518
elm3 = $("#field_" + i + "_1");
519
if (isNaN(val) && elm3.val() != "") {
521
alert(PMA_messages['strNotNumber']);
527
if (atLeastOneField == 0) {
528
id = "field_" + i + "_1";
529
if (!emptyCheckTheField(theForm, id)) {
534
if (atLeastOneField == 0) {
535
var theField = theForm.elements["field_0_1"];
536
alert(PMA_messages['strFormEmpty']);
541
// at least this section is under jQuery
542
if ($("input.textfield[name='table']").val() == "") {
543
alert(PMA_messages['strFormEmpty']);
544
$("input.textfield[name='table']").focus();
550
} // enf of the 'checkTableEditForm()' function
553
* Unbind all event handlers before tearing down a page
555
AJAX.registerTeardown('functions.js', function() {
556
$('input:checkbox.checkall').die('click');
558
AJAX.registerOnload('functions.js', function() {
560
* Row marking in horizontal mode (use "live" so that it works also for
561
* next pages reached via AJAX); a tr may have the class noclick to remove
565
$('input:checkbox.checkall').live('click', function(e) {
566
var $tr = $(this).closest('tr');
568
// make the table unselectable (to prevent default highlighting when shift+click)
569
//$tr.parents('table').noSelect();
571
if (!e.shiftKey || last_clicked_row == -1) {
574
// XXX: FF fires two click events for <label> (label and checkbox), so we need to handle this differently
575
var $checkbox = $tr.find(':checkbox');
576
if ($checkbox.length) {
577
// checkbox in a row, add or remove class depending on checkbox state
578
var checked = $checkbox.prop('checked');
579
if (!$(e.target).is(':checkbox, label')) {
581
$checkbox.prop('checked', checked).trigger('change');
584
$tr.addClass('marked');
586
$tr.removeClass('marked');
588
last_click_checked = checked;
590
// normal data table, just toggle class
591
$tr.toggleClass('marked');
592
last_click_checked = false;
595
// remember the last clicked row
596
last_clicked_row = last_click_checked ? $('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr) : -1;
597
last_shift_clicked_row = -1;
599
// handle the shift click
600
PMA_clearSelection();
603
// clear last shift click result
604
if (last_shift_clicked_row >= 0) {
605
if (last_shift_clicked_row >= last_clicked_row) {
606
start = last_clicked_row;
607
end = last_shift_clicked_row;
609
start = last_shift_clicked_row;
610
end = last_clicked_row;
612
$tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
613
.slice(start, end + 1)
614
.removeClass('marked')
616
.prop('checked', false)
620
// handle new shift click
621
var curr_row = $('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr);
622
if (curr_row >= last_clicked_row) {
623
start = last_clicked_row;
627
end = last_clicked_row;
629
$tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
630
.slice(start, end + 1)
633
.prop('checked', true)
636
// remember the last shift clicked row
637
last_shift_clicked_row = curr_row;
644
* Add attribute to text boxes for iOS devices (based on bugID: 3508912)
646
if (navigator.userAgent.match(/(iphone|ipod|ipad)/i)) {
647
$('input[type=text]').attr('autocapitalize','off').attr('autocorrect','off');
652
* True if last click is to check a row.
654
var last_click_checked = false;
657
* Zero-based index of last clicked row.
658
* Used to handle the shift + click event in the code above.
660
var last_clicked_row = -1;
663
* Zero-based index of last shift clicked row.
665
var last_shift_clicked_row = -1;
668
* Row highlighting in horizontal mode (use "live"
669
* so that it works also for pages reached via AJAX)
671
/*AJAX.registerOnload('functions.js', function() {
672
$('tr.odd, tr.even').live('hover',function(event) {
674
$tr.toggleClass('hover',event.type=='mouseover');
675
$tr.children().toggleClass('hover',event.type=='mouseover');
680
* This array is used to remember mark status of rows in browse mode
685
* marks all rows and selects its first checkbox inside the given element
686
* the given element is usaly a table or a div containing the table or tables
688
* @param container DOM element
690
function markAllRows(container_id)
693
$("#" + container_id).find("input:checkbox:enabled").prop('checked', true)
695
.parents("tr").addClass("marked");
700
* marks all rows and selects its first checkbox inside the given element
701
* the given element is usaly a table or a div containing the table or tables
703
* @param container DOM element
705
function unMarkAllRows(container_id)
708
$("#" + container_id).find("input:checkbox:enabled").prop('checked', false)
710
.parents("tr").removeClass("marked");
715
* Checks/unchecks all checkbox in given conainer (f.e. a form, fieldset or div)
717
* @param string container_id the container id
718
* @param boolean state new value for checkbox (true or false)
719
* @return boolean always true
721
function setCheckboxes(container_id, state)
724
$("#" + container_id).find("input:checkbox").prop('checked', state);
726
} // end of the 'setCheckboxes()' function
729
* Checks/unchecks all options of a <select> element
731
* @param string the form name
732
* @param string the element name
733
* @param boolean whether to check or to uncheck options
735
* @return boolean always true
737
function setSelectOptions(the_form, the_select, do_check)
739
$("form[name='"+ the_form +"'] select[name='"+the_select+"']").find("option").prop('selected', do_check);
741
} // end of the 'setSelectOptions()' function
744
* Sets current value for query box.
746
function setQuery(query)
748
if (codemirror_editor) {
749
codemirror_editor.setValue(query);
750
codemirror_editor.focus();
752
document.sqlform.sql_query.value = query;
753
document.sqlform.sql_query.focus();
759
* Create quick sql statements.
762
function insertQuery(queryType)
764
if (queryType == "clear") {
770
var myListBox = document.sqlform.dummy;
771
var table = document.sqlform.table.value;
773
if (myListBox.options.length > 0) {
774
sql_box_locked = true;
779
for (var i=0; i < myListBox.options.length; i++) {
786
chaineAj += myListBox.options[i].value;
787
valDis += "[value-" + NbSelect + "]";
788
editDis += myListBox.options[i].value + "=[value-" + NbSelect + "]";
790
if (queryType == "selectall") {
791
query = "SELECT * FROM `" + table + "` WHERE 1";
792
} else if (queryType == "select") {
793
query = "SELECT " + chaineAj + " FROM `" + table + "` WHERE 1";
794
} else if (queryType == "insert") {
795
query = "INSERT INTO `" + table + "`(" + chaineAj + ") VALUES (" + valDis + ")";
796
} else if (queryType == "update") {
797
query = "UPDATE `" + table + "` SET " + editDis + " WHERE 1";
798
} else if (queryType == "delete") {
799
query = "DELETE FROM `" + table + "` WHERE 1";
802
sql_box_locked = false;
808
* Inserts multiple fields.
811
function insertValueQuery()
813
var myQuery = document.sqlform.sql_query;
814
var myListBox = document.sqlform.dummy;
816
if (myListBox.options.length > 0) {
817
sql_box_locked = true;
820
for (var i=0; i<myListBox.options.length; i++) {
821
if (myListBox.options[i].selected) {
826
chaineAj += myListBox.options[i].value;
830
/* CodeMirror support */
831
if (codemirror_editor) {
832
codemirror_editor.replaceSelection(chaineAj);
834
} else if (document.selection) {
836
var sel = document.selection.createRange();
838
document.sqlform.insert.focus();
840
//MOZILLA/NETSCAPE support
841
else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart == "0") {
842
var startPos = document.sqlform.sql_query.selectionStart;
843
var endPos = document.sqlform.sql_query.selectionEnd;
844
var chaineSql = document.sqlform.sql_query.value;
846
myQuery.value = chaineSql.substring(0, startPos) + chaineAj + chaineSql.substring(endPos, chaineSql.length);
848
myQuery.value += chaineAj;
850
sql_box_locked = false;
855
* Add a date/time picker to each element that needs it
856
* (only when jquery-ui-timepicker-addon.js is loaded)
858
function addDateTimePicker() {
859
if ($.timepicker != undefined) {
860
$('input.datefield, input.datetimefield').each(function() {
861
PMA_addDatepicker($(this));
867
* Refresh/resize the WYSIWYG scratchboard
869
function refreshLayout()
871
var $elm = $('#pdflayout');
872
var orientation = $('#orientation_opt').val();
873
if ($('#paper_opt').length==1) {
874
var paper = $('#paper_opt').val();
878
if (orientation == 'P') {
885
$elm.css('width', pdfPaperSize(paper, posa) + 'px');
886
$elm.css('height', pdfPaperSize(paper, posb) + 'px');
890
* Initializes positions of elements.
892
function TableDragInit() {
893
$('.pdflayout_table').each(function () {
895
var number = $this.data('number');
896
var x = $('#c_table_' + number + '_x').val();
897
var y = $('#c_table_' + number + '_y').val();
898
$this.css('left', x + 'px');
899
$this.css('top', y + 'px');
900
/* Make elements draggable */
902
containment: "parent",
903
drag: function (evt, ui) {
904
var number = $this.data('number');
905
$('#c_table_' + number + '_x').val(parseInt(ui.position.left));
906
$('#c_table_' + number + '_y').val(parseInt(ui.position.top));
913
* Resets drag and drop positions.
915
function resetDrag() {
916
$('.pdflayout_table').each(function () {
918
var x = $this.data('x');
919
var y = $this.data('y');
920
$this.css('left', x + 'px');
921
$this.css('top', y + 'px');
926
* User schema handlers.
929
/* Move in scratchboard on manual change */
930
$('.position-change').live('change', function () {
932
var $elm = $('#table_' + $this.data('number'));
933
$elm.css($this.data('axis'), $this.val() + 'px');
935
/* Refresh on paper size/orientation change */
936
$('.paper-change').live('change', function () {
937
var $elm = $('#pdflayout');
938
if ($elm.css('visibility') == 'visible') {
943
/* Show/hide the WYSIWYG scratchboard */
944
$('#toggle-dragdrop').live('click', function () {
945
var $elm = $('#pdflayout');
946
if ($elm.css('visibility') == 'hidden') {
949
$elm.css('visibility', 'visible');
950
$elm.css('display', 'block');
951
$('#showwysiwyg').val('1');
953
$elm.css('visibility', 'hidden');
954
$elm.css('display', 'none');
955
$('#showwysiwyg').val('0');
958
/* Reset scratchboard */
959
$('#reset-dragdrop').live('click', function () {
965
* Returns paper sizes for a given format
967
function pdfPaperSize(format, axis)
969
switch (format.toUpperCase()) {
1319
* Unbind all event handlers before tearing down a page
1321
AJAX.registerTeardown('functions.js', function() {
1322
$("a.inline_edit_sql").die('click');
1323
$("input#sql_query_edit_save").die('click');
1324
$("input#sql_query_edit_discard").die('click');
1325
$('input.sqlbutton').unbind('click');
1326
$("#export_type").unbind('change');
1327
$('#sqlquery').unbind('keydown');
1328
$('#sql_query_edit').unbind('keydown');
1330
if (codemirror_inline_editor) {
1331
// Copy the sql query to the text area to preserve it.
1332
$('#sql_query_edit').text(codemirror_inline_editor.getValue());
1333
$(codemirror_inline_editor.getWrapperElement()).unbind('keydown');
1334
codemirror_inline_editor.toTextArea();
1335
codemirror_inline_editor = false;
1337
if (codemirror_editor) {
1338
$(codemirror_editor.getWrapperElement()).unbind('keydown');
1343
* Jquery Coding for inline editing SQL_QUERY
1345
AJAX.registerOnload('functions.js', function() {
1346
// If we are coming back to the page by clicking forward button
1347
// of the browser, bind the code mirror to inline query editor.
1348
bindCodeMirrorToInlineEditor();
1349
$("a.inline_edit_sql").live('click', function() {
1350
if ($('#sql_query_edit').length) {
1351
// An inline query editor is already open,
1352
// we don't want another copy of it
1356
var $form = $(this).prev('form');
1357
var sql_query = $form.find("input[name='sql_query']").val();
1358
var $inner_sql = $(this).parent().prev().find('.inner_sql');
1359
var old_text = $inner_sql.html();
1361
var new_content = "<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">" + sql_query + "</textarea>\n";
1362
new_content += "<input type=\"submit\" id=\"sql_query_edit_save\" class=\"button btnSave\" value=\"" + PMA_messages['strGo'] + "\"/>\n";
1363
new_content += "<input type=\"button\" id=\"sql_query_edit_discard\" class=\"button btnDiscard\" value=\"" + PMA_messages['strCancel'] + "\"/>\n";
1364
var $editor_area = $('div#inline_editor');
1365
if ($editor_area.length == 0) {
1366
$editor_area = $('<div id="inline_editor_outer"></div>');
1367
$editor_area.insertBefore($inner_sql);
1369
$editor_area.html(new_content);
1372
bindCodeMirrorToInlineEditor();
1376
$("input#sql_query_edit_save").live('click', function() {
1377
if (codemirror_inline_editor) {
1378
var sql_query = codemirror_inline_editor.getValue();
1380
var sql_query = $(this).prev().val();
1383
var $form = $("a.inline_edit_sql").prev('form');
1384
var $fake_form = $('<form>', {action: 'import.php', method: 'post'})
1385
.append($form.find("input[name=server], input[name=db], input[name=table], input[name=token]").clone())
1386
.append($('<input/>', {type: 'hidden', name: 'show_query', value: 1}))
1387
.append($('<input/>', {type: 'hidden', name: 'sql_query', value: sql_query}));
1388
$fake_form.appendTo($('body')).submit();
1391
$("input#sql_query_edit_discard").live('click', function() {
1392
$('div#inline_editor_outer')
1394
.siblings('.inner_sql').show();
1397
$('input.sqlbutton').click(function(evt) {
1398
insertQuery(evt.target.id);
1402
$("#export_type").change(function() {
1403
if ($("#export_type").val()=='svg') {
1404
$("#show_grid_opt").prop("disabled",true);
1405
$("#orientation_opt").prop("disabled",true);
1406
$("#with_doc").prop("disabled",true);
1407
$("#show_table_dim_opt").removeProp("disabled");
1408
$("#all_tables_same_width").removeProp("disabled");
1409
$("#paper_opt").removeProp("disabled");
1410
$("#show_color_opt").removeProp("disabled");
1411
//$(this).css("background-color","yellow");
1412
} else if ($("#export_type").val()=='dia') {
1413
$("#show_grid_opt").prop("disabled",true);
1414
$("#with_doc").prop("disabled",true);
1415
$("#show_table_dim_opt").prop("disabled",true);
1416
$("#all_tables_same_width").prop("disabled",true);
1417
$("#paper_opt").removeProp("disabled");
1418
$("#show_color_opt").removeProp("disabled");
1419
$("#orientation_opt").removeProp("disabled");
1420
} else if ($("#export_type").val()=='eps') {
1421
$("#show_grid_opt").prop("disabled",true);
1422
$("#orientation_opt").removeProp("disabled");
1423
$("#with_doc").prop("disabled",true);
1424
$("#show_table_dim_opt").prop("disabled",true);
1425
$("#all_tables_same_width").prop("disabled",true);
1426
$("#paper_opt").prop("disabled",true);
1427
$("#show_color_opt").prop("disabled",true);
1428
} else if ($("#export_type").val()=='pdf') {
1429
$("#show_grid_opt").removeProp("disabled");
1430
$("#orientation_opt").removeProp("disabled");
1431
$("#with_doc").removeProp("disabled");
1432
$("#show_table_dim_opt").removeProp("disabled");
1433
$("#all_tables_same_width").removeProp("disabled");
1434
$("#paper_opt").removeProp("disabled");
1435
$("#show_color_opt").removeProp("disabled");
1441
if ($('#input_username')) {
1442
if ($('#input_username').val() == '') {
1443
$('#input_username').focus();
1445
$('#input_password').focus();
1451
* Binds the CodeMirror to the text area used to inline edit a query.
1453
function bindCodeMirrorToInlineEditor() {
1454
var $inline_editor = $('#sql_query_edit');
1455
if ($inline_editor.length > 0) {
1456
if (typeof CodeMirror !== 'undefined') {
1457
var height = $('#sql_query_edit').css('height');
1458
codemirror_inline_editor = CodeMirror.fromTextArea($inline_editor[0], {
1460
matchBrackets: true,
1462
mode: "text/x-mysql",
1465
codemirror_inline_editor.getScrollerElement().style.height = height;
1466
codemirror_inline_editor.refresh();
1467
codemirror_inline_editor.focus();
1468
$(codemirror_inline_editor.getWrapperElement()).bind(
1470
catchKeypressesFromSqlTextboxes
1473
$inline_editor.focus().bind(
1475
catchKeypressesFromSqlTextboxes
1481
function catchKeypressesFromSqlTextboxes(event) {
1482
// ctrl-enter is 10 in chrome and ie, but 13 in ff
1483
if (event.ctrlKey && (event.keyCode == 13 || event.keyCode == 10)) {
1484
if ($('#sql_query_edit').length > 0) {
1485
$("#sql_query_edit_save").trigger('click');
1486
} else if ($('#sqlquery').length > 0) {
1487
$("#button_submit_query").trigger('click');
1493
* Show a message on the top of the page for an Ajax request
1497
* 1) var $msg = PMA_ajaxShowMessage();
1498
* This will show a message that reads "Loading...". Such a message will not
1499
* disappear automatically and cannot be dismissed by the user. To remove this
1500
* message either the PMA_ajaxRemoveMessage($msg) function must be called or
1501
* another message must be show with PMA_ajaxShowMessage() function.
1503
* 2) var $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
1504
* This is a special case. The behaviour is same as above,
1505
* just with a different message
1507
* 3) var $msg = PMA_ajaxShowMessage('The operation was successful');
1508
* This will show a message that will disappear automatically and it can also
1509
* be dismissed by the user.
1511
* 4) var $msg = PMA_ajaxShowMessage('Some error', false);
1512
* This will show a message that will not disappear automatically, but it
1513
* can be dismissed by the user after he has finished reading it.
1515
* @param string message string containing the message to be shown.
1516
* optional, defaults to 'Loading...'
1517
* @param mixed timeout number of milliseconds for the message to be visible
1518
* optional, defaults to 5000. If set to 'false', the
1519
* notification will never disappear
1520
* @return jQuery object jQuery Element that holds the message div
1521
* this object can be passed to PMA_ajaxRemoveMessage()
1522
* to remove the notification
1524
function PMA_ajaxShowMessage(message, timeout)
1527
* @var self_closing Whether the notification will automatically disappear
1529
var self_closing = true;
1531
* @var dismissable Whether the user will be able to remove
1532
* the notification by clicking on it
1534
var dismissable = true;
1535
// Handle the case when a empty data.message is passed.
1536
// We don't want the empty message
1537
if (message == '') {
1539
} else if (! message) {
1540
// If the message is undefined, show the default
1541
message = PMA_messages['strLoading'];
1542
dismissable = false;
1543
self_closing = false;
1544
} else if (message == PMA_messages['strProcessingRequest']) {
1545
// This is another case where the message should not disappear
1546
dismissable = false;
1547
self_closing = false;
1549
// Figure out whether (or after how long) to remove the notification
1550
if (timeout == undefined) {
1552
} else if (timeout === false) {
1553
self_closing = false;
1555
// Create a parent element for the AJAX messages, if necessary
1556
if ($('#loading_parent').length == 0) {
1557
$('<div id="loading_parent"></div>')
1560
// Update message count to create distinct message elements every time
1561
ajax_message_count++;
1562
// Remove all old messages, if any
1563
$("span.ajax_notification[id^=ajax_message_num]").remove();
1565
* @var $retval a jQuery object containing the reference
1566
* to the created AJAX message
1569
'<span class="ajax_notification" id="ajax_message_num_'
1570
+ ajax_message_count +
1574
.appendTo("#loading_parent")
1577
// If the notification is self-closing we should create a callback to remove it
1581
.fadeOut('medium', function() {
1582
if ($(this).is('.dismissable')) {
1583
$(this).tooltip('destroy');
1585
// Remove the notification
1589
// If the notification is dismissable we need to add the relevant class to it
1590
// and add a tooltip so that the users know that it can be removed
1592
$retval.addClass('dismissable').css('cursor', 'pointer');
1594
* Add a tooltip to the notification to let the user know that (s)he
1595
* can dismiss the ajax notification by clicking on it.
1600
PMA_messages['strDismiss']
1608
* Removes the message shown for an Ajax operation when it's completed
1610
* @param jQuery object jQuery Element that holds the notification
1614
function PMA_ajaxRemoveMessage($this_msgbox)
1616
if ($this_msgbox != undefined && $this_msgbox instanceof jQuery) {
1620
if ($this_msgbox.is('.dismissable')) {
1621
if ($.isFunction($this_msgbox.tooltip)) {
1622
$this_msgbox.tooltip('destroy');
1625
$this_msgbox.remove();
1630
// This event only need to be fired once after the initial page load
1633
* Allows the user to dismiss a notification
1634
* created with PMA_ajaxShowMessage()
1636
$('span.ajax_notification.dismissable').live('click', function () {
1637
PMA_ajaxRemoveMessage($(this));
1640
* The below two functions hide the "Dismiss notification" tooltip when a user
1641
* is hovering a link or button that is inside an ajax message
1643
$('span.ajax_notification a, span.ajax_notification button, span.ajax_notification input')
1644
.live('mouseover', function () {
1645
$(this).parents('span.ajax_notification').tooltip('disable');
1647
.live('mouseout', function () {
1648
$(this).parents('span.ajax_notification').tooltip('enable');
1653
* Hides/shows the "Open in ENUM/SET editor" message, depending on the data type of the column currently selected
1655
function PMA_showNoticeForEnum(selectElement)
1657
var enum_notice_id = selectElement.attr("id").split("_")[1];
1658
enum_notice_id += "_" + (parseInt(selectElement.attr("id").split("_")[2]) + 1);
1659
var selectedType = selectElement.val();
1660
if (selectedType == "ENUM" || selectedType == "SET") {
1661
$("p#enum_notice_" + enum_notice_id).show();
1663
$("p#enum_notice_" + enum_notice_id).hide();
1668
* Creates a Profiling Chart with jqplot. Used in sql.js
1669
* and in server_status_monitor.js
1671
function PMA_createProfilingChartJqplot(target, data)
1673
return $.jqplot(target, [data],
1676
renderer: $.jqplot.PieRenderer,
1678
showDataLabels: true
1685
// from http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines#Color_Palette
1711
* Formats a profiling duration nicely (in us and ms time). Used in server_status.js
1713
* @param integer Number to be formatted, should be in the range of microsecond to second
1714
* @param integer Accuracy, how many numbers right to the comma should be
1715
* @return string The formatted number
1717
function PMA_prettyProfilingNum(num, acc)
1722
acc = Math.pow(10, acc);
1723
if (num * 1000 < 0.1) {
1724
num = Math.round(acc * (num * 1000 * 1000)) / acc + 'µ';
1725
} else if (num < 0.1) {
1726
num = Math.round(acc * (num * 1000)) / acc + 'm';
1728
num = Math.round(acc * num) / acc;
1736
* Formats a SQL Query nicely with newlines and indentation. Depends on Codemirror and MySQL Mode!
1738
* @param string Query to be formatted
1739
* @return string The formatted query
1741
function PMA_SQLPrettyPrint(string)
1743
if (typeof CodeMirror == 'undefined') {
1747
var mode = CodeMirror.getMode({},"text/x-mysql");
1748
var stream = new CodeMirror.StringStream(string);
1749
var state = mode.startState();
1750
var token, tokens = [];
1752
var tabs = function(cnt) {
1754
for (var i=0; i<4*cnt; i++) {
1760
// "root-level" statements
1762
'select': ['select', 'from','on','where','having','limit','order by','group by'],
1763
'update': ['update', 'set','where'],
1764
'insert into': ['insert into', 'values']
1766
// don't put spaces before these tokens
1767
var spaceExceptionsBefore = { ';':true, ',': true, '.': true, '(': true };
1768
// don't put spaces after these tokens
1769
var spaceExceptionsAfter = { '.': true };
1771
// Populate tokens array
1773
while (! stream.eol()) {
1774
stream.start = stream.pos;
1775
token = mode.token(stream, state);
1776
if (token != null) {
1777
tokens.push([token, stream.current().toLowerCase()]);
1781
var currentStatement = tokens[0][1];
1783
if (! statements[currentStatement]) {
1786
// Holds all currently opened code blocks (statement, function or generic)
1787
var blockStack = [];
1788
// Holds the type of block from last iteration (the current is in blockStack[0])
1790
// If a new code block is found, newBlock contains its type for one iteration and vice versa for endBlock
1791
var newBlock, endBlock;
1792
// How much to indent in the current line
1793
var indentLevel = 0;
1794
// Holds the "root-level" statements
1795
var statementPart, lastStatementPart = statements[currentStatement][0];
1797
blockStack.unshift('statement');
1799
// Iterate through every token and format accordingly
1800
for (var i = 0; i < tokens.length; i++) {
1801
previousBlock = blockStack[0];
1803
// New block => push to stack
1804
if (tokens[i][1] == '(') {
1805
if (i < tokens.length - 1 && tokens[i+1][0] == 'statement-verb') {
1806
blockStack.unshift(newBlock = 'statement');
1807
} else if (i > 0 && tokens[i-1][0] == 'builtin') {
1808
blockStack.unshift(newBlock = 'function');
1810
blockStack.unshift(newBlock = 'generic');
1816
// Block end => pop from stack
1817
if (tokens[i][1] == ')') {
1818
endBlock = blockStack[0];
1824
// A subquery is starting
1825
if (i > 0 && newBlock == 'statement') {
1827
output += "\n" + tabs(indentLevel) + tokens[i][1] + ' ' + tokens[i+1][1].toUpperCase() + "\n" + tabs(indentLevel + 1);
1828
currentStatement = tokens[i+1][1];
1833
// A subquery is ending
1834
if (endBlock == 'statement' && indentLevel > 0) {
1835
output += "\n" + tabs(indentLevel);
1839
// One less indentation for statement parts (from, where, order by, etc.) and a newline
1840
statementPart = statements[currentStatement].indexOf(tokens[i][1]);
1841
if (statementPart != -1) {
1845
output += tabs(indentLevel) + tokens[i][1].toUpperCase();
1846
output += "\n" + tabs(indentLevel + 1);
1847
lastStatementPart = tokens[i][1];
1849
// Normal indentatin and spaces for everything else
1851
if (! spaceExceptionsBefore[tokens[i][1]]
1852
&& ! (i > 0 && spaceExceptionsAfter[tokens[i-1][1]])
1853
&& output.charAt(output.length -1) != ' ' ) {
1856
if (tokens[i][0] == 'keyword') {
1857
output += tokens[i][1].toUpperCase();
1859
output += tokens[i][1];
1863
// split columns in select and 'update set' clauses, but only inside statements blocks
1864
if (( lastStatementPart == 'select' || lastStatementPart == 'where' || lastStatementPart == 'set')
1865
&& tokens[i][1]==',' && blockStack[0] == 'statement') {
1867
output += "\n" + tabs(indentLevel + 1);
1870
// split conditions in where clauses, but only inside statements blocks
1871
if (lastStatementPart == 'where'
1872
&& (tokens[i][1]=='and' || tokens[i][1]=='or' || tokens[i][1]=='xor')) {
1874
if (blockStack[0] == 'statement') {
1875
output += "\n" + tabs(indentLevel + 1);
1877
// Todo: Also split and or blocks in newlines & identation++
1878
//if (blockStack[0] == 'generic')
1886
* jQuery function that uses jQueryUI's dialogs to confirm with user. Does not
1887
* return a jQuery object yet and hence cannot be chained
1889
* @param string question
1890
* @param string url URL to be passed to the callbackFn to make
1892
* @param function callbackFn callback to execute after user clicks on OK
1895
jQuery.fn.PMA_confirm = function(question, url, callbackFn) {
1896
var confirmState = PMA_commonParams.get('confirm');
1897
// when the Confirm directive is set to false in config.inc.php
1898
// and not changed in user prefs, confirmState is ""
1899
// when it's unticked in user prefs, confirmState is 1
1900
if (confirmState === "" || confirmState === "1") {
1901
// user does not want to confirm
1902
if ($.isFunction(callbackFn)) {
1903
callbackFn.call(this, url);
1907
if (PMA_messages['strDoYouReally'] == '') {
1912
* @var button_options Object that stores the options passed to jQueryUI
1915
var button_options = {};
1916
button_options[PMA_messages['strOK']] = function() {
1917
$(this).dialog("close");
1919
if ($.isFunction(callbackFn)) {
1920
callbackFn.call(this, url);
1923
button_options[PMA_messages['strCancel']] = function() {
1924
$(this).dialog("close");
1927
$('<div/>', {'id':'confirm_dialog'})
1930
buttons: button_options,
1931
close: function () {
1939
* jQuery function to sort a table's body after a new row has been appended to it.
1940
* Also fixes the even/odd classes of the table rows at the end.
1942
* @param string text_selector string to select the sortKey's text
1944
* @return jQuery Object for chaining purposes
1946
jQuery.fn.PMA_sort_table = function(text_selector) {
1947
return this.each(function() {
1950
* @var table_body Object referring to the table's <tbody> element
1952
var table_body = $(this);
1954
* @var rows Object referring to the collection of rows in {@link table_body}
1956
var rows = $(this).find('tr').get();
1958
//get the text of the field that we will sort by
1959
$.each(rows, function(index, row) {
1960
row.sortKey = $.trim($(row).find(text_selector).text().toLowerCase());
1963
//get the sorted order
1964
rows.sort(function(a, b) {
1965
if (a.sortKey < b.sortKey) {
1968
if (a.sortKey > b.sortKey) {
1974
//pull out each row from the table and then append it according to it's order
1975
$.each(rows, function(index, row) {
1976
$(table_body).append(row);
1980
//Re-check the classes of each row
1981
$(this).find('tr:odd')
1982
.removeClass('even').addClass('odd')
1985
.removeClass('odd').addClass('even');
1990
* Unbind all event handlers before tearing down a page
1992
AJAX.registerTeardown('functions.js', function() {
1993
$("#create_table_form_minimal.ajax").die('submit');
1994
$("form.create_table_form.ajax").die('submit');
1995
$("form.create_table_form.ajax input[name=submit_num_fields]").die('click');
1996
$("form.create_table_form.ajax input").die('keyup');
2000
* jQuery coding for 'Create Table'. Used on db_operations.php,
2001
* db_structure.php and db_tracking.php (i.e., wherever
2002
* libraries/display_create_table.lib.php is used)
2004
* Attach Ajax Event handlers for Create Table
2006
AJAX.registerOnload('functions.js', function() {
2008
* Attach event handler for submission of create table form (save)
2010
$("form.create_table_form.ajax").live('submit', function(event) {
2011
event.preventDefault();
2014
* @var the_form object referring to the create table form
2016
var $form = $(this);
2019
* First validate the form; if there is a problem, avoid submitting it
2021
* checkTableEditForm() needs a pure element and not a jQuery object,
2022
* this is why we pass $form[0] as a parameter (the jQuery object
2023
* is actually an array of DOM elements)
2026
if (checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) {
2027
PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2028
PMA_prepareForAjaxRequest($form);
2029
//User wants to submit the form
2030
$.post($form.attr('action'), $form.serialize() + "&do_save_data=1", function(data) {
2031
if (data.success == true) {
2032
$('#properties_message')
2033
.removeClass('error')
2035
PMA_ajaxShowMessage(data.message);
2036
// Only if the create table dialog (distinct panel) exists
2037
if ($("#create_table_dialog").length > 0) {
2038
$("#create_table_dialog").dialog("close").remove();
2040
$('#tableslistcontainer').before(data.formatted_sql);
2043
* @var tables_table Object referring to the <tbody> element that holds the list of tables
2045
var tables_table = $("#tablesForm").find("tbody").not("#tbl_summary_row");
2046
// this is the first table created in this db
2047
if (tables_table.length == 0) {
2048
PMA_commonActions.refreshMain(
2049
PMA_commonParams.get('opendb_url')
2053
* @var curr_last_row Object referring to the last <tr> element in {@link tables_table}
2055
var curr_last_row = $(tables_table).find('tr:last');
2057
* @var curr_last_row_index_string String containing the index of {@link curr_last_row}
2059
var curr_last_row_index_string = $(curr_last_row).find('input:checkbox').attr('id').match(/\d+/)[0];
2061
* @var curr_last_row_index Index of {@link curr_last_row}
2063
var curr_last_row_index = parseFloat(curr_last_row_index_string);
2065
* @var new_last_row_index Index of the new row to be appended to {@link tables_table}
2067
var new_last_row_index = curr_last_row_index + 1;
2069
* @var new_last_row_id String containing the id of the row to be appended to {@link tables_table}
2071
var new_last_row_id = 'checkbox_tbl_' + new_last_row_index;
2073
data.new_table_string = data.new_table_string.replace(/checkbox_tbl_/, new_last_row_id);
2075
$(data.new_table_string)
2076
.appendTo(tables_table);
2079
$(tables_table).PMA_sort_table('th');
2081
// Adjust summary row
2085
//Refresh navigation as a new table has been added
2086
PMA_reloadNavigation();
2088
PMA_ajaxShowMessage(
2089
'<div class="error">' + data.error + '</div>',
2094
} // end if (checkTableEditForm() )
2095
}); // end create table form (save)
2098
* Attach event handler for create table form (add fields)
2100
$("form.create_table_form.ajax input[name=submit_num_fields]").live('click', function(event) {
2101
event.preventDefault();
2103
* @var the_form object referring to the create table form
2105
var $form = $(this).closest('form');
2107
var $msgbox = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2108
PMA_prepareForAjaxRequest($form);
2110
//User wants to add more fields to the table
2111
$.post($form.attr('action'), $form.serialize() + "&submit_num_fields=1", function(data) {
2113
$("#page_content").html(data.message);
2114
PMA_verifyColumnsProperties();
2115
PMA_ajaxRemoveMessage($msgbox);
2117
PMA_ajaxShowMessage(data.error);
2120
}); // end create table form (add fields)
2122
$("form.create_table_form.ajax input").live('keydown', function (event) {
2123
if (event.keyCode == 13) {
2124
event.preventDefault();
2125
event.stopImmediatePropagation();
2128
.append('<input type="hidden" name="do_save_data" value="1" />')
2136
* Unbind all event handlers before tearing down a page
2138
AJAX.registerTeardown('functions.js', function() {
2139
$("#copyTable.ajax").die('submit');
2140
$("#moveTableForm").die('submit');
2141
$("#tableOptionsForm").die('submit');
2142
$("#tbl_maintenance li a.maintain_action.ajax").die('click');
2145
* jQuery coding for 'Table operations'. Used on tbl_operations.php
2146
* Attach Ajax Event handlers for Table operations
2148
AJAX.registerOnload('functions.js', function() {
2150
*Ajax action for submitting the "Copy table"
2152
$("#copyTable.ajax").live('submit', function(event) {
2153
event.preventDefault();
2154
var $form = $(this);
2155
PMA_prepareForAjaxRequest($form);
2156
$.post($form.attr('action'), $form.serialize()+"&submit_copy=Go", function(data) {
2157
if (data.success == true) {
2158
if ($form.find("input[name='switch_to_new']").prop('checked')) {
2159
PMA_commonParams.set(
2163
PMA_commonParams.set(
2165
$form.find("input[name='new_name']").val()
2167
PMA_commonActions.refreshMain(false, function () {
2168
PMA_ajaxShowMessage(data.message);
2171
PMA_ajaxShowMessage(data.message);
2173
// Refresh navigation when the table is copied
2174
PMA_reloadNavigation();
2176
PMA_ajaxShowMessage(data.error, false);
2179
});//end of copyTable ajax submit
2182
*Ajax action for submitting the "Move table"
2184
$("#moveTableForm").live('submit', function(event) {
2185
event.preventDefault();
2186
var $form = $(this);
2187
var db = $form.find('select[name=target_db]').val();
2188
var tbl = $form.find('input[name=new_name]').val();
2189
PMA_prepareForAjaxRequest($form);
2190
$.post($form.attr('action'), $form.serialize()+"&submit_move=1", function(data) {
2191
if (data.success == true) {
2192
PMA_commonParams.set('db', db);
2193
PMA_commonParams.set('table', tbl);
2194
PMA_commonActions.refreshMain(false, function () {
2195
PMA_ajaxShowMessage(data.message);
2197
// Refresh navigation when the table is copied
2198
PMA_reloadNavigation();
2200
PMA_ajaxShowMessage(data.error, false);
2206
* Ajax action for submitting the "Table options"
2208
$("#tableOptionsForm").live('submit', function(event) {
2209
event.preventDefault();
2210
event.stopPropagation();
2211
var $form = $(this);
2212
var $tblNameField = $form.find('input[name=new_name]');
2213
if ($tblNameField.val() !== $tblNameField[0].defaultValue) {
2214
// reload page and navigation if the table has been renamed
2215
PMA_prepareForAjaxRequest($form);
2216
var tbl = $tblNameField.val();
2217
$.post($form.attr('action'), $form.serialize(), function(data) {
2218
if (data.success == true) {
2219
PMA_commonParams.set('table', tbl);
2220
PMA_commonActions.refreshMain(false, function() {
2221
$('#page_content').html(data.message);
2224
PMA_ajaxShowMessage(data.error, false);
2228
$form.removeClass('ajax').submit().addClass('ajax');
2233
*Ajax events for actions in the "Table maintenance"
2235
$("#tbl_maintenance li a.maintain_action.ajax").live('click', function(event) {
2236
event.preventDefault();
2237
if ($("#sqlqueryresults").length != 0) {
2238
$("#sqlqueryresults").remove();
2240
if ($("#result_query").length != 0) {
2241
$("#result_query").remove();
2243
//variables which stores the common attributes
2244
$.post($(this).attr('href'), { ajax_request: 1 }, function(data) {
2245
function scrollToTop() {
2246
$('html, body').animate({ scrollTop: 0 });
2248
if (data.success == true && data.sql_query != undefined) {
2249
PMA_ajaxShowMessage(data.message);
2250
$("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");
2251
$("#sqlqueryresults").html(data.sql_query);
2253
} else if (data.success == true) {
2254
var $temp_div = $("<div id='temp_div'></div>");
2255
$temp_div.html(data.message);
2256
var $success = $temp_div.find("#result_query .success");
2257
PMA_ajaxShowMessage($success);
2258
$("<div id='sqlqueryresults' class='ajax'></div>").prependTo("#page_content");
2259
$("#sqlqueryresults").html(data.message);
2261
$("#sqlqueryresults").children("fieldset,br").remove();
2264
var $temp_div = $("<div id='temp_div'></div>");
2265
$temp_div.html(data.error);
2266
var $error = $temp_div.find("code").addClass("error");
2267
PMA_ajaxShowMessage($error, false);
2270
});//end of table maintanance ajax click
2271
}); //end $(document).ready for 'Table operations'
2274
* Unbind all event handlers before tearing down a page
2276
AJAX.registerTeardown('functions.js', function() {
2277
$("#drop_db_anchor.ajax").die('click');
2280
* Attach Ajax event handlers for Drop Database. Moved here from db_structure.js
2281
* as it was also required on db_create.php
2283
AJAX.registerOnload('functions.js', function() {
2284
$("#drop_db_anchor.ajax").live('click', function(event) {
2285
event.preventDefault();
2287
* @var question String containing the question to be asked for confirmation
2289
var question = PMA_messages.strDropDatabaseStrongWarning + ' ';
2290
question += $.sprintf(
2291
PMA_messages.strDoYouReally,
2292
'DROP DATABASE ' + escapeHtml(PMA_commonParams.get('db'))
2294
$(this).PMA_confirm(question, $(this).attr('href'), function(url) {
2295
PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2296
$.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function(data) {
2298
//Database deleted successfully, refresh both the frames
2299
PMA_reloadNavigation();
2300
PMA_commonParams.set('db', '');
2301
PMA_commonActions.refreshMain(
2302
'server_databases.php',
2304
PMA_ajaxShowMessage(data.message);
2308
PMA_ajaxShowMessage(data.error, false);
2313
}); // end of $() for Drop Database
2316
* Validates the password field in a form
2318
* @see PMA_messages['strPasswordEmpty']
2319
* @see PMA_messages['strPasswordNotSame']
2320
* @param object $the_form The form to be validated
2323
function PMA_checkPassword($the_form)
2325
// Did the user select 'no password'?
2326
if ($the_form.find('#nopass_1').is(':checked')) {
2329
var $pred = $the_form.find('#select_pred_password');
2330
if ($pred.length && ($pred.val() == 'none' || $pred.val() == 'keep')) {
2335
var $password = $the_form.find('input[name=pma_pw]');
2336
var $password_repeat = $the_form.find('input[name=pma_pw2]');
2337
var alert_msg = false;
2339
if ($password.val() == '') {
2340
alert_msg = PMA_messages['strPasswordEmpty'];
2341
} else if ($password.val() != $password_repeat.val()) {
2342
alert_msg = PMA_messages['strPasswordNotSame'];
2348
$password_repeat.val('');
2356
* Unbind all event handlers before tearing down a page
2358
AJAX.registerTeardown('functions.js', function() {
2359
$('#change_password_anchor.ajax').die('click');
2362
* Attach Ajax event handlers for 'Change Password' on index.php
2364
AJAX.registerOnload('functions.js', function() {
2367
* Attach Ajax event handler on the change password anchor
2369
$('#change_password_anchor.ajax').live('click', function(event) {
2370
event.preventDefault();
2372
var $msgbox = PMA_ajaxShowMessage();
2375
* @var button_options Object containing options to be passed to jQueryUI's dialog
2377
var button_options = {};
2378
button_options[PMA_messages['strGo']] = function() {
2380
event.preventDefault();
2383
* @var $the_form Object referring to the change password form
2385
var $the_form = $("#change_password_form");
2387
if (! PMA_checkPassword($the_form)) {
2392
* @var this_value String containing the value of the submit button.
2393
* Need to append this for the change password form on Server Privileges
2396
var this_value = $(this).val();
2398
var $msgbox = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
2399
$the_form.append('<input type="hidden" name="ajax_request" value="true" />');
2401
$.post($the_form.attr('action'), $the_form.serialize() + '&change_pw='+ this_value, function(data) {
2402
if (data.success == true) {
2403
$("#page_content").prepend(data.message);
2404
$("#change_password_dialog").hide().remove();
2405
$("#edit_user_dialog").dialog("close").remove();
2406
PMA_ajaxRemoveMessage($msgbox);
2409
PMA_ajaxShowMessage(data.error, false);
2414
button_options[PMA_messages['strCancel']] = function() {
2415
$(this).dialog('close');
2417
$.get($(this).attr('href'), {'ajax_request': true}, function(data) {
2419
$('<div id="change_password_dialog"></div>')
2421
title: PMA_messages['strChangePassword'],
2423
close: function(ev, ui) {
2426
buttons : button_options,
2429
.append(data.message);
2430
// for this dialog, we remove the fieldset wrapping due to double headings
2431
$("fieldset#fieldset_change_password")
2432
.find("legend").remove().end()
2433
.find("table.noclick").unwrap().addClass("some-margin")
2434
.find("input#text_pma_pw").focus();
2435
displayPasswordGenerateButton();
2436
$('#fieldset_change_password_footer').hide();
2437
PMA_ajaxRemoveMessage($msgbox);
2438
$('#change_password_form').bind('submit', function (e) {
2441
.closest('.ui-dialog')
2442
.find('.ui-dialog-buttonpane .ui-button')
2447
PMA_ajaxShowMessage(data.error, false);
2450
}); // end handler for change password anchor
2451
}); // end $() for Change Password
2454
* Unbind all event handlers before tearing down a page
2456
AJAX.registerTeardown('functions.js', function() {
2457
$("select.column_type").die('change');
2458
$("select.default_type").die('change');
2459
$('input.allow_null').die('change');
2462
* Toggle the hiding/showing of the "Open in ENUM/SET editor" message when
2463
* the page loads and when the selected data type changes
2465
AJAX.registerOnload('functions.js', function() {
2466
// is called here for normal page loads and also when opening
2467
// the Create table dialog
2468
PMA_verifyColumnsProperties();
2470
// needs live() to work also in the Create Table dialog
2471
$("select.column_type").live('change', function() {
2472
PMA_showNoticeForEnum($(this));
2474
$("select.default_type").live('change', function() {
2475
PMA_hideShowDefaultValue($(this));
2477
$('input.allow_null').live('change', function() {
2478
PMA_validateDefaultValue($(this));
2482
function PMA_verifyColumnsProperties()
2484
$("select.column_type").each(function() {
2485
PMA_showNoticeForEnum($(this));
2487
$("select.default_type").each(function() {
2488
PMA_hideShowDefaultValue($(this));
2493
* Hides/shows the default value input field, depending on the default type
2494
* Ticks the NULL checkbox if NULL is chosen as default value.
2496
function PMA_hideShowDefaultValue($default_type)
2498
if ($default_type.val() == 'USER_DEFINED') {
2499
$default_type.siblings('.default_value').show().focus();
2501
$default_type.siblings('.default_value').hide();
2502
if ($default_type.val() == 'NULL') {
2503
var $null_checkbox = $default_type.closest('tr').find('.allow_null');
2504
$null_checkbox.prop('checked', true);
2510
* If the column does not allow NULL values, makes sure that default is not NULL
2512
function PMA_validateDefaultValue($null_checkbox)
2514
if (! $null_checkbox.prop('checked')) {
2515
var $default = $null_checkbox.closest('tr').find('.default_type');
2516
if ($default.val() == 'NULL') {
2517
$default.val('NONE');
2524
* Unbind all event handlers before tearing down a page
2526
AJAX.registerTeardown('functions.js', function() {
2527
$("a.open_enum_editor").die('click');
2528
$("input.add_value").die('click');
2529
$("#enum_editor td.drop").die('click');
2532
* @var $enum_editor_dialog An object that points to the jQuery
2533
* dialog of the ENUM/SET editor
2535
var $enum_editor_dialog = null;
2537
* Opens the ENUM/SET editor and controls its functions
2539
AJAX.registerOnload('functions.js', function() {
2540
$("a.open_enum_editor").live('click', function() {
2541
// Get the name of the column that is being edited
2542
var colname = $(this).closest('tr').find('input:first').val();
2543
// And use it to make up a title for the page
2544
if (colname.length < 1) {
2545
var title = PMA_messages['enum_newColumnVals'];
2547
var title = PMA_messages['enum_columnVals'].replace(
2549
'"' + decodeURIComponent(colname) + '"'
2552
// Get the values as a string
2553
var inputstring = $(this)
2557
// Escape html entities
2558
inputstring = $('<div/>')
2561
// Parse the values, escaping quotes and
2562
// slashes on the fly, into an array
2564
var in_string = false;
2565
var curr, next, buffer = '';
2566
for (var i=0; i<inputstring.length; i++) {
2567
curr = inputstring.charAt(i);
2568
next = i == inputstring.length ? '' : inputstring.charAt(i+1);
2569
if (! in_string && curr == "'") {
2571
} else if (in_string && curr == "\\" && next == "\\") {
2574
} else if (in_string && next == "'" && (curr == "'" || curr == "\\")) {
2577
} else if (in_string && curr == "'") {
2579
values.push(buffer);
2581
} else if (in_string) {
2585
if (buffer.length > 0) {
2586
// The leftovers in the buffer are the last value (if any)
2587
values.push(buffer);
2590
// If there are no values, maybe the user is about to make a
2591
// new list so we add a few for him/her to get started with.
2592
if (values.length == 0) {
2593
values.push('','','','');
2595
// Add the parsed values to the editor
2596
var drop_icon = PMA_getImage('b_drop.png');
2597
for (var i=0; i<values.length; i++) {
2598
fields += "<tr><td>"
2599
+ "<input type='text' value='" + values[i] + "'/>"
2600
+ "</td><td class='drop'>"
2605
* @var dialog HTML code for the ENUM/SET dialog
2607
var dialog = "<div id='enum_editor'>"
2609
+ "<legend>" + title + "</legend>"
2610
+ "<p>" + PMA_getImage('s_notice.png')
2611
+ PMA_messages['enum_hint'] + "</p>"
2612
+ "<table class='values'>" + fields + "</table>"
2613
+ "</fieldset><fieldset class='tblFooters'>"
2614
+ "<table class='add'><tr><td>"
2615
+ "<div class='slider'></div>"
2617
+ "<form><div><input type='submit' class='add_value' value='"
2618
+ $.sprintf(PMA_messages['enum_addValue'], 1)
2619
+ "'/></div></form>"
2620
+ "</td></tr></table>"
2621
+ "<input type='hidden' value='" // So we know which column's data is being edited
2622
+ $(this).closest('td').find("input").attr("id")
2627
* @var Defines functions to be called when the buttons in
2628
* the buttonOptions jQuery dialog bar are pressed
2630
var buttonOptions = {};
2631
buttonOptions[PMA_messages['strGo']] = function () {
2632
// When the submit button is clicked,
2633
// put the data back into the original form
2634
var value_array = [];
2635
$(this).find(".values input").each(function(index, elm) {
2636
var val = elm.value.replace(/\\/g, '\\\\').replace(/'/g, "''");
2637
value_array.push("'" + val + "'");
2639
// get the Length/Values text field where this value belongs
2640
var values_id = $(this).find("input[type='hidden']").val();
2641
$("input#" + values_id).val(value_array.join(","));
2642
$(this).dialog("close");
2644
buttonOptions[PMA_messages['strClose']] = function () {
2645
$(this).dialog("close");
2648
var width = parseInt(
2649
(parseInt($('html').css('font-size'), 10)/13)*340,
2655
$enum_editor_dialog = $(dialog).dialog({
2658
title: PMA_messages['enum_editor'],
2659
buttons: buttonOptions,
2661
// Focus the "Go" button after opening the dialog
2662
$(this).closest('.ui-dialog').find('.ui-dialog-buttonpane button:first').focus();
2668
// slider for choosing how many fields to add
2669
$enum_editor_dialog.find(".slider").slider({
2675
slide: function( event, ui ) {
2676
$(this).closest('table').find('input[type=submit]').val(
2677
$.sprintf(PMA_messages['enum_addValue'], ui.value)
2681
// Focus the slider, otherwise it looks nearly transparent
2682
$('a.ui-slider-handle').addClass('ui-state-focus');
2686
// When "add a new value" is clicked, append an empty text field
2687
$("input.add_value").live('click', function(e) {
2689
var num_new_rows = $enum_editor_dialog.find("div.slider").slider('value');
2690
while (num_new_rows--) {
2691
$enum_editor_dialog.find('.values')
2693
"<tr style='display: none;'><td>"
2694
+ "<input type='text' />"
2695
+ "</td><td class='drop'>"
2696
+ PMA_getImage('b_drop.png')
2704
// Removes the specified row from the enum editor
2705
$("#enum_editor td.drop").live('click', function() {
2706
$(this).closest('tr').hide('fast', function () {
2713
* Ensures indexes names are valid according to their type and, for a primary
2714
* key, lock index name to 'PRIMARY'
2715
* @param string form_id Variable which parses the form name as
2717
* @return boolean false if there is no index form, true else
2719
function checkIndexName(form_id)
2721
if ($("#"+form_id).length == 0) {
2725
// Gets the elements pointers
2726
var $the_idx_name = $("#input_index_name");
2727
var $the_idx_type = $("#select_index_type");
2729
// Index is a primary key
2730
if ($the_idx_type.find("option:selected").val() == 'PRIMARY') {
2731
$the_idx_name.val('PRIMARY');
2732
$the_idx_name.prop("disabled", true);
2737
if ($the_idx_name.val() == 'PRIMARY') {
2738
$the_idx_name.val("");
2740
$the_idx_name.prop("disabled", false);
2744
} // end of the 'checkIndexName()' function
2746
AJAX.registerTeardown('functions.js', function() {
2747
$('#index_frm input[type=submit]').die('click');
2749
AJAX.registerOnload('functions.js', function() {
2751
* Handler for adding more columns to an index in the editor
2753
$('#index_frm input[type=submit]').live('click', function(event) {
2754
event.preventDefault();
2755
var rows_to_add = $(this)
2756
.closest('fieldset')
2759
while (rows_to_add--) {
2760
var $newrow = $('#index_columns')
2761
.find('tbody > tr:first')
2764
$('#index_columns').find('tbody')
2766
$newrow.find(':input').each(function() {
2769
// focus index size input on column picked
2770
$newrow.find('select').change(function() {
2771
if ($(this).find("option:selected").val() == '') {
2774
$(this).closest("tr").find("input").focus();
2780
function indexEditorDialog(url, title, callback_success, callback_failure)
2782
/*Remove the hidden dialogs if there are*/
2783
if ($('#edit_index_dialog').length != 0) {
2784
$('#edit_index_dialog').remove();
2786
var $div = $('<div id="edit_index_dialog"></div>');
2789
* @var button_options Object that stores the options
2790
* passed to jQueryUI dialog
2792
var button_options = {};
2793
button_options[PMA_messages['strGo']] = function() {
2795
* @var the_form object referring to the export form
2797
var $form = $("#index_frm");
2798
PMA_prepareForAjaxRequest($form);
2799
//User wants to submit the form
2800
$.post($form.attr('action'), $form.serialize()+"&do_save_data=1", function(data) {
2801
if ($("#sqlqueryresults").length != 0) {
2802
$("#sqlqueryresults").remove();
2804
if (data.success == true) {
2805
PMA_ajaxShowMessage(data.message);
2806
if ($('#result_query').length) {
2807
$('#result_query').remove();
2809
if (data.sql_query) {
2810
$('<div id="result_query"></div>')
2811
.html(data.sql_query)
2812
.prependTo('#page_content');
2814
$("#result_query .notice").remove();
2815
$("#result_query").prepend(data.message);
2816
/*Reload the field form*/
2817
$("#table_index").remove();
2818
var $temp_div = $("<div id='temp_div'><div>").append(data.index_table);
2819
$temp_div.find("#table_index").insertAfter("#index_header");
2820
if ($("#edit_index_dialog").length > 0) {
2821
$("#edit_index_dialog").dialog("close");
2823
$('div.no_indexes_defined').hide();
2824
if (callback_success) {
2827
PMA_reloadNavigation();
2829
var $temp_div = $("<div id='temp_div'><div>").append(data.error);
2830
if ($temp_div.find(".error code").length != 0) {
2831
var $error = $temp_div.find(".error code").addClass("error");
2833
var $error = $temp_div;
2835
if (callback_failure) {
2838
PMA_ajaxShowMessage($error, false);
2842
button_options[PMA_messages['strCancel']] = function() {
2843
$(this).dialog('close');
2845
var $msgbox = PMA_ajaxShowMessage();
2846
$.get("tbl_indexes.php", url, function(data) {
2847
if (data.success == false) {
2848
//in the case of an error, show the error message returned.
2849
PMA_ajaxShowMessage(data.error, false);
2851
PMA_ajaxRemoveMessage($msgbox);
2852
// Show dialog if the request was successful
2854
.append(data.message)
2858
open: PMA_verifyColumnsProperties,
2860
buttons: button_options,
2861
close: function () {
2866
checkIndexName("index_frm");
2867
PMA_showHints($div);
2868
// Add a slider for selecting how many columns to add to the index
2869
$div.find('.slider').slider({
2874
slide: function( event, ui ) {
2875
$(this).closest('fieldset').find('input[type=submit]').val(
2876
$.sprintf(PMA_messages['strAddToIndex'], ui.value)
2880
// focus index size input on column picked
2881
$div.find('table#index_columns select').change(function() {
2882
if ($(this).find("option:selected").val() == '') {
2885
$(this).closest("tr").find("input").focus();
2887
// Focus the slider, otherwise it looks nearly transparent
2888
$('a.ui-slider-handle').addClass('ui-state-focus');
2889
// set focus on index name input, if empty
2890
var input = $div.find('input#input_index_name');
2891
input.val() || input.focus();
2897
* Function to display tooltips that were
2898
* generated on the PHP side by PMA_Util::showHint()
2900
* @param object $div a div jquery object which specifies the
2901
* domain for searching for tooltips. If we
2902
* omit this parameter the function searches
2905
function PMA_showHints($div)
2907
if ($div == undefined || ! $div instanceof jQuery || $div.length == 0) {
2910
$div.find('.pma_hint').each(function () {
2912
$(this).children('img'),
2914
$(this).children('span').html()
2919
AJAX.registerOnload('functions.js', function() {
2923
function PMA_mainMenuResizerCallback() {
2924
// 5 px margin for jumping menu in Chrome
2925
return $(document.body).width() - 5;
2927
// This must be fired only once after the inital page load
2929
// Initialise the menu resize plugin
2930
$('#topmenu').menuResizer(PMA_mainMenuResizerCallback);
2931
// register resize event
2932
$(window).resize(function (){
2933
$('#topmenu').menuResizer('resize');
2938
* Get the row number from the classlist (for example, row_1)
2940
function PMA_getRowNumber(classlist)
2942
return parseInt(classlist.split(/\s+row_/)[1]);
2946
* Changes status of slider
2948
function PMA_set_status_label($element)
2950
var text = $element.css('display') == 'none'
2953
$element.closest('.slide-wrapper').prev().find('span').text(text);
2957
* var toggleButton This is a function that creates a toggle
2958
* sliding button given a jQuery reference
2959
* to the correct DOM element
2961
var toggleButton = function ($obj) {
2962
// In rtl mode the toggle switch is flipped horizontally
2963
// so we need to take that into account
2964
if ($('span.text_direction', $obj).text() == 'ltr') {
2965
var right = 'right';
2970
* var h Height of the button, used to scale the
2971
* background image and position the layers
2973
var h = $obj.height();
2974
$('img', $obj).height(h);
2975
$('table', $obj).css('bottom', h-1);
2977
* var on Width of the "ON" part of the toggle switch
2978
* var off Width of the "OFF" part of the toggle switch
2980
var on = $('td.toggleOn', $obj).width();
2981
var off = $('td.toggleOff', $obj).width();
2982
// Make the "ON" and "OFF" parts of the switch the same size
2983
// + 2 pixels to avoid overflowed
2984
$('td.toggleOn > div', $obj).width(Math.max(on, off) + 2);
2985
$('td.toggleOff > div', $obj).width(Math.max(on, off) + 2);
2987
* var w Width of the central part of the switch
2989
var w = parseInt(($('img', $obj).height() / 16) * 22, 10);
2990
// Resize the central part of the switch on the top
2991
// layer to match the background
2992
$('table td:nth-child(2) > div', $obj).width(w);
2994
* var imgw Width of the background image
2995
* var tblw Width of the foreground layer
2996
* var offset By how many pixels to move the background
2997
* image, so that it matches the top layer
2999
var imgw = $('img', $obj).width();
3000
var tblw = $('table', $obj).width();
3001
var offset = parseInt(((imgw - tblw) / 2), 10);
3002
// Move the background to match the layout of the top layer
3003
$obj.find('img').css(right, offset);
3005
* var offw Outer width of the "ON" part of the toggle switch
3006
* var btnw Outer width of the central part of the switch
3008
var offw = $('td.toggleOff', $obj).outerWidth();
3009
var btnw = $('table td:nth-child(2)', $obj).outerWidth();
3010
// Resize the main div so that exactly one side of
3011
// the switch plus the central part fit into it.
3012
$obj.width(offw + btnw + 2);
3014
* var move How many pixels to move the
3015
* switch by when toggling
3017
var move = $('td.toggleOff', $obj).outerWidth();
3018
// If the switch is initialized to the
3019
// OFF state we need to move it now.
3020
if ($('div.container', $obj).hasClass('off')) {
3021
if (right == 'right') {
3022
$('div.container', $obj).animate({'left': '-=' + move + 'px'}, 0);
3024
$('div.container', $obj).animate({'left': '+=' + move + 'px'}, 0);
3027
// Attach an 'onclick' event to the switch
3028
$('div.container', $obj).click(function () {
3029
if ($(this).hasClass('isActive')) {
3032
$(this).addClass('isActive');
3034
var $msg = PMA_ajaxShowMessage();
3035
var $container = $(this);
3036
var callback = $('span.callback', this).text();
3037
// Perform the actual toggle
3038
if ($(this).hasClass('on')) {
3039
if (right == 'right') {
3040
var operator = '-=';
3042
var operator = '+=';
3044
var url = $(this).find('td.toggleOff > span').text();
3045
var removeClass = 'on';
3046
var addClass = 'off';
3048
if (right == 'right') {
3049
var operator = '+=';
3051
var operator = '-=';
3053
var url = $(this).find('td.toggleOn > span').text();
3054
var removeClass = 'off';
3055
var addClass = 'on';
3057
$.post(url, {'ajax_request': true}, function(data) {
3058
if (data.success == true) {
3059
PMA_ajaxRemoveMessage($msg);
3061
.removeClass(removeClass)
3063
.animate({'left': operator + move + 'px'}, function () {
3064
$container.removeClass('isActive');
3068
PMA_ajaxShowMessage(data.error, false);
3069
$container.removeClass('isActive');
3076
* Unbind all event handlers before tearing down a page
3078
AJAX.registerTeardown('functions.js', function() {
3079
$('div.container').unbind('click');
3082
* Initialise all toggle buttons
3084
AJAX.registerOnload('functions.js', function () {
3085
$('div.toggleAjax').each(function () {
3086
var $button = $(this).show();
3087
$button.find('img').each(function() {
3088
if (this.complete) {
3089
toggleButton($button);
3091
$(this).load(function () {
3092
toggleButton($button);
3100
* Unbind all event handlers before tearing down a page
3102
AJAX.registerTeardown('functions.js', function() {
3103
$('.vpointer').die('hover');
3104
$('.vmarker').die('click');
3105
$('#pageselector').die('change');
3106
$('a.formLinkSubmit').die('click');
3107
$('#update_recent_tables').unbind('ready');
3112
AJAX.registerOnload('functions.js', function() {
3113
$('.vpointer').live('hover',
3116
var $this_td = $(this);
3117
var row_num = PMA_getRowNumber($this_td.attr('class'));
3118
// for all td of the same vertical row, toggle hover
3119
$('.vpointer').filter('.row_' + row_num).toggleClass('hover');
3127
$('.vmarker').live('click', function(e) {
3128
// do not trigger when clicked on anchor
3129
if ($(e.target).is('a, img, a *')) {
3133
var $this_td = $(this);
3134
var row_num = PMA_getRowNumber($this_td.attr('class'));
3136
// XXX: FF fires two click events for <label> (label and checkbox), so we need to handle this differently
3137
var $checkbox = $('.vmarker').filter('.row_' + row_num + ':first').find(':checkbox');
3138
if ($checkbox.length) {
3139
// checkbox in a row, add or remove class depending on checkbox state
3140
var checked = $checkbox.prop('checked');
3141
if (!$(e.target).is(':checkbox, label')) {
3143
$checkbox.prop('checked', checked);
3145
// for all td of the same vertical row, toggle the marked class
3147
$('.vmarker').filter('.row_' + row_num).addClass('marked');
3149
$('.vmarker').filter('.row_' + row_num).removeClass('marked');
3152
// normaln data table, just toggle class
3153
$('.vmarker').filter('.row_' + row_num).toggleClass('marked');
3158
* Autosubmit page selector
3160
$('select.pageselector').live('change', function(event) {
3161
event.stopPropagation();
3162
// Check where to load the new content
3163
if ($(this).closest("#pma_navigation").length == 0) {
3164
// For the main page we don't need to do anything,
3165
$(this).closest("form").submit();
3167
// but for the navigation we need to manually replace the content
3168
PMA_navigationTreePagination($(this));
3173
* Load version information asynchronously.
3175
if ($('li.jsversioncheck').length > 0) {
3176
$.getJSON('version_check.php', {}, PMA_current_version);
3179
if ($('#is_git_revision').length > 0) {
3180
setTimeout(PMA_display_git_revision, 10);
3189
* Enables the text generated by PMA_Util::linkOrButton() to be clickable
3191
$('a.formLinkSubmit').live('click', function(e) {
3193
if ($(this).attr('href').indexOf('=') != -1) {
3194
var data = $(this).attr('href').substr($(this).attr('href').indexOf('#')+1).split('=', 2);
3195
$(this).parents('form').append('<input type="hidden" name="' + data[0] + '" value="' + data[1] + '"/>');
3197
$(this).parents('form').submit();
3201
if ($('#update_recent_tables').length) {
3203
$('#update_recent_tables').attr('href'),
3205
if (data.success == true) {
3206
$('#recentTable').html(data.options);
3216
* Initializes slider effect.
3218
function PMA_init_slider()
3220
$('div.pma_auto_slider').each(function() {
3221
var $this = $(this);
3222
if ($this.data('slider_init_done')) {
3225
var $wrapper = $('<div>', {'class': 'slide-wrapper'});
3226
$wrapper.toggle($this.is(':visible'));
3227
$('<a>', {href: '#'+this.id, "class":'ajax'})
3229
.prepend($('<span>'))
3230
.insertBefore($this)
3232
var $wrapper = $this.closest('.slide-wrapper');
3233
var visible = $this.is(':visible');
3237
$this[visible ? 'hide' : 'show']('blind', function() {
3238
$wrapper.toggle(!visible);
3239
PMA_set_status_label($this);
3243
$this.wrap($wrapper);
3244
PMA_set_status_label($this);
3245
$this.data('slider_init_done', 1);
3250
* Initializes slider effect.
3252
AJAX.registerOnload('functions.js', function() {
3257
* Restores sliders to the state they were in before initialisation.
3259
AJAX.registerTeardown('functions.js', function() {
3260
$('div.pma_auto_slider').each(function() {
3261
var $this = $(this);
3263
$this.parent().replaceWith($this);
3264
$this.parent().children('a').remove();
3269
* Creates a message inside an object with a sliding effect
3271
* @param msg A string containing the text to display
3272
* @param $obj a jQuery object containing the reference
3273
* to the element where to put the message
3274
* This is optional, if no element is
3275
* provided, one will be created below the
3276
* navigation links at the top of the page
3278
* @return bool True on success, false on failure
3280
function PMA_slidingMessage(msg, $obj)
3282
if (msg == undefined || msg.length == 0) {
3283
// Don't show an empty message
3286
if ($obj == undefined || ! $obj instanceof jQuery || $obj.length == 0) {
3287
// If the second argument was not supplied,
3288
// we might have to create a new DOM node.
3289
if ($('#PMA_slidingMessage').length == 0) {
3290
$('#page_content').prepend(
3291
'<span id="PMA_slidingMessage" '
3292
+ 'style="display: inline-block;"></span>'
3295
$obj = $('#PMA_slidingMessage');
3297
if ($obj.has('div').length > 0) {
3298
// If there already is a message inside the
3299
// target object, we must get rid of it
3303
.fadeOut(function () {
3308
.append('<div style="display: none;">' + msg + '</div>')
3310
height: $obj.find('div').first().height()
3317
// Object does not already have a message
3318
// inside it, so we simply slide it down
3321
.html('<div style="display: none;">' + msg + '</div>')
3333
// Set the height of the parent
3334
// to the height of the child
3345
} // end PMA_slidingMessage()
3348
* Unbind all event handlers before tearing down a page
3350
AJAX.registerTeardown('functions.js', function() {
3351
$("#drop_tbl_anchor.ajax").die('click');
3352
$("#truncate_tbl_anchor.ajax").die('click');
3355
* Attach Ajax event handlers for Drop Table.
3357
AJAX.registerOnload('functions.js', function() {
3358
$("#drop_tbl_anchor.ajax").live('click', function(event) {
3359
event.preventDefault();
3361
* @var question String containing the question to be asked for confirmation
3363
var question = PMA_messages.strDropTableStrongWarning + ' ';
3364
question += $.sprintf(
3365
PMA_messages.strDoYouReally,
3366
'DROP TABLE ' + PMA_commonParams.get('table')
3369
$(this).PMA_confirm(question, $(this).attr('href'), function(url) {
3371
var $msgbox = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
3372
$.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function(data) {
3373
if (data.success == true) {
3374
PMA_ajaxRemoveMessage($msgbox);
3375
// Table deleted successfully, refresh both the frames
3376
PMA_reloadNavigation();
3377
PMA_commonParams.set('table', '');
3378
PMA_commonActions.refreshMain(
3379
PMA_commonParams.get('opendb_url'),
3381
PMA_ajaxShowMessage(data.message);
3385
PMA_ajaxShowMessage(data.error, false);
3388
}); // end $.PMA_confirm()
3389
}); //end of Drop Table Ajax action
3391
$("#truncate_tbl_anchor.ajax").live('click', function(event) {
3392
event.preventDefault();
3394
* @var question String containing the question to be asked for confirmation
3396
var question = PMA_messages.strTruncateTableStrongWarning + ' ';
3397
question += $.sprintf(
3398
PMA_messages.strDoYouReally,
3399
'TRUNCATE ' + PMA_commonParams.get('table')
3401
$(this).PMA_confirm(question, $(this).attr('href'), function(url) {
3402
PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
3403
$.get(url, {'is_js_confirmed': '1', 'ajax_request': true}, function(data) {
3404
if ($("#sqlqueryresults").length != 0) {
3405
$("#sqlqueryresults").remove();
3407
if ($("#result_query").length != 0) {
3408
$("#result_query").remove();
3410
if (data.success == true) {
3411
PMA_ajaxShowMessage(data.message);
3412
$("<div id='sqlqueryresults'></div>").prependTo("#page_content");
3413
$("#sqlqueryresults").html(data.sql_query);
3415
PMA_ajaxShowMessage(data.error, false);
3418
}); // end $.PMA_confirm()
3419
}); //end of Truncate Table Ajax action
3420
}); // end of $() for Truncate Table
3423
* Attach CodeMirror2 editor to SQL edit area.
3425
AJAX.registerOnload('functions.js', function() {
3426
var $elm = $('#sqlquery');
3427
if ($elm.length > 0) {
3428
if (typeof CodeMirror != 'undefined') {
3430
codemirror_editor = CodeMirror.fromTextArea($elm[0], {
3432
matchBrackets: true,
3434
mode: "text/x-mysql",
3437
codemirror_editor.focus();
3438
$(codemirror_editor.getWrapperElement()).bind(
3440
catchKeypressesFromSqlTextboxes
3443
// without codemirror
3444
$elm.focus().bind('keydown', catchKeypressesFromSqlTextboxes);
3448
AJAX.registerTeardown('functions.js', function() {
3449
if (codemirror_editor) {
3450
$('#sqlquery').text(codemirror_editor.getValue());
3451
codemirror_editor.toTextArea();
3452
codemirror_editor = false;
3457
* jQuery plugin to cancel selection in HTML code.
3460
$.fn.noSelect = function (p) { //no select plugin by Paulo P.Marinas
3461
var prevent = (p == null) ? true : p;
3463
return this.each(function () {
3464
if ($.browser.msie || $.browser.safari) {
3465
$(this).bind('selectstart', function () {
3468
} else if ($.browser.mozilla) {
3469
$(this).css('MozUserSelect', 'none');
3470
$('body').trigger('focus');
3471
} else if ($.browser.opera) {
3472
$(this).bind('mousedown', function () {
3476
$(this).attr('unselectable', 'on');
3480
return this.each(function () {
3481
if ($.browser.msie || $.browser.safari) {
3482
$(this).unbind('selectstart');
3483
} else if ($.browser.mozilla) {
3484
$(this).css('MozUserSelect', 'inherit');
3485
} else if ($.browser.opera) {
3486
$(this).unbind('mousedown');
3488
$(this).removeAttr('unselectable');
3496
* jQuery plugin to correctly filter input fields by value, needed
3497
* because some nasty values may break selector syntax
3500
$.fn.filterByValue = function (value) {
3501
return this.filter(function () {
3502
return $(this).val() === value;
3508
* Create a jQuery UI tooltip
3510
* @param $elements jQuery object representing the elements
3511
* @param item the item
3512
* (see http://api.jqueryui.com/tooltip/#option-items)
3513
* @param myContent content of the tooltip
3514
* @param additionalOptions to override the default options
3517
function PMA_tooltip($elements, item, myContent, additionalOptions)
3519
if ($('#no_hint').length > 0) {
3523
var defaultOptions = {
3526
tooltipClass: "tooltip",
3532
$elements.tooltip($.extend(true, defaultOptions, additionalOptions));
3536
* Return value of a cell in a table.
3538
function PMA_getCellValue(td) {
3540
if ($td.is('.null')) {
3542
} else if (! $td.is('.to_be_saved') && $td.data('original_data')) {
3543
return $td.data('original_data');
3550
* Unbind all event handlers before tearing down a page
3552
AJAX.registerTeardown('functions.js', function() {
3553
$('a.themeselect').die('click');
3554
$('.autosubmit').die('change');
3555
$('a.take_theme').unbind('click');
3558
AJAX.registerOnload('functions.js', function() {
3562
$('a.themeselect').live('click', function(e) {
3566
'left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes'
3572
* Automatic form submission on change.
3574
$('.autosubmit').live('change', function(e) {
3575
$(this).closest('form').submit();
3581
$('a.take_theme').click(function(e) {
3582
var what = this.name;
3583
if (window.opener && window.opener.document.forms['setTheme'].elements['set_theme']) {
3584
window.opener.document.forms['setTheme'].elements['set_theme'].value = what;
3585
window.opener.document.forms['setTheme'].submit();
3594
* Clear text selection
3596
function PMA_clearSelection() {
3597
if (document.selection && document.selection.empty) {
3598
document.selection.empty();
3599
} else if (window.getSelection) {
3600
var sel = window.getSelection();
3604
if (sel.removeAllRanges) {
3605
sel.removeAllRanges();
3613
function escapeHtml(unsafe) {
3615
.replace(/&/g, "&")
3616
.replace(/</g, "<")
3617
.replace(/>/g, ">")
3618
.replace(/"/g, """)
3619
.replace(/'/g, "'");
3625
function printPage()
3627
// Do print the page
3628
if (typeof(window.print) != 'undefined') {
3634
* Unbind all event handlers before tearing down a page
3636
AJAX.registerTeardown('functions.js', function() {
3637
$('input#print').unbind('click');
3638
$('span a.create_view.ajax').die('click');
3639
$('#createViewDialog').find('input, select').die('keydown');
3642
AJAX.registerOnload('functions.js', function() {
3643
$('input#print').click(printPage);
3645
* Ajaxification for the "Create View" action
3647
$('span a.create_view.ajax').live('click', function (e) {
3649
PMA_createViewDialog($(this));
3652
* Attach Ajax event handlers for input fields in the editor
3653
* and used to submit the Ajax request when the ENTER key is pressed.
3655
$('#createViewDialog').find('input, select').live('keydown', function (e) {
3656
if (e.which === 13) { // 13 is the ENTER key
3658
$(this).closest('.ui-dialog').find('.ui-button:first').click();
3663
function PMA_createViewDialog($this)
3665
var $msg = PMA_ajaxShowMessage();
3666
var syntaxHighlighter = null;
3667
$.get($this.attr('href') + '&ajax_request=1', function (data) {
3668
if (data.success == true) {
3669
PMA_ajaxRemoveMessage($msg);
3670
var buttonOptions = {};
3671
buttonOptions[PMA_messages['strGo']] = function () {
3672
if (typeof CodeMirror !== 'undefined') {
3673
syntaxHighlighter.save();
3675
$msg = PMA_ajaxShowMessage();
3676
$.get('view_create.php', $('#createViewDialog').find('form').serialize(), function (data) {
3677
PMA_ajaxRemoveMessage($msg);
3678
if (data.success === true) {
3679
$('#createViewDialog').dialog("close");
3680
$('#result_query').html(data.message);
3681
PMA_reloadNavigation();
3683
PMA_ajaxShowMessage(data.error, false);
3687
buttonOptions[PMA_messages['strClose']] = function () {
3688
$(this).dialog("close");
3690
var $dialog = $('<div/>').attr('id', 'createViewDialog').append(data.message).dialog({
3695
buttons: buttonOptions,
3696
title: $('legend', $(data.message)).html(),
3697
close: function () {
3701
$dialog.find('legend').remove();
3702
// Attach syntax highlited editor
3703
if (typeof CodeMirror !== 'undefined') {
3704
var $elm = $dialog.find('textarea');
3705
var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"};
3706
syntaxHighlighter = CodeMirror.fromTextArea($elm[0], opts);
3708
$('input:visible[type=text]', $dialog).first().focus();
3710
PMA_ajaxShowMessage(data.error);
3716
* Makes the breadcrumbs and the menu bar float at the top of the viewport
3719
if ($("#floating_menubar").length && $('#PMA_disable_floating_menubar').length == 0) {
3720
var left = $('html').attr('dir') == 'ltr' ? 'left' : 'right';
3721
$("#floating_menubar")
3722
.css('margin-' + left, $('#pma_navigation').width() + $('#pma_navigation_resizer').width())
3725
'position': 'fixed',
3730
.append($('#serverinfo'))
3731
.append($('#topmenucontainer'));
3732
// Allow the DOM to render, then adjust the padding on the body
3733
setTimeout(function () {
3736
$('#floating_menubar').outerHeight(true)
3738
$('#topmenu').menuResizer('resize');
3744
* Scrolls the page to the top if clicking the serverinfo bar
3747
$(document).delegate("#serverinfo, #goto_pagetop", "click", function (event) {
3748
event.preventDefault();
3749
$('html, body').animate({scrollTop: 0}, 'fast');
3754
* Watches checkboxes in a form to set the checkall box accordingly
3756
var checkboxes_sel = "input.checkall:checkbox:enabled";
3757
$(checkboxes_sel).live("change", function () {
3758
var $form = $(this.form);
3759
// total number of checkboxes in current form
3760
var total_boxes = $form.find(checkboxes_sel).length;
3761
// number of checkboxes checked in current form
3762
var checked_boxes = $form.find(checkboxes_sel + ":checked").length;
3763
var $checkall = $form.find("input#checkall");
3764
if (total_boxes == checked_boxes) {
3765
$checkall.prop({checked: true, indeterminate: false});
3767
else if (checked_boxes > 0) {
3768
$checkall.prop({checked: true, indeterminate: true});
3771
$checkall.prop({checked: false, indeterminate: false});
3774
$("input#checkall").live("change", function() {
3775
var is_checked = $(this).is(":checked");
3776
$(this.form).find(checkboxes_sel).prop("checked", is_checked)
3777
.parents("tr").toggleClass("marked", is_checked);
3781
* Toggles row colors of a set of 'tr' elements starting from a given element
3783
* @param $start Starting element
3785
function toggleRowColors($start)
3787
for (var $curr_row = $start; $curr_row.length > 0; $curr_row = $curr_row.next()) {
3788
if ($curr_row.hasClass('odd')) {
3789
$curr_row.removeClass('odd').addClass('even');
3790
} else if ($curr_row.hasClass('even')) {
3791
$curr_row.removeClass('even').addClass('odd');
3797
* Formats a byte number to human-readable form
3799
* @param bytes the bytes to format
3800
* @param optional subdecimals the number of digits after the point
3801
* @param optional pointchar the char to use as decimal point
3803
function formatBytes(bytes, subdecimals, pointchar) {
3805
var subdecimals = 0;
3808
var pointchar = '.';
3810
var units = ['B', 'KiB', 'MiB', 'GiB'];
3811
for (var i = 0; bytes > 1024 && i < units.length; i++) {
3814
var factor = Math.pow(10, subdecimals);
3815
bytes = Math.round(bytes * factor) / factor;
3816
bytes = bytes.toString().split('.').join(pointchar);
3817
return bytes + ' ' + units[i];
3820
AJAX.registerOnload('functions.js', function () {
3822
* Opens pma more themes link in themes browser, in new window instead of popup
3823
* This way, we don't break HTML validity
3825
$("a._blank").prop("target", "_blank");
3827
* Reveal the login form to users with JS enabled
3828
* and focus the appropriate input field
3830
var $loginform = $('#loginform');
3831
if ($loginform.length) {
3832
$loginform.find('.js-show').show();
3833
if ($('#input_username').val()) {
3834
$('#input_password').focus();
3836
$('#input_username').focus();
3842
* When user gets an ajax session expiry message, we show a login link
3844
$('a.login-link').live('click', function(e) {
3846
window.location.reload(true);
3850
* Formats timestamp for display
3852
function PMA_formatDateTime(date, seconds) {
3853
var result = $.datepicker.formatDate('yy-mm-dd', date);
3854
var timefmt = 'HH:mm';
3856
timefmt = 'HH:mm:ss';
3858
return result + ' ' + $.datepicker.formatTime(
3860
hour: date.getHours(),
3861
minute: date.getMinutes(),
3862
second: date.getSeconds()