Add support for automatic lookup of foriegn key values in insert/update form fields.
authorxzilla <xzilla>
Fri, 4 Aug 2006 20:42:24 +0000 (20:42 +0000)
committerxzilla <xzilla>
Fri, 4 Aug 2006 20:42:24 +0000 (20:42 +0000)
Adds new config option to control the setting (default on/off, disable)
Patch from John Jawed (with a few go arounds from me) for google soc.
Config version bumped.

aciur.js [new file with mode: 0644]
autocomplete.php [new file with mode: 0644]
classes/database/Postgres.php
conf/config.inc.php-dist
display.php
lang/english.php
lang/recoded/english.php
tables.php
themes/default/global.css

diff --git a/aciur.js b/aciur.js
new file mode 100644 (file)
index 0000000..a817a9a
--- /dev/null
+++ b/aciur.js
@@ -0,0 +1,400 @@
+var nkeycode = 0;
+var curopt = 0;
+var bnsr = false;
+var aSuggests = [];
+var otxb = null;
+var xo = null;
+var acv = false;
+var fac_c = 1;
+var c_fac_c = 1;
+var asg = new Array();
+var rasg = new Array();
+var rasgc = new Array();
+var iMoR = false;
+var g_c_tb = "";
+var g_c_fk = "";
+var g_c_sid = "";
+var g_c_db = "";
+var g_c_v = "";
+var g_i_ac = true;
+
+document.body.onclick=function() {deAC();};
+
+function aS(aSuggests) {
+    if (aSuggests.length > 0) {
+        tA(aSuggests[curopt]);
+    }
+}
+
+function hKU(oEvent) {
+       nkeycode = oEvent.keyCode;
+       var iKeyCode = oEvent.keyCode;
+       if(iKeyCode!=13) {
+               if(iKeyCode==40 && (curopt+1)<=(rasg.length-1)) {
+                       curopt++;
+                       bnsr = true;
+                       tA(rasg[curopt]);
+                       htr(document.getElementById('option_tr_'+(curopt+1)));
+               } else if(iKeyCode==38 && ((curopt-1)<=(rasg.length-1) && (curopt-1)>=0)) {
+                       curopt--;
+                       bnsr = true;
+                       tA(rasg[curopt]);
+                       htr(document.getElementById('option_tr_'+(curopt+1)));
+               } else {
+                       if ( (iKeyCode!=8 && iKeyCode <= 32) || (iKeyCode >= 33 && iKeyCode <= 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
+                       } else {
+                               var sTextboxValue = otxb.value.toLowerCase();
+                               SG1(sTextboxValue);                             
+                               bnsr = false;
+                       }
+               }
+       }
+       else {
+               if(acv) {
+                       hideAC();
+               }
+               return false;
+       }
+}
+
+function initac(tb,fk,sid,db,v) {
+    g_c_tb = tb;
+    g_c_fk = fk;
+    g_c_sid = sid;
+    g_c_db = db;
+}
+
+function sR(p_start,p_len) {
+if(!bnsr) {
+    if (otxb.createTextRange) {
+        var oRange = otxb.createTextRange(); 
+        oRange.moveStart("character", p_start); 
+        oRange.moveEnd("character", p_len - otxb.value.length);
+        oRange.select();
+    } else if (otxb.setSelectionRange) {
+        otxb.setSelectionRange(p_start, p_len);
+    }
+} else {
+       if (otxb.createTextRange) {
+        var oRange = otxb.createTextRange();
+        oRange.moveStart("character",p_len);
+        oRange.moveEnd("character",p_len);
+        oRange.select();
+       } else if (otxb.setSelectionRange) {
+                otxb.setSelectionRange(p_len,p_len);
+       }
+}
+    otxb.focus();
+}
+
+function tA(p_suggestion) {
+       if(nkeycode!=8) {
+               if ((otxb.createTextRange || otxb.setSelectionRange) && p_suggestion) {
+                       var p_len = otxb.value.length; 
+                       otxb.value = p_suggestion; 
+                       sR(p_len, p_suggestion.length);
+               }
+       }
+}
+
+function findPosX(obj)
+{
+       if(obj) {
+               var curleft = 0;
+               if (obj.offsetParent)
+               {
+                       while (obj.offsetParent)
+                       {
+                               curleft += obj.offsetLeft
+                               obj = obj.offsetParent;
+                       }
+               }
+               else if (obj.x)
+                       curleft += obj.x;
+               return curleft;
+       }
+}
+
+function findPosY(obj)
+{
+       if(obj) {
+               var curtop = 0;
+               var n = 0;
+               if (obj.y) {
+                       curtop += obj.y;
+               }
+               else if (obj.offsetParent)
+               {
+                       while (obj.offsetParent)
+                       {
+                               curtop += obj.offsetTop;
+                               obj = obj.offsetParent;
+                       }
+               }
+               return curtop;
+       }
+}
+
+function hideAC() {
+               var d = document.getElementById('ac');
+               d.innerHTML='';
+               d.style.zIndex=0;
+               d.style.border=0;
+               d.style.visibility='hidden';
+               acv = false;
+}
+
+function deAC() {
+       if(acv) {
+               hideAC();
+       }
+}
+
+function makenormaltr(id) {
+       var tr = document.getElementById(id);
+       tr.style.backgroundColor='white';tr.style.color='black';
+}
+
+function fillinval(val) {
+       var tx = document.getElementById('fac' + c_fac_c);
+       tx.value=val;
+       hideAC();
+}
+
+function showAC() {
+       var d = document.getElementById('ac');
+       d.innerHTML='';
+       var tb = document.getElementById('fac'+c_fac_c+'_ph');
+       d.style.top=findPosY(tb)+'px';
+       d.style.visibility='visible';
+       acv = true;
+       d.style.left=findPosX(tb)+'px';
+       d.style.border='1px solid black';
+       d.style.position='absolute';
+       d.style.width=(document.getElementById('aciwp' + c_fac_c).offsetWidth-3) + "px";
+       d.style.zIndex=20;
+       d.style.backgroundColor='white';
+       d.style.margin='0px';
+       d.style.padding='0px';
+       d.style.textAlign='left';
+       document.getElementById("ac_form").onsubmit=function(){return false;};
+       return d;
+}
+
+function aftr() {
+       for(i=0;i<rasg.length;i++) {
+               ftr(document.getElementById('option_tr_'+(i+1)));
+       }
+}
+
+function htr(obj) {
+       aftr();
+       obj.style.backgroundColor='#3d80df';
+       obj.style.color='white';
+}
+
+function ftr(obj) {
+       obj.style.backgroundColor='white';
+       obj.style.color='black'; 
+}
+
+function buildSelectOptions() {
+       if(rasg.length>0) {
+       var t = document.createElement('table');
+       var tb = document.createElement('tbody');
+       var d = showAC();
+       t.style.width='100%';
+       t.style.margin='0px';
+       t.style.padding='0px';
+       t.cellPadding='0px';
+       t.cellSpacing='0px';
+       t.style.zIndex=6;
+       t.style.visibility='visible';
+       for(i=0;i<rasg.length;i++) {
+               var tr = document.createElement('tr');
+               var td = document.createElement('td');
+               var tx = document.createTextNode(rasg[i]);
+               if(i==0) {
+                       td.style.color='white';
+                       td.id='option_tr_1';
+                       td.style.backgroundColor='#3d80df';
+               } else {
+                       td.id='option_tr_' + (i+1);
+                       td.style.color='black';
+                       td.style.backgroundColor='white';
+               }
+               td.onmouseover=function() { htr(this); this.style.cursor='pointer'; };
+               td.onmouseout=function() { ftr(this); this.style.cursor='normal'; };
+               td.onclick=function() { fillinval(this.firstChild.innerHTML); };
+               td.style.paddingLeft='10px';
+               td.style.fontSize='9pt';
+               td.style.fontFamily='Arial';
+               td.appendChild(tx);
+               tr.appendChild(td);
+               tb.appendChild(tr);
+       }
+       t.appendChild(tb);
+       d.appendChild(t);
+       } else {
+               hideAC();
+       }
+}
+
+function dF(v) {
+       g_i_ac = document.getElementById(v).checked;
+}
+
+function makeAC(tx,n,tb,fk,sid,db) {
+       otxb = document.getElementById(tx);
+       c_fac_c = n;
+       if(document.getElementById('no_ac').checked) {
+               if(acv) {
+                       hideAC();
+               }
+               otxb = document.getElementById(tx);
+               v = otxb.value;
+               curopt = 0;
+               bnsr = false;
+               otxb.onkeyup = function (oEvent) {
+               if (!oEvent) { oEvent = window.event; } hKU(oEvent); };
+               initac(tb,fk,sid,db,v);
+       } else {
+               otxb.onkeyup = function() {};
+       }
+}
+
+function gfacc(s) {
+       return s.substr(3);
+}
+
+function iA(parent, node, referenceNode) {
+    parent.insertBefore(node, referenceNode.nextSibling);
+}
+var asg = new Array();
+var rasg = new Array();
+var rasgc = new Array();
+
+function rS(tx) {
+    rasg = [];
+    rasgc = [];
+    var sTextboxValue = otxb.value.toLowerCase(); 
+    if (sTextboxValue.length > 0) {
+        for (var i=0;i<asg.length;i++) { 
+       var c = asg[i];
+            if (c.indexOf(sTextboxValue) == 0) {
+                rasg.push(asg[i]);
+            }
+        }
+       buildSelectOptions();
+    } else {
+               hideAC();
+       }
+}
+
+function SG1(s) {
+       if(!iMoR && s.length>0) {
+               pr("autocomplete.php","tb="+g_c_tb+"&database="+g_c_db+"&server="+g_c_sid+"&fk="+g_c_fk+"&v="+escapeHTML(s)+"");
+       } else if(!s.length) {
+               hideAC();
+       }
+}
+
+function escapeHTML(s) {
+       s = escape(s);
+       s = s.replace(/\//g,"%2F");
+       s = s.replace(/\?/g,"%3F");
+       s = s.replace(/=/g,"%3D");
+       s = s.replace(/&/g,"%26");
+       s = s.replace(/@/g,"%40");
+       return s;
+}
+
+function rEB(v) {
+       var il = document.getElementsByTagName('input');
+       for(i in il) {
+               if(il[i].className=='ac_field' || il[i].className=='normal_field') {
+                       if(v==false) {
+                               il[i].className='normal_field';
+                               il[i].setAttribute("autocomplete",'on');
+                       } else {
+                               il[i].className='ac_field';
+                               il[i].setAttribute("autocomplete",'off');
+                       }
+               }
+       }
+}
+
+function pgsg(v) {
+       prgsp(v);
+}
+
+function prgsp(v) {
+       var d = v.split("PPA_EOF;|"); // pondered using RegExp here, but overhead to gain ratio is not convincing
+       var l = d.length;
+       asg = [];
+       for(i=0;i<l;i++) {
+               asg.push(d[i]);
+       }
+       rS(otxb);
+       aS(rasg);
+}
+
+function rS(tx) {
+    rasg = [];
+    rasgc = [];
+    var sTextboxValue = otxb.value.toLowerCase(); 
+    if (sTextboxValue.length > 0) {
+        for (var i=0;i<asg.length;i++) { 
+       var c = asg[i];
+            if (c.indexOf(sTextboxValue) == 0) {
+                rasg.push(asg[i]);
+            }
+        }
+       buildSelectOptions();
+    } else {
+               hideAC();
+       }
+}
+
+function pr(pg,sr) {
+        mii();
+        xo.open("POST",pg,true);
+        xo.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+        xo.onreadystatechange=xoc;
+        xo.send(sr);
+}
+
+function mii() {
+        if(!xo) {
+                /*@cc_on @*//*@if (@_jscript_version >= 5) try {
+                xo = new ActiveXObject("Msxml2.XMLHTTP");
+                }
+                catch (e) {
+                try {
+                xo = new ActiveXObject("Microsoft.XMLHTTP");
+                }
+                catch (E) {
+                xo = false;
+                }
+                }
+                @end @*/if (!xo && typeof XMLHttpRequest!='undefined') {
+                xo = new XMLHttpRequest();
+                }
+        }
+}
+
+function xoc(){
+        iMoR = true;
+        szr = "";
+        if (xo.readyState==4) {
+                if(xo.status==200) {
+                       pgsg(xo.responseText);
+                        iMoR = false;
+                }
+                else {
+                        alert("Oops, something unexpected happened, try again");
+                        window.location.reload();
+                }
+        }
+}
+
diff --git a/autocomplete.php b/autocomplete.php
new file mode 100644 (file)
index 0000000..983a9c6
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+include_once("libraries/lib.inc.php");
+$szSQL = "select * from ". $data->clean($_REQUEST["tb"]) ." where ". $data->clean($_REQUEST["fk"]) ." LIKE '". $data->clean($_REQUEST["v"]) ."%' LIMIT 11";
+$objRes = $data->selectSet($szSQL);
+$arrayRes = array();
+while(!$objRes->EOF) {
+       $arrayRes[] = $objRes->fields[$_REQUEST["fk"]];
+       $objRes->moveNext();
+}
+echo implode("PPA_EOF;|",$arrayRes);
+?>
index fc6db6135c650977c8913e932acb617b1228ebb8..b58a850ddbe6e9c73d2d831d9285ad185509ba7b 100755 (executable)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres.php,v 1.286 2006/06/20 14:06:09 xzilla Exp $
+ * $Id: Postgres.php,v 1.287 2006/08/04 20:42:24 xzilla Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -266,7 +266,7 @@ class Postgres extends ADODB_base {
         * @param $type The database type of the field
         * @param $actions An array of javascript action name to the code to execute on that action
         */
-       function printField($name, $value, $type, $actions = array()) {
+       function printField($name, $value, $type, $actions = array(),$szExtra="") {
                global $lang;
                
                // Determine actions string
@@ -291,7 +291,7 @@ class Postgres extends ADODB_base {
                                        echo "</select>\n";
                                }
                                else {
-                                       echo "<input name=\"", htmlspecialchars($name), "\" value=\"", htmlspecialchars($value), "\" size=\"35\"{$action_str} />\n";
+                                       echo "<input name=\"", htmlspecialchars($name), "\" value=\"", htmlspecialchars($value), "\" size=\"35\"{$action_str} {$szExtra} />\n";
                                }                               
                                break;
                        case 'bytea':
@@ -316,7 +316,7 @@ class Postgres extends ADODB_base {
                                echo "</textarea>\n";
                                break;
                        default:
-                               echo "<input name=\"", htmlspecialchars($name), "\" value=\"", htmlspecialchars($value), "\" size=\"35\"{$action_str} />\n";
+                               echo "<input name=\"", htmlspecialchars($name), "\" value=\"", htmlspecialchars($value), "\" size=\"35\"{$action_str} {$szExtra} />\n";
                                break;
                }               
        }
index 65a67693128cfa483054ac0c4c44096dc3c8268e..da955e8d0c8fb46111fa295c176ae47e8e2d5c4d 100644 (file)
@@ -4,7 +4,7 @@
         * Central phpPgAdmin configuration.  As a user you may modify the
         * settings here for your particular configuration.
         *
-        * $Id: config.inc.php-dist,v 1.48 2006/05/22 17:31:23 xzilla Exp $
+        * $Id: config.inc.php-dist,v 1.49 2006/08/04 20:42:24 xzilla Exp $
         */
 
        // An example server.  Create as many of these as you wish,
        // for all possibilities. If you specify 'auto' (the default) it will use 
        // your browser preference.
        $conf['default_lang'] = 'auto';
+
+       // AutoComplete uses ajaxy interaction to list FK options on insert fields
+    // It currently only works on single column foreign keys. You can control
+       // it's behavior with the following settings.  
+       // 'default on' enables AutoComplete and turns it on by default.
+       // 'default off' enables AutoComplete but turns it off by default.
+       // 'disable' disables AutoComplete.
+       $conf['autocomplete'] = 'default on';
        
        // If extra login security is true, then logins via phpPgAdmin with no
        // password or certain usernames (pgsql, postgres, root, administrator)
         * Don't modify anything below this line *
         *****************************************/
 
-       $conf['version'] = 16;
+       $conf['version'] = 17;
 
 ?>
index f3dad375cbb7ad0564bbe4bf67ab6fdf212113cc..49a5dde39c86bf2e0926db814bbe45597a3a89fd 100644 (file)
@@ -9,7 +9,7 @@
         * @param $return_desc The return link name
         * @param $page The current page
         *
-        * $Id: display.php,v 1.54 2006/06/21 18:02:52 xzilla Exp $
+        * $Id: display.php,v 1.55 2006/08/04 20:42:24 xzilla Exp $
         */
 
        // Prevent timeouts on large exports (non-safe mode only)
@@ -27,7 +27,7 @@
         * Show confirmation of edit and perform actual update
         */
        function doEditRow($confirm, $msg = '') {
-               global $data, $misc;
+               global $data, $misc, $conf;
                global $lang;
                global $PHP_SELF;
 
                        $misc->printTitle($lang['streditrow']);
                        $misc->printMsg($msg);
 
+                       $bAllowAC = ($conf["autocomplete"]!='disable') ? TRUE : FALSE ;
+                       if($bAllowAC) {
+                               $constraints = $data->getConstraints($_REQUEST['table']);
+                               $arrayLocals = array();
+                               $arrayRefs = array();
+                               $nC = 0;
+                               // A word of caution, the following does not support multicolumn FK's at the moment
+                               while(!$constraints->EOF) {
+                                       preg_match('/foreign key \((\w+)\) references ([\w]+)\((\w+)\)/i',$constraints->fields["consrc"],$matches);
+                                       if(!empty($matches)) {
+                                               $arrayLocals[$nC] = $matches[1];
+                                               $arrayRefs[$nC] = array($matches[2],$matches[3]);
+                                               $nC++;
+                                       }
+                                       $constraints->moveNext();
+                               }
+                       }
+
                        $attrs = $data->getTableAttributes($_REQUEST['table']);
                        $rs = $data->browseRow($_REQUEST['table'], $key);
-
-                       echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       
+                       echo "<form action=\"$PHP_SELF\" method=\"post\" id=\"ac_form\">\n";
                        $elements = 0;
                        $error = true;                  
                        if ($rs->recordCount() == 1 && $attrs->recordCount() > 0) {
                                echo "<th class=\"data\">{$lang['strnull']}</th><th class=\"data\">{$lang['strvalue']}</th></tr>";
 
                                $i = 0;
+                               $nCC = 0;
                                while (!$attrs->EOF) {
+                                       $szValueName = "values[{$attrs->f['attname']}]";
+                                       $szEvents = "";
+                                       $szDivPH = "";
+                                       if($bAllowAC) {
+                                               if(($idxFound = array_search($attrs->f['attname'],$arrayLocals))!==false) {
+                                                       $szEvent = "makeAC('{$szValueName}',{$i},'{$arrayRefs[$idxFound][0]}','{$arrayRefs[$idxFound][1]}','{$_REQUEST["server"]}','{$_REQUEST["database"]}');";
+                                                       $szEvents = "onfocus=\"{$szEvent}\" onblur=\"hideAC();document.getElementById('ac_form').onsubmit=function(){return true;};\" onchange=\"{$szEvent}\" id=\"{$szValueName}\" onkeyup=\"{$szEvent}\" autocomplete=\"off\" class='ac_field'";
+                                                       $szDivPH = "<div id=\"fac{$i}_ph\"></div>";
+                                               }
+                                       }
                                        $attrs->f['attnotnull'] = $data->phpBool($attrs->f['attnotnull']);
                                        $id = (($i % 2) == 0 ? '1' : '2');
                                        
                                        else
                                                echo "&nbsp;</td>";
 
-                                       echo "<td class=\"data{$id}\" nowrap>";
+                                       echo "<td class=\"data{$id}\" id=\"aciwp{$i}\" nowrap=\"nowrap\">";
                                        // If the column allows nulls, then we put a JavaScript action on the data field to unset the
                                        // NULL checkbox as soon as anything is entered in the field.  We use the $elements variable to 
                                        // keep track of which element offset we're up to.  We can't refer to the null checkbox by name
                                        // as it contains '[' and ']' characters.
-                                       if (!$attrs->f['attnotnull'])
-                                               echo $data->printField("values[{$attrs->f['attname']}]", $rs->f[$attrs->f['attname']], $attrs->f['type'], 
-                                                                                                       array('onChange' => 'elements[' . ($elements - 1) . '].checked = false;'));
-                                       else
-                                               echo $data->printField("values[{$attrs->f['attname']}]", $rs->f[$attrs->f['attname']], $attrs->f['type']);
+                                       if (!$attrs->f['attnotnull']) {
+                                               echo $data->printField($szValueName, $rs->f[$attrs->f['attname']], $attrs->f['type'], 
+                                                                                                       array('onChange' => 'elements[' . ($elements - 1) . '].checked = false;'),$szEvents) . $szDivPH;
+                                       }
+                                       else {
+                                               echo $data->printField($szValueName, $rs->f[$attrs->f['attname']], $attrs->f['type'],array(),$szEvents) . $szDivPH;
+                                       }
                                        echo "</td>";
                                        $elements++;
                                        echo "</tr>\n";
                                        $attrs->moveNext();
                                }
                                echo "</table>\n";
+                               if($bAllowAC) {
+                                       echo '<script src="aciur.js" type="text/javascript"></script>';
+                                       echo "<div id=\"ac\"></div>";
+                               }
                                $error = false;
                        }
                        elseif ($rs->recordCount() != 1) {
                        echo "<input type=\"hidden\" name=\"key\" value=\"", htmlspecialchars(serialize($key)), "\" />\n";
                        echo "<p>";
                        if (!$error) echo "<input type=\"submit\" name=\"save\" value=\"{$lang['strsave']}\" />\n";
-                       echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
+                       echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n";
+                       if($bAllowAC) {
+                               $szChecked = $conf["autocomplete"]!='default off' ? "checked=\"checked\"" : "";
+                               echo "<input type=\"checkbox\" name=\"no_ac\" id=\"no_ac\" onclick=\"rEB(this.checked);\" value=\"1\" {$szChecked} /><label for='no_ac' onmouseover='this.style.cursor=\"pointer\";'>{$lang['strac']}</label>\n";
+                       }
+                       echo "</p>\n";
                        echo "</form>\n";
+                       echo "<script>rEB(document.getElementById('no_ac').checked);</script>";
                }
                else {
                        if (!isset($_POST['values'])) $_POST['values'] = array();
index 9fadc28d720eaae589ed51c038be34e377f66aae..41892843d318f77e01db4002686dc4b68b12c427 100755 (executable)
@@ -4,7 +4,7 @@
         * English language file for phpPgAdmin.  Use this as a basis
         * for new translations.
         *
-        * $Id: english.php,v 1.192 2006/08/03 19:03:33 xzilla Exp $
+        * $Id: english.php,v 1.193 2006/08/04 20:42:24 xzilla Exp $
         */
 
        // Language and character set
@@ -58,6 +58,7 @@
        $lang['stralter'] = 'Alter';
        $lang['strok'] = 'OK';
        $lang['strcancel'] = 'Cancel';
+       $lang['strac'] = 'Enable AutoComplete';
        $lang['strsave'] = 'Save';
        $lang['strreset'] = 'Reset';
        $lang['strinsert'] = 'Insert';
index fabd2d8e09555fa8cddd08bbc7e544e41f18a7b0..56678c46cdd37ef50abdf9a322b873baba20a83b 100644 (file)
@@ -4,7 +4,7 @@
         * English language file for phpPgAdmin.  Use this as a basis
         * for new translations.
         *
-        * $Id: english.php,v 1.145 2006/08/03 19:03:33 xzilla Exp $
+        * $Id: english.php,v 1.146 2006/08/04 20:42:24 xzilla Exp $
         */
 
        // Language and character set
@@ -58,6 +58,7 @@
        $lang['stralter'] = 'Alter';
        $lang['strok'] = 'OK';
        $lang['strcancel'] = 'Cancel';
+       $lang['strac'] = 'Enable AutoComplete';
        $lang['strsave'] = 'Save';
        $lang['strreset'] = 'Reset';
        $lang['strinsert'] = 'Insert';
index b7314b8bf709726ca4828e5d5302edf059fa6ad8..866609a2f822f88198890fb9fa68b55240e1c19d 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * List tables in a database
         *
-        * $Id: tables.php,v 1.80 2006/06/29 18:22:33 xzilla Exp $
+        * $Id: tables.php,v 1.81 2006/08/04 20:42:24 xzilla Exp $
         */
 
        // Include application functions
         * Ask for insert parameters and then actually insert row
         */
        function doInsertRow($confirm, $msg = '') {
-               global $data, $misc;
+               global $data, $misc, $conf;
                global $lang;
                global $PHP_SELF;
 
+               $bAllowAC = ($conf["autocomplete"]!='disable') ? TRUE : FALSE ;
+
                if ($confirm) {
                        $misc->printTrail('table');
                        $misc->printTitle($lang['strinsertrow'], 'pg.sql.insert');
                        $misc->printMsg($msg);
 
                        $attrs = $data->getTableAttributes($_REQUEST['table']);
+                       if($bAllowAC) {
+                               $constraints = $data->getConstraints($_REQUEST['table']);
+                               $arrayLocals = array();
+                               $arrayRefs = array();
+                               $nC = 0;
+                               // A word of caution, the following does not support multicolumn FK's at the moment
+                               while(!$constraints->EOF) {
+                                       preg_match('/foreign key \((\w+)\) references ([\w]+)\((\w+)\)/i',$constraints->fields["consrc"],$matches);
+                                       if(!empty($matches)) {
+                                               $arrayLocals[$nC] = $matches[1];
+                                               $arrayRefs[$nC] = array($matches[2],$matches[3]);
+                                               $nC++;
+                                       }
+                                       $constraints->moveNext();
+                               }
+                       }
 
-                       echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo "<form action=\"$PHP_SELF\" method=\"post\" id=\"ac_form\">\n";
                        if ($attrs->recordCount() > 0) {
                                echo "<table>\n";
 
                                
                                $i = 0;
                                while (!$attrs->EOF) {
+                                       $szValueName = "values[{$attrs->f['attname']}]";
+                                       $szEvents = "";
+                                       $szDivPH = "";
+                                       if($bAllowAC) {
+                                               if(($idxFound = array_search($attrs->f['attname'],$arrayLocals))!==false) {
+                                                       $szEvent = "makeAC('{$szValueName}',{$i},'{$arrayRefs[$idxFound][0]}','{$arrayRefs[$idxFound][1]}','{$_REQUEST["server"]}','{$_REQUEST["database"]}');";
+                                                       $szEvents = "onfocus=\"{$szEvent}\" onblur=\"hideAC();document.getElementById('ac_form').onsubmit=function(){return true;};\" onchange=\"{$szEvent}\" id=\"{$szValueName}\" onkeyup=\"{$szEvent}\" autocomplete=\"off\" class='ac_field'";
+                                                       $szDivPH = "<div id=\"fac{$i}_ph\"></div>";
+                                               }
+                                       }
                                        $attrs->f['attnotnull'] = $data->phpBool($attrs->f['attnotnull']);
                                        // Set up default value if there isn't one already
                                        if (!isset($_REQUEST['values'][$attrs->f['attname']]))
                                        echo "</select>\n</td>\n";
                                        echo "<td class=\"data{$id}\" nowrap=\"nowrap\">";
                                        // Output null box if the column allows nulls (doesn't look at CHECKs or ASSERTIONS)
-                                       if (!$attrs->f['attnotnull'])
+                                       if (!$attrs->f['attnotnull']) {
                                                echo "<input type=\"checkbox\" name=\"nulls[", htmlspecialchars($attrs->f['attname']), "]\"",
                                                        isset($_REQUEST['nulls'][$attrs->f['attname']]) ? ' checked="checked"' : '', " /></td>";
-                                       else
+                                       }
+                                       else {
                                                echo "&nbsp;</td>";
-                                       echo "<td class=\"data{$id}\" nowrap=\"nowrap\">", $data->printField("values[{$attrs->f['attname']}]",
-                                               $_REQUEST['values'][$attrs->f['attname']], $attrs->f['type']), "</td>";
+                                       }
+                                       echo "<td class=\"data{$id}\" id=\"aciwp{$i}\" nowrap=\"nowrap\">", $data->printField($szValueName,
+                                       $_REQUEST['values'][$attrs->f['attname']], $attrs->f['type'],array(),$szEvents),$szDivPH ,"</td>";
                                        echo "</tr>\n";
                                        $i++;
                                        $attrs->moveNext();
                                }
                                echo "</table>\n";
+                               if($bAllowAC) {
+                                       echo '<script src="aciur.js" type="text/javascript"></script>';
+                                       echo "<div id=\"ac\"></div>";
+                               }
                        }
                        else echo "<p>{$lang['strnodata']}</p>\n";
                        
                        echo $misc->form;
                        echo "<p><input type=\"submit\" name=\"insert\" value=\"{$lang['strinsert']}\" />\n";
                        echo "<input type=\"submit\" name=\"insertandrepeat\" value=\"{$lang['strinsertandrepeat']}\" />\n";
-                       echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
+                       echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n";
+                       if($bAllowAC) {
+                               $szChecked = $conf["autocomplete"]!='default off' ? "checked=\"checked\"" : "";
+                               echo "<input type=\"checkbox\" name=\"no_ac\" id=\"no_ac\" onclick=\"rEB(this.checked);\" value=\"1\" {$szChecked} /><label for='no_ac' onmouseover='this.style.cursor=\"pointer\";'>{$lang['strac']}</label>\n";
+                       }
+                       echo "</p>\n";
                        echo "</form>\n";
+                       echo "<script>rEB(document.getElementById('no_ac').checked);</script>";
                }
                else {
                        if (!isset($_POST['values'])) $_POST['values'] = array();
index 1db64eb3ae6d5f1972704e3b4e9644b7a29cdcd4..3664bfa9420ab5bb58012700869ea05e3a2cfe12 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Default style sheet
  *
- * $Id: global.css,v 1.38 2006/07/25 18:58:10 xzilla Exp $
+ * $Id: global.css,v 1.39 2006/08/04 20:42:24 xzilla Exp $
  */
 
 /** ELEMENTS */
@@ -387,3 +387,10 @@ pre.data
 .arg_tr_pc {
 
 }
+
+.ac_field {
+border:1px solid #D9D95F;
+}
+
+.normal_field {
+}