Changeset 4251
- Timestamp:
- Apr 28, 2008, 10:48:05 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/clients/web/net/sf/basedb/clients/web/taglib/table/ColumnDef.java
r4250 r4251 630 630 if (getEnumeration() != null) 631 631 { 632 String filterValue = filter == null ? "" : Base.getPropertyFilterString(filter, dateFormatter);632 String filterValue = filter == null ? "" : HTML.encodeTags(Base.getPropertyFilterString(filter, dateFormatter)); 633 633 if (smartEnum || isAnnotation) 634 634 { … … 639 639 sb.append(" value=\"").append(filterValue).append("\""); 640 640 sb.append(">"); 641 sb.append("<img class=\"smartimage\" src=\"").append(table.getPage().getRoot()).append("images/ dropdown.png\"");641 sb.append("<img class=\"smartimage\" src=\"").append(table.getPage().getRoot()).append("images/pull_down.gif\""); 642 642 sb.append(" onclick=\"SmartEnum.activateAndDisplay('"); 643 643 sb.append(table.getId()).append("','").append(inputName).append("')\">"); -
trunk/www/include/scripts/main.js
r4250 r4251 1291 1291 } 1292 1292 1293 } 1294 1295 var SmartEnum = new SmartEnumClass(); 1296 /* 1297 Handles "smart" input fields which can have an attached list of 1298 enumeration options. As the user types a popup-list is displayed 1299 with the matching options. 1300 */ 1301 function SmartEnumClass() 1302 { 1303 this.initialDelay = 300; 1304 this.repeatDelay = 50; 1305 1306 this.activeField = null; 1307 this.selected = -1; 1308 this.lastSelected = null; 1309 this.lastText = ''; 1310 1311 /* 1312 Initialise the smart enum system by creating the <div> tag that 1313 is used to hold the options. 1314 */ 1315 this.init = function() 1316 { 1317 if (this.div) return; 1318 var div = document.createElement('div'); 1319 div.className = 'smartenum'; 1320 div.style.display = 'none'; 1321 document.body.appendChild(div); 1322 this.div = div; 1323 this.debug = document.createElement('div'); 1324 document.body.appendChild(this.debug); 1325 } 1326 1327 /* 1328 Enable the input field for smart enum. Ignored if 1329 the form or field doesn't exists, the field is not an 1330 input field or if there are no options. This method 1331 changes event handlers for the input field. 1332 @param frmName The name of the form 1333 @param fieldName The name of the field 1334 @param An array object with the options 1335 */ 1336 this.enableForField = function(frmName, fieldName, options) 1337 { 1338 if (!options) return; 1339 var frm = document.forms[frmName]; 1340 if (!frm) return; 1341 var field = frm[fieldName]; 1342 if (!field) return; 1343 1344 this.init(); 1345 field.smartOptions = options; 1346 field.setAttribute('autocomplete', 'off'); 1347 Main.addClass(field, 'smartinput'); 1348 field.onfocus = this.onfocus; 1349 field.onkeyup = this.onkeyup; 1350 field.onkeydown = this.onkeydown; 1351 field.onblur = this.onblur; 1352 } 1353 1354 this.activateAndDisplay = function(formName, fieldName) 1355 { 1356 var frm = document.forms[formName]; 1357 if (!frm) return; 1358 var field = frm[fieldName]; 1359 if (!field) return; 1360 1361 if (this.blurTimerId) 1362 { 1363 clearTimeout(this.blurTimerId); 1364 this.blurTimerId = null; 1365 } 1366 this.setActive(field); 1367 this.filterOptions(true); 1368 this.showOptions(); 1369 var oldfocus = field.onfocus; 1370 field.onfocus = null; 1371 field.focus(); 1372 field.onfocus = oldFocus; 1373 } 1374 1375 /* 1376 Set a field as the active field. All other operations will 1377 now use this field. Set to null to disable all smart enum. 1378 Ignored if the field doesn't have any options. This method 1379 also positions the <div> with the options. 1380 */ 1381 this.setActive = function(field) 1382 { 1383 if (!field || !field.smartOptions) return; 1384 this.activeField = field; 1385 var pos = Main.getElementPosition(this.activeField); 1386 var div = this.div; 1387 div.style.top = (pos.top + this.activeField.offsetHeight) + 'px'; 1388 div.style.left = (pos.left-2) + 'px'; 1389 div.style.width = (this.activeField.offsetWidth + 10) + 'px'; 1390 } 1391 1392 /* 1393 Hide the enum options. 1394 */ 1395 this.hideOptions = function() 1396 { 1397 this.div.style.display = 'none'; 1398 } 1399 1400 /* 1401 Show the enum options setting the correct position. 1402 */ 1403 this.showOptions = function() 1404 { 1405 this.div.style.display = 'block'; 1406 } 1407 1408 /* 1409 Filter the enum options by the text in the active field. 1410 The options that passed the filter are added as <div> tags 1411 to the enum <div>. 1412 @return TRUE if the filter generated any options, FALSE otherwise 1413 */ 1414 this.filterOptions = function(allowEmpty) 1415 { 1416 if (!this.activeField) return false; 1417 var text = this.activeField.value.replace(/^[=!<>]*/, ''); 1418 if (text == this.lastMatchedText) return true; 1419 if (text == '' && !allowEmpty) return false; 1420 1421 var options = this.activeField.smartOptions; 1422 this.lastMatchedText = text; 1423 this.selected = -1; 1424 this.lastSelected = null; 1425 var matching = ''; 1426 var index = 0; 1427 for (var i = 0; i < options.length; i++) 1428 { 1429 if (options[i].indexOf(text) >= 0) 1430 { 1431 matching += '<div class="smartoption" id="smartoption.' + index + '"'; 1432 matching += ' onmouseover="SmartEnum.setSelectedOption(' + index + ')"'; 1433 matching += ' onclick="SmartEnum.submitSelected()">' + options[i] + '</div>'; 1434 index++; 1435 } 1436 } 1437 this.div.innerHTML = matching; 1438 return true; 1439 } 1440 1441 /* 1442 Mark a specific enum option as selected. Also makes sure 1443 that the selected option is within the viewable area. 1444 @param index The index of the option 1445 */ 1446 this.setSelectedOption = function(index) 1447 { 1448 if (this.lastSelected) 1449 { 1450 Main.removeClass(this.lastSelected, 'selected'); 1451 this.lastSelected = null; 1452 } 1453 var option = document.getElementById('smartoption.' + index); 1454 if (option) 1455 { 1456 Main.addClass(option, 'selected'); 1457 this.lastSelected = option; 1458 this.selected = index; 1459 var optionTop = option.offsetTop; 1460 var optionBottom = optionTop + option.offsetHeight; 1461 var parent = option.offsetParent; 1462 var parentTop = parent.scrollTop; 1463 var parentBottom = parentTop + parent.offsetHeight; 1464 if (optionTop < parentTop) 1465 { 1466 parent.scrollTop = optionTop; 1467 } 1468 else if (optionBottom > parentBottom) 1469 { 1470 parent.scrollTop = optionBottom - parent.offsetHeight; 1471 } 1472 } 1473 } 1474 1475 /* 1476 Moves the selection up or down, optionally 1477 repeating the operation at specified time intervals. 1478 @param delta The number of options to shift the selection 1479 @param delayRepeat Number of milliseconds to wait until 1480 the move is repeated for the first time 1481 @param repeat Number of milliseconds to wait between 1482 subsequent repeats 1483 */ 1484 this.moveSelection = function(delta, delayRepeat, repeat) 1485 { 1486 var option = document.getElementById('smartoption.' + (this.selected + delta)); 1487 if (option) 1488 { 1489 this.setSelectedOption(this.selected + delta); 1490 } 1491 if (delayRepeat && repeat) 1492 { 1493 var call = 'SmartEnum.moveSelection(' + delta + ',' + repeat + ',' + repeat + ')'; 1494 this.timerId = setTimeout(call, delayRepeat); 1495 } 1496 } 1497 1498 /* 1499 Copies the selected option to the active field and submits 1500 the form. If no option is selected, just submit the form. 1501 */ 1502 this.submitSelected = function(event) 1503 { 1504 if (!this.activeField) return; 1505 if (this.lastSelected) 1506 { 1507 var text = this.activeField.value; 1508 var selectedText = this.lastSelected.innerHTML; 1509 this.activeField.value = text.replace(/^([=!<>]*).*/, '$1' + selectedText); 1510 } 1511 this.activeField.form.submit(); 1512 } 1513 1514 /* 1515 Cancels a move selection repeat set in the 'moveSelection' method. 1516 */ 1517 this.cancelKeyRepeat = function() 1518 { 1519 if (this.timerId) 1520 { 1521 clearTimeout(this.timerId); 1522 this.timerId = null; 1523 } 1524 } 1525 1526 /* 1527 Called when a smart-enum enabled field receivs 1528 the focus. This should set the current field to 1529 the active field. 1530 */ 1531 this.onfocus = function(event) 1532 { 1533 if (!event) event = window.event; 1534 var field = Main.getEventTarget(event); 1535 SmartEnum.setActive(field); 1536 } 1537 1538 /* 1539 Called when a smart-enum enabled field loses 1540 the focus. This should hide the options and 1541 set the current field to null. 1542 */ 1543 this.onblur = function(event) 1544 { 1545 if (!event) event = window.event; 1546 // Need timout, otherwise the options are hidden and can't receive 1547 // a possible mouseclick that selects an options and submits the form. 1548 SmartEnum.blurTimerId = setTimeout('SmartEnum.hideOptions(); SmartEnum.setActive(null);', 100); 1549 } 1550 1551 /* 1552 Called when a key is pressed in a smart-enum enabled field. 1553 This function detects: 1554 * up/down arrow: moves the selected option 1555 * enter: submits the form 1556 */ 1557 this.onkeydown = function(event) 1558 { 1559 if (!event) event = window.event; 1560 var charCode = Main.getEventCharCode(event); 1561 if (charCode == 38) 1562 { 1563 // Up arrow 1564 SmartEnum.moveSelection(-1, SmartEnum.initialDelay, SmartEnum.repeatDelay); 1565 } 1566 else if (charCode == 40) 1567 { 1568 // Down arrow 1569 SmartEnum.moveSelection(1, SmartEnum.initialDelay, SmartEnum.repeatDelay); 1570 } 1571 else if (charCode == 13) 1572 { 1573 // Enter 1574 SmartEnum.submitSelected(event); 1575 } 1576 } 1577 1578 /* 1579 Called when a key is released in a smart-enum enabled field. 1580 This function detects changes to the text and displays matching 1581 options. 1582 */ 1583 this.onkeyup = function(event) 1584 { 1585 if (!event) event = window.event; 1586 SmartEnum.cancelKeyRepeat(); 1587 var charCode = Main.getEventCharCode(event); 1588 if (SmartEnum.filterOptions(charCode == 40 || charCode == 38)) 1589 { 1590 SmartEnum.showOptions(); 1591 } 1592 else 1593 { 1594 SmartEnum.hideOptions(); 1595 } 1596 } 1597 1293 /** 1294 Compare two strings ignoreing case. 1295 returns -1 if a<b, +1 if a>b, 0 if a==b 1296 */ 1297 this.compareIgnoreCase = function(a, b) 1298 { 1299 var lcA = a.toLowerCase(); 1300 var lcB = b.toLowerCase(); 1301 if (lcA < lcB) return -1; 1302 if (lcA > lcB) return +1; 1303 return 0; 1304 } 1598 1305 } 1599 1306 … … 2073 1780 request.send(null); 2074 1781 } 1782 } 1783 } 1784 1785 var SmartEnum = new SmartEnumClass(); 1786 /* 1787 Handles "smart" input fields which can have an attached list of 1788 enumeration options. As the user types a popup-list is displayed 1789 with the matching options. 1790 */ 1791 function SmartEnumClass() 1792 { 1793 // Configuration parameters 1794 this.initialDelay = 300; 1795 this.repeatDelay = 50; 1796 this.leftOffset = Browser.isIE ? -1 : -2; 1797 this.topOffset = Browser.isIE ? 2 : 0; 1798 this.widthOffset = 15; 1799 1800 this.activeField = null; 1801 this.selectedIndex = -1; 1802 this.lastSelectedEnum = null; 1803 this.lastMatchedText = null; 1804 1805 /* 1806 Initialise the smart enum system by creating the <div> tag that 1807 is used to hold the options. 1808 */ 1809 this.init = function() 1810 { 1811 if (this.div) return; 1812 var div = document.createElement('div'); 1813 div.className = 'smartenum'; 1814 div.style.display = 'none'; 1815 div.onmouseenter = function() {SmartEnum.disableHide = true; }; 1816 div.onmouseleave = function() {SmartEnum.disableHide = false; }; 1817 document.body.appendChild(div); 1818 this.div = div; 1819 this.debug = document.createElement('div'); 1820 document.body.appendChild(this.debug); 1821 } 1822 1823 /* 1824 Enable the input field for smart enum. Ignored if 1825 the form or field doesn't exists, the field is not an 1826 input field or if there are no options. This method 1827 changes event handlers for the input field. 1828 @param frmName The name of the form 1829 @param fieldName The name of the field 1830 @param An array object with the options 1831 */ 1832 this.enableForField = function(frmName, fieldName, options) 1833 { 1834 if (!options) return; 1835 var frm = document.forms[frmName]; 1836 if (!frm) return; 1837 var field = frm[fieldName]; 1838 if (!field) return; 1839 1840 this.init(); 1841 // Sort the options in alphabetical order, ignoring case 1842 field.smartOptions = options.sort(Strings.compareIgnoreCase); 1843 field.setAttribute('autocomplete', 'off'); 1844 Main.addClass(field, 'smartinput'); 1845 field.onfocus = this.onfocus; 1846 field.onkeyup = this.onkeyup; 1847 field.onkeydown = this.onkeydown; 1848 field.onblur = this.onblur; 1849 } 1850 1851 /* 1852 Activate and display the enum options for a field. 1853 */ 1854 this.activateAndDisplay = function(formName, fieldName) 1855 { 1856 var frm = document.forms[formName]; 1857 if (!frm) return; 1858 var field = frm[fieldName]; 1859 if (!field) return; 2075 1860 2076 } 2077 2078 1861 // We need to disable the onfocus event to make sure that 1862 // methods are called in the correct order. In IE. the 1863 // onfocus() event is called last, but in Firefox it is called 1864 // immediately after the call to focus(). 1865 this.ignoreNextOnFocus = true; 1866 field.focus(); 1867 this.hideOptions(); 1868 this.setActive(field); 1869 this.filterOptions(true); 1870 this.showOptions(); 1871 } 1872 1873 /* 1874 Set a field as the active field. All other operations will 1875 now use this field. Set to null to disable all smart enum. 1876 Ignored if the field doesn't have any options. This method 1877 also positions the <div> with the options. 1878 */ 1879 this.setActive = function(field) 1880 { 1881 if (field == this.activeField) return; 1882 this.activeField = field; 1883 this.lastMatchedText = null; 1884 if (!field || !field.smartOptions) return; 1885 var pos = Main.getElementPosition(this.activeField); 1886 var div = this.div; 1887 div.innerHTML = ''; 1888 div.style.top = (pos.top + this.activeField.offsetHeight + this.topOffset) + 'px'; 1889 div.style.left = (pos.left + this.leftOffset) + 'px'; 1890 div.style.width = (this.activeField.offsetWidth + this.widthOffset) + 'px'; 1891 } 1892 1893 /* 1894 Hide the enum options. 1895 */ 1896 this.hideOptions = function() 1897 { 1898 this.div.style.display = 'none'; 1899 this.lastSelectedEnum = null; 1900 } 1901 1902 /* 1903 Hide the enum options after a short delay. The delay is needed 1904 in so a possible onClick event can get sent to the currently 1905 selected option. 1906 */ 1907 this.hideOptionsDelayed = function() 1908 { 1909 if (this.disableHide) return; 1910 this.hideTimerId = setTimeout("SmartEnum.hideOptions();", 100); 1911 } 1912 1913 /* 1914 Show the enum options setting the correct position. 1915 */ 1916 this.showOptions = function() 1917 { 1918 this.cancelHideOptions(); 1919 if (this.div.style.display == 'block') return; 1920 this.div.style.display = 'block'; 1921 this.div.scrollTop = 0; 1922 } 1923 1924 /* 1925 Filter the enum options by the text in the active field. 1926 The options that passed the filter are added as <div> tags 1927 to the enum <div>. 1928 @return TRUE if the filter generated any options, FALSE otherwise 1929 */ 1930 this.filterOptions = function(allowEmpty) 1931 { 1932 if (!this.activeField) return false; 1933 var text = this.activeField.value.replace(/^[=!<>]*/, ''); 1934 if (text == this.lastMatchedText) return true; 1935 if (text == '' && !allowEmpty) return false; 1936 1937 var options = this.activeField.smartOptions; 1938 this.lastMatchedText = text; 1939 this.selectedIndex = -1; 1940 this.lastSelectedEnum = null; 1941 var matching = ''; 1942 var index = 0; 1943 for (var i = 0; i < options.length; i++) 1944 { 1945 if (text == '' || options[i].indexOf(text) >= 0) 1946 { 1947 matching += '<div class="smartoption" id="smartoption.' + index + '"'; 1948 matching += ' onmouseover="SmartEnum.setSelectedEnum(' + index + ')"'; 1949 matching += ' onclick="SmartEnum.submitSelected()">' + options[i] + '</div>'; 1950 index++; 1951 } 1952 } 1953 this.div.innerHTML = matching; 1954 return true; 1955 } 1956 1957 /* 1958 Mark a specific enum option as selected. Also makes sure 1959 that the selected option is within the viewable area. 1960 @param index The index of the option 1961 */ 1962 this.setSelectedEnum = function(index) 1963 { 1964 if (this.lastSelectedEnum) 1965 { 1966 Main.removeClass(this.lastSelectedEnum, 'selected'); 1967 this.lastSelectedEnum = null; 1968 } 1969 var option = document.getElementById('smartoption.' + index); 1970 if (option) 1971 { 1972 Main.addClass(option, 'selected'); 1973 this.lastSelectedEnum = option; 1974 this.selectedIndex = index; 1975 var optionTop = option.offsetTop; 1976 var optionBottom = optionTop + option.offsetHeight; 1977 var parent = option.offsetParent; 1978 var parentTop = parent.scrollTop; 1979 var parentBottom = parentTop + parent.offsetHeight; 1980 if (optionTop < parentTop) 1981 { 1982 parent.scrollTop = optionTop; 1983 } 1984 else if (optionBottom > parentBottom) 1985 { 1986 parent.scrollTop = optionBottom - parent.offsetHeight + 2; 1987 } 1988 } 1989 } 1990 1991 /* 1992 Moves the selection up or down, optionally 1993 repeating the operation at specified time intervals. 1994 @param delta The number of options to shift the selection 1995 @param delayRepeat Number of milliseconds to wait until 1996 the move is repeated for the first time 1997 @param repeat Number of milliseconds to wait between 1998 subsequent repeats 1999 */ 2000 this.moveSelection = function(delta, delayRepeat, repeat) 2001 { 2002 var option = document.getElementById('smartoption.' + (this.selectedIndex + delta)); 2003 if (option) 2004 { 2005 this.setSelectedEnum(this.selectedIndex + delta); 2006 } 2007 if (delayRepeat && repeat) 2008 { 2009 var call = 'SmartEnum.moveSelection(' + delta + ',' + repeat + ',' + repeat + ')'; 2010 if (this.timerId) clearTimeout(this.timerId); 2011 this.timerId = setTimeout(call, delayRepeat); 2012 } 2013 } 2014 2015 /* 2016 Copies the selected option to the active field and submits 2017 the form. If no option is selected, just submit the form. 2018 */ 2019 this.submitSelected = function(event) 2020 { 2021 if (!this.activeField) return; 2022 if (this.lastSelectedEnum) 2023 { 2024 var text = this.activeField.value; 2025 var selectedText = this.lastSelectedEnum.innerHTML; 2026 this.activeField.value = text.replace(/^([=!<>]*).*/, '$1' + selectedText); 2027 } 2028 this.hideOptions(); 2029 this.activeField.onkeyup = null; 2030 this.activeField.form.submit(); 2031 } 2032 2033 /* 2034 Cancels a move selection repeat set in the 'moveSelection' method. 2035 */ 2036 this.cancelKeyRepeat = function() 2037 { 2038 if (this.timerId) 2039 { 2040 clearTimeout(this.timerId); 2041 this.timerId = null; 2042 } 2043 } 2044 2045 /* 2046 Cancels a scheduled hide of the dropdown enum options. 2047 */ 2048 this.cancelHideOptions = function() 2049 { 2050 if (this.hideTimerId) 2051 { 2052 clearTimeout(this.hideTimerId); 2053 this.hideTimerId = null; 2054 } 2055 } 2056 2057 /* 2058 Called when a smart-enum enabled field receivs 2059 the focus. This should set the current field to 2060 the active field. 2061 */ 2062 this.onfocus = function(event) 2063 { 2064 if (SmartEnum.ignoreNextOnFocus) 2065 { 2066 SmartEnum.ignoreNextOnFocus = false; 2067 return; 2068 } 2069 if (!event) event = window.event; 2070 var field = Main.getEventTarget(event); 2071 SmartEnum.hideOptions(); 2072 SmartEnum.setActive(field); 2073 } 2074 2075 /* 2076 Called when a smart-enum enabled field loses 2077 the focus. This should hide the options and 2078 set the current field to null. 2079 */ 2080 this.onblur = function(event) 2081 { 2082 if (!event) event = window.event; 2083 SmartEnum.hideOptionsDelayed(); 2084 } 2085 2086 /* 2087 Called when a key is pressed in a smart-enum enabled field. 2088 This function detects: 2089 * up/down arrow: moves the selected option 2090 * enter: submits the form 2091 */ 2092 this.onkeydown = function(event) 2093 { 2094 if (!event) event = window.event; 2095 var charCode = Main.getEventCharCode(event); 2096 if (charCode == 38) 2097 { 2098 // Up arrow 2099 SmartEnum.moveSelection(-1, SmartEnum.initialDelay, SmartEnum.repeatDelay); 2100 } 2101 else if (charCode == 40) 2102 { 2103 // Down arrow 2104 SmartEnum.moveSelection(1, SmartEnum.initialDelay, SmartEnum.repeatDelay); 2105 } 2106 else if (charCode == 13) 2107 { 2108 // Enter 2109 SmartEnum.submitSelected(event); 2110 } 2111 } 2112 2113 /* 2114 Called when a key is released in a smart-enum enabled field. 2115 This function detects changes to the text and displays matching 2116 options. 2117 */ 2118 this.onkeyup = function(event) 2119 { 2120 if (!event) event = window.event; 2121 SmartEnum.cancelKeyRepeat(); 2122 var charCode = Main.getEventCharCode(event); 2123 if (SmartEnum.filterOptions(charCode == 40 || charCode == 38)) 2124 { 2125 SmartEnum.showOptions(); 2126 } 2127 else 2128 { 2129 SmartEnum.hideOptions(); 2130 } 2131 } 2079 2132 } -
trunk/www/include/styles/main.css
r4250 r4251 350 350 351 351 .smartenum { 352 position: absolute; 353 width: 100px; 352 position: absolute; 354 353 height: 200px; 355 background: #E0E0E0; 356 border-top: 1px solid #333333; 357 border-left: 1px solid #333333; 358 border-right: 1px solid #333333; 359 border-bottom: 1px solid #333333; 360 padding: 2px; 354 background: #FFFFFF; 355 border: 1px solid #666666; 361 356 z-index: 999; 362 357 overflow: auto; … … 368 363 border-bottom: 2px ridge #FFFFFF; 369 364 border-right: 2px ridge #FFFFFF; 370 365 background: #ffffff; 371 366 } 372 367 373 368 .smartinput input { 374 369 border: 0px; 370 border-right: 1px solid #999999; 375 371 } 376 372 377 373 .smartoption { 378 374 cursor: pointer; 375 padding: 0px 2px 0px 2px; 376 379 377 } 380 378 381 379 .smartimage { 382 380 cursor: pointer; 383 border -left: 1px solid #999999;381 border: 0px; 384 382 background: #ffffff; 385 383 } 386 384 387 385 .smartenum .selected { 388 background: #cccccc; 389 } 386 background: #445577; 387 color: #ffffff; 388 }
Note: See TracChangeset
for help on using the changeset viewer.