Thread: Help with some website design...

  1. #106
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Huh. That's a very well-written post, Mario.

    Maybe I should stop viewing C/C++ as the only true languages and actually get to know a language before I judge it so harshly. If my wife were here, she's laugh and tease about my overbearing reluctance to new things. She gives me a lot of grief because I did the same thing to C++ in the past and now I'm like in love with it so she definitely lets me know that she did not forget.

  2. #107
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Okay, I took a stab at using a new style (the one phantom suggested). Could anyone test this page for bugs? I'm just hoping I got the mouse and tab interfaces to co-exist without making any weird coloring mistakes. I took Alpo's advice about using "===" so I hope I'm doing it right.

    Edit : One question I have is, am I being redundant in passing the window object and then using :
    Code:
    function(event)
    {
        var evt = event || window.event;
    }
    Wouldn't "event" already be part of the window? Like, when I add the eventListener to the document, I don't need to call window.loadInterfaces, I just type "loadInterfaces". Does this same type of principle apply to everything encapsulated in the function?

    Code:
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <script type="text/javascript">
    (function(window)
    {
        var voteData = null;
        var form = null;
        var input = null;
    
    
        var evenColor = "#D3D8E3";
        var oddColor = "#BDBDBD";
        var matchColor = "#2E9AFE";
        var focusColor = "#04B404";
        var prevColor = null;
    
    
        var selectBlur = function(event)
        {
            var evt = event || window.event;
    
    
            var hostRow = evt.target.parentNode.parentNode;
    
    
            hostRow.style.backgroundColor = prevColor;
        };
    
    
        var selectFocus = function(event)
        {
            var evt = event || window.event;
    
    
            var hostRow = evt.target.parentNode.parentNode;
    
    
            var currColor = hostRow.style.backgroundColor;
    
    
            prevColor = (currColor === focusColor ? prevColor : currColor);
            hostRow.style.backgroundColor = focusColor;
        };
    
    
        var selectAddEvent = function()
        {
            for (var i = 0; i < voteData.length; ++i)
            {
                voteData[i].select.addEventListener("focus", selectFocus);
                voteData[i].select.addEventListener("blur", selectBlur);
            }
        };
    
    
        var clearRow = function(idx)
        {
            voteData[idx].row.style.backgroundColor = (idx % 2 === 0 ? evenColor : oddColor);
        };
    
    
        var clearAllRows = function()
        {
            for (var i = 0; i < voteData.length; ++i)
            {
                clearRow(i);
                voteData[i].select.tabIndex = 0;
            }
        };
    
    
        var highlightRow = function(idx)
        {
            voteData[idx].row.style.backgroundColor = matchColor;
        };
    
    
        var findMatches = function(needle)
        { 
            if (needle.length === 0)
            {
                clearAllRows();
                return;
            }
    
    
            var newTabIdx = 1;
            var firstMatch = null;
    
    
            for (var i = 0; i < voteData.length; ++i)
            {
                if (voteData[i].name.indexOf(needle) >= 0)
                {
                    highlightRow(i);
    
    
                    voteData[i].select.tabIndex = newTabIdx;
                    ++newTabIdx;
    
    
                    if (firstMatch === null)
                        firstMatch = i;
                }
                else
                {
                    clearRow(i);
    
    
                    voteData[i].select.tabIndex = -1;
                }
            }
    
    
            input.tabIndex = newTabIdx;
            ++newTabIdx;
    
    
            if (firstMatch !== null)
                voteData[firstMatch].select.focus();
        };
    
    
        var highlightMatches = function(event)
        {
            var evt = event || window.event;
            evt.preventDefault();
    
    
            input = String(document.getElementById("search-input").value).toLowerCase();
    
    
            findMatches(input);
        };
    
    
        var formAddEvent = function()
        {
            form = document.getElementById("search-form");
            form.addEventListener("submit", highlightMatches);
        };
    
    
        var buildLookup = function()
        {
            voteData = [];
    
    
            var names = document.getElementsByClassName("name");
    
    
            for (var i = 0; i < names.length; ++i)
            {
                voteData[i] = { name : String(names[i].textContent).toLowerCase(),
                                row : names[i].parentNode,
                                select : (names[i].parentNode).querySelector("select") };
            }
    
    
            console.log(voteData);
        };
    
    
        var tabInit = function()
        {
            buildLookup();
            selectAddEvent();
            formAddEvent();
        };
    
    
        var hoverClear = function(event)
        {
            var evt = event || window.event;
    
    
            evt.currentTarget.style.backgroundColor = prevColor;
        };
    
    
        var hoverHighlight = function(event)
        {
            var evt = event || window.event;
    
    
            prevColor = (evt.currentTarget.style.backgroundColor === focusColor ? prevColor : evt.currentTarget.style.backgroundColor);
            evt.currentTarget.style.backgroundColor = focusColor;
        }
    
    
        var mouseInit = function()
        {
            for (var i = 0; i < voteData.length; ++i)
            {
                voteData[i].row.addEventListener("mouseover", hoverHighlight);
                voteData[i].row.addEventListener("mouseout", hoverClear);
            }
        };
    
    
        var initInterfaces = function()
        {
            tabInit();
            mouseInit();
        }
    
    
        if (window)
        {
            window.loadInterfaces = initInterfaces;
        }
    }(window));
    
    
    // Load the interface and set-up the page
    document.addEventListener("DOMContentLoaded", loadInterfaces);
            </script>
        </head>
        <body>
            <table>
                <tbody>
                    <tr style="background-color : #D3D8E3">
                        <td class="name">MutantJohn</td>
                        <td>
                            <select>
                                <option>C</option>
                                <option>C++</option>
                                <option>Java</option>
                                <option>Python</option>
                                <option>Fortran</option>
                                <option>Perl</option>
                                <option>Haskell</option>
                            </select>
                        </td>
                    </tr>
                    <tr style="background-color : #BDBDBD">
                        <td class="name">phantomotap</td>
                        <td>
                            <select>
                                <option>C</option>
                                <option>C++</option>
                                <option>Java</option>
                                <option>Python</option>
                                <option>Fortran</option>
                                <option>Perl</option>
                                <option>Haskell</option>
                            </select>
                        </td>
                    </tr>
                    <tr style="background-color : #D3D8E3">
                        <td class="name">Nominal Animal</td>
                        <td>
                            <select>
                                <option>C</option>
                                <option>C++</option>
                                <option>Java</option>
                                <option>Python</option>
                                <option>Fortran</option>
                                <option>Perl</option>
                                <option>Haskell</option>
                            </select>
                        </td>
                    </tr>
                    <tr style="background-color : #BDBDBD">
                        <td class="name">Alpo</td>
                        <td>
                            <select>
                                <option>C</option>
                                <option>C++</option>
                                <option>Java</option>
                                <option>Python</option>
                                <option>Fortran</option>
                                <option>Perl</option>
                                <option>Haskell</option>
                            </select>
                        </td>
                    </tr>
                    <tr style="background-color : #D3D8E3">
                        <td class="name">Salem</td>
                        <td>
                            <select>
                                <option>C</option>
                                <option>C++</option>
                                <option>Java</option>
                                <option>Python</option>
                                <option>Fortran</option>
                                <option>Perl</option>
                                <option>Haskell</option>
                            </select>
                        </td>
                    </tr>
                    <tr style="background-color : #BDBDBD">
                        <td class="name">laserlight</td>
                        <td>
                            <select>
                                <option>C</option>
                                <option>C++</option>
                                <option>Java</option>
                                <option>Python</option>
                                <option>Fortran</option>
                                <option>Perl</option>
                                <option>Haskell</option>
                            </select>
                        </td>
                    </tr>
                    <tr style="background-color : #D3D8E3">
                        <td class="name">Mario F.</td>
                        <td>
                            <select>
                                <option>C</option>
                                <option>C++</option>
                                <option>Java</option>
                                <option>Python</option>
                                <option>Fortran</option>
                                <option>Perl</option>
                                <option>Haskell</option>
                            </select>
                        </td>
                    </tr>
                </tbody>
            </table>
            <div id="search-div">
                <form id="search-form">
                    <input type="text" value="" action="#" id="search-input"></input>
                </form>
            </div>
        </body>
    </html>
    Last edited by MutantJohn; 05-15-2015 at 05:06 PM.

  3. #108
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by MutantJohn View Post
    Could anyone test this page for bugs?
    Firefox 38.0 on Linux x86-64: I'd say works pretty well already.

    If you hover over the last match, and tab to the search bar, the last match stays green after you move the mouse out.

    Hovering over a non-match, tabbing from last match to search bar, then moving out from the non-match turns that non-match blue.

    Would using CSS for the focus/hover/active coloring, and using tab and click to just .focus() on the desired element, work better? I am not sure myself, I'm just wondering aloud.

    I'm too rusty to comment on the code itself; I'm hoping someone more up to date in Javascript stuff will comment further

  4. #109
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    One question I have is, am I being redundant in passing the window object and then using :
    O_o

    No. The fragment in question represents a tiny shim.

    You could change the fragment, but you aren't really paying for anything, and you do potentially gain some coverage.

    Wouldn't "event" already be part of the window? Like, when I add the eventListener to the document, I don't need to call window.loadInterfaces, I just type "loadInterfaces". Does this same type of principle apply to everything encapsulated in the function?
    I will not, as before, go into a lot of actual details or implementation issues.

    The functions in Javascript have multiple hidden arguments. You already know about the `this' reference. The functions also have hidden `global' and `closure' arguments. (You can, by using certain methods or exploiting implementation details, change the hidden references.) The references are chained according to a rather long list of rules, but you don't need to worry about the majority. You already have a basic handle on the `this' reference. You can imagine the `closure' reference as the anonymous, the syntax you use without the `.' operator, reference you create by using variables from an enclosing scope. The `global' reference you may imagine as a `closure' you can't see.

    Would using CSS for the focus/hover/active coloring, and using tab and click to just .focus() on the desired element, work better? I am not sure myself, I'm just wondering aloud.
    I would argue that using CSS, directly or indirectly, is the only correct way to change the colors.

    I'm hoping someone more up to date in Javascript stuff will comment further
    I don't have time to explain, but I can show an example of basically everything technique covered in the discussion.

    Of course, I don't code quite like anyone else in the Javascipt language. I'm not going to get into all the reasons just now. Basically though, my reaction to years of "NO! The * goes $(Preference)!" and such similar nonsense was the creation of a C++ style everyone can find something to love and hate. I use a lot of stylistic conventions designed to annoy people. I eventually just ported the awful beast to every language I use.

    Soma

    Code:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript">
    (function(fModule, fEnvironment) {
        /* I am, again, just showing an example. I do a lot of checks. */
        /* I also use several techniques to normalize the environment. */
        var Register;
        Register = (function() {
            /* The registration function has a variable implementation depending on the actual environment. */
            /* The implementation is ultimately exposed for the use of dependent modules. */
            if (fEnvironment) {
                return function(fModule) {
                    fEnvironment['$UUID!'] = fModule;
                    return fModule;
                };
            }
        }());
        return Register(fModule({
            document: fEnvironment.document,
            environment: fEnvironment,
            register: Register,
        }));
    }(function(fContext) {
        'use strict';
        /* I use the '$' character as a resolution operator. */
        /* You might think of the combination as the anonymous namespace from the C++ language. */
        var gDocument, gEnvironment, gModule, SElement, SElement$RemoveClass;
        /* I have quite a bit of context to import by name. */
        gDocument = fContext.document;
        gEnvironment = fContext.environment;
        /* I actually use a much more elaborate mechanism. */
        /* I just don't have time to explain or show an example. */
        SElement = function(fIdentifier) {
            if (this instanceof SElement) {
                if (typeof fIdentifier === 'string') {
                    this.mNative = gDocument.getElementById(fIdentifier);
                } else {
                    this.mNative = fIdentifier;
                }
            } else {
                /* I prefer to use `new' yet appreciate the strategy. */
                return new SElement(fIdentifier);
            }
        };
        /* I know. I really do know, but the actual validator is thousands of characters long. */
        SElement$RemoveClass = function(fSelf, fIdentifier, fRemove) {
            var sFilter, sResult;
            sFilter = new RegExp('(^|\\s)' + fIdentifier + '(\\s|$)');
            sResult = fSelf.className.match(sFilter);
            if (sResult && fRemove) {
                fSelf.className = fSelf.className.replace(sFilter, '');
            }
            return sResult;
        };
        /* I actually shim some of the missing characteristics of other languages offering prototype-based polymorphisms. */
        /* I, again, simply don't have time to explain all the code. */
        SElement.prototype.addClass = function(fIdentifier) {
            if (!this.hasClass(fIdentifier)) {
                this.mNative.className += ' ' + fIdentifier;
                return true;
            }
            return false;
        };
        SElement.prototype.hasClass = function(fIdentifier) {
            return SElement$RemoveClass(this.mNative, fIdentifier, false);
        };
        SElement.prototype.removeClass = function(fIdentifier) {
            return !SElement$RemoveClass(this.mNative, fIdentifier, true);
        };
        SElement.prototype.attachHandler = function(fIdentifier, fHandler) {
            var sHandler = function(fEvent) {
                fEvent = fEvent || gEnvironment.event;
                fHandler(fEvent.currentTarget, fEvent);
            };
            this.mNative.addEventListener(fIdentifier, sHandler);
            return sHandler;
        };
        gModule = function(fIdentifier) {
            return new SElement(fIdentifier);
        };
        return gModule;
    }, typeof window === 'undefined' ? this : window));
    document.addEventListener('DOMContentLoaded', function() {
        var $, sOne, sTwo, ProcessMouseDown, ProcessMouseUp;
        /* Nope. I wasn't being silly. I often use a UUID for modules. */
        $ = window['$UUID!'];
        ProcessMouseDown = function(f) {
            f = $(f);
            f.addClass('held');
        };
        ProcessMouseUp = function(f) {
            f = $(f);
            f.removeClass('held');
        };
        sOne = $('one');
        sTwo = $('two');
        sOne.attachHandler('mousedown', ProcessMouseDown);
        sOne.attachHandler('mouseup', ProcessMouseUp);
        sOne.attachHandler('mouseout', ProcessMouseUp);
        sTwo.attachHandler('mousedown', ProcessMouseDown);
        sTwo.attachHandler('mouseup', ProcessMouseUp);
        sTwo.attachHandler('mouseout', ProcessMouseUp);
        sOne.addClass('highlighted');
        setInterval((function() {
            var sCurrent, sLast;
            sCurrent = sOne;
            sLast = sTwo;
            return function() {
                var sTemporary;
                sTemporary = sCurrent;
                sCurrent = sLast;
                sLast = sTemporary;
                sLast.addClass('highlighted');
                sCurrent.removeClass('highlighted');
            };
        }()), 500);
    });
        </script>
        <style>
        tr {
            background-color: #F00;
    }   tr.highlighted {
            background-color: #F0F;
    }   tr:hover {
            background-color: #0F0;
    }   tr.held {
            background-color: #00F;
    }   tr.held.highlighted {
            background-color: #0FF;
    }
        </style>
        <title>Title</title>
    </head>
    <body>
    <table>
        <tbody>
            <tr id="one">
                <td>one</td><td>1111</td>
            </tr>
            <tr id="two">
                <td>two</td><td>2222</td>
            </tr>
        </tbody>
    </table>
    </body>
    </html>
    Last edited by phantomotap; 05-15-2015 at 11:10 PM.
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #110
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I would argue that using CSS, directly or indirectly, is the only correct way to change the colors.
    Interesting. Why is this? Is accessing the color attribute not as ideal?

    Also, that is a trippy lookin' web page O_o

  6. #111
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by MutantJohn View Post
    Interesting. Why is this? Is accessing the color attribute not as ideal?
    The browsers have different ways of representing the same colors, I probably don't know them all, but:

    rgba(n, n, n, n);
    rgb(n, n, n)
    #FFFFFF
    #FFF

    I've written a few modules with interfaces that can extract the color values in a generalized fashion (its a decent project if you are learning regular expression btw), but the string comparisons between one of those formats and the other might not match. It's much easier to use the CSS semi-selectors (:focus, ect), or use classes like Phantomotap does.

    Also, that is a trippy lookin' web page O_o
    I started reading the code and when I looked up an hour had gone by lol. I need to start thinking more like Phantomotap when doing my own work, less ad hoc solutions and more detection beforehand.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  7. #112
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by MutantJohn View Post
    Interesting. Why is this? Is accessing the color attribute not as ideal?
    The browser already tracks the state, and the CSS provides a simple way to associate state to visual effects (via :hover, :active, :focus etc. pseudo-classes).

    Trying to override that by tracking the state yourself, and doing the visual changes, is just fighting with the browser, and leads to conflicts, like the bugs I observed.

    Instead, you could use two classes for the data rows, say normalrow and matchingrow, and assign that to the element .class property. Actually, make that four; two for odd rows, and two for even rows.

    In your head section, you add the classes and their pseudo-classes, and the visual effects you want,
    Code:
      <style type="text/css">
    
       .oddnormalrow           { background-color: #ccc; }
       .oddnormalrow:hover     { background-color: #ccc; }
       .oddnormalrow:active    { background-color: #ccc; }
       .oddnormalrow:focus     { background-color: #ccc; }
    
       .evennormalrow          { background-color: #ccc; }
       .evennormalrow:hover    { background-color: #ccc; }
       .evennormalrow:active   { background-color: #ccc; }
       .evennormalrow:focus    { background-color: #ccc; }
    
       .oddmatchingrow         { background-color: #ccc; }
       .oddmatchingrow:hover   { background-color: #ccc; }
       .oddmatchingrow:active  { background-color: #ccc; }
       .oddmatchingrow:focus   { background-color: #ccc; }
    
       .evenmatchingrow        { background-color: #ccc; }
       .evenmatchingrow:hover  { background-color: #ccc; }
       .evenmatchingrow:active { background-color: #ccc; }
       .evenmatchingrow:focus  { background-color: #ccc; }
    
      </style>
    (I just used grey for all above, I'm lazy), and let the browser worry about picking the proper visuals based on the state. No mouseup, mousedown, or focus handlers needed at all.

    In your findMatches() function, you just assign the data row .className to oddmatchingrow, evenmatchingrow, oddnormalrow, or evennormalrow, depending on whether the row is odd or even, and whether the data element on that row matched the search terms or not.

    Phantomotap's example code adds and removes classes from the element dynamically, even during mouse presses (which I don't like much because it's fighting against the browser), whereas this just assigns a single class during the search, and lets the browser handle all the visual effects. Since this does not modify the element properties except when the search is performed, this should also be a bit faster on slow machines.

  8. #113
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Thank you, Nominal. That's definitely much more approachable.

    But now, phantom, I have, like, a million questions.

    I was going to list a few :

    Code:
    /* Nope. I wasn't being silly. I often use a UUID for modules. */
        $ = window['$UUID!'];
    I tried looking it up and it said that a UUID was a universally unique identifier and wiki said it was just like a 128 bit value, commonly. Is that what this is? The MDN didn't give me much useful info either.

    What's this fContext variable you're using? What's the logic behind it? I trust the implementation of this code but I'm having trouble seeing the overall picture of it.

  9. #114
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Btw, you guys were super duper right about using CSS to handle all the color changing stuff. I started using it and now I think the code works perfectly! Seriously, thank you guys for all your help.

  10. #115
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Okay, this is driving me nuts. The page works awesome in Chromium but in Firefox, if you are focused on a select element and you use alt-down to expand the list and you keep tabbing through the matches, the CSS is ridiculously slow to update the color. I've checked it in the inspector, the class name is changing as it should but the CSS seems to lag like all get out. What could be wrong?

    Code:
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <style>
                .evenRow { background-color : #D3D8E3 }
                .evenRow:hover { background-color : #04B404 }
    
    
                .oddRow { background-color : #BDBDBD }
                .oddRow:hover { background-color : #04B404 }
                
                .match { background-color : #2E9AFE }
                .match:hover { background-color : #04B404 }
                .focus { background-color : #04B404 }
    
    
                #search-input:focus { background-color : #C3BEEA }
            </style>
            <script type="text/javascript">
    (function(window)
    {
        var voteData = null;
        var form = null;
        var input = null;
        var prevClassName = null;
    
    
        var selectFocus = function(event)
        {
            var evt = event || window.event;
    
    
            var rowClassName = evt.currentTarget.parentNode.parentNode.className;
    console.log(rowClassName);
            prevClassName = (rowClassName === "focus" ? prevClassName : rowClassName);
            evt.currentTarget.parentNode.parentNode.className = "focus";
        };
    
    
        var selectBlur = function(event)
        {
            var evt = event || window.event;
    
    
            //alert(prevClassName);
    
    
            evt.currentTarget.parentNode.parentNode.className = prevClassName;
            prevClassName = null;
        };
    
    
    
    
        var addSelectEvents = function()
        { 
            for (var i = 0; i < voteData.length; ++i)
            {
                voteData[i].select.addEventListener("focus", selectFocus);
                voteData[i].select.addEventListener("blur", selectBlur);
            }
        };
    
    
        var findMatches = function(event)
        {
            var evt = event || window.event;
    
    
            evt.preventDefault();
    
    
            var needle = String(document.getElementById("search-input").value).toLowerCase();
            var tabidx = 1;
            var first = null;
    
    
            if (needle.length === 0)
            {
                for (var i = 0; i < voteData.length; ++i)
                {
                    voteData[i].row.className = (i % 2 === 0 ? "evenRow" : "oddRow");
                    voteData[i].select.tabIndex = 0;
                }
    
    
                return;
            }
    
    
            for (var i = 0; i < voteData.length; ++i)
            { 
                if (voteData[i].name.indexOf(needle) >= 0)
                {
                    voteData[i].row.className = "match";
                    voteData[i].select.tabIndex = tabidx;
                    ++tabidx;
    
    
                    if (first === null)
                        first = i;
                }
                else
                {
                    voteData[i].select.tabIndex = -1;
                    voteData[i].row.className = (i % 2 === 0 ? "evenRow" : "oddRow");
                }
            }
    
    
            input.tabIndex = tabidx;
            ++tabidx;
    
    
            if (first !== null)
            {
                voteData[first].select.focus();
            }
        };
    
    
        var buildLookup = function()
        {
            form = document.getElementById("search-form");
            input = document.getElementById("search-input");
            voteData = [];
    
    
            var rows = document.getElementsByTagName("tr");
    
    
            for (var i = 0; i < rows.length; ++i)
            {
                voteData[i] = { name : String(rows[i].querySelector("td").textContent).toLowerCase(),
                                row : rows[i],
                                select : rows[i].querySelector("select") };
            }
    
    
            console.log(voteData);
    
    
        
            form.addEventListener("submit", findMatches);
            addSelectEvents();
        };
    
    
        var newSelectElement = function()
        {
            var options = [ "C", "C++", "C#", "Java", "CUDA",
                            "Fortran", "Python", "Haskell" ];
    
    
            var select = document.createElement("select");
            var optElements = [];
    
    
            for (var i = 0; i < options.length; ++i)
            {
                optElements[i] = document.createElement("option");
                optElements[i].textContent = options[i];
                select.appendChild(optElements[i]);
            };
    
    
            return select;
        };
    
    
        var generateTable = function()
        { 
            var names = [ "MutantJohn",
                          "phantomotap",
                          "Nominal Animal",
                          "Alpo",
                          "Mario F.",
                          "laserlight",
                          "Salem",
                          "grumpy" ];
    
    
            var table = document.createElement("table");
            var tbody = document.createElement("tbody");
    
    
            for (var i = 0; i < names.length; ++i)
            {
                var row = document.createElement("tr");
                row.className = (i % 2 === 0 ? "evenRow" : "oddRow");
    
    
                var col0 = document.createElement("td");
                var col1 = document.createElement("td");
    
    
                col0.textContent = names[i];
                col1.appendChild(newSelectElement());
    
    
                row.appendChild(col0);
                row.appendChild(col1);
    
    
                tbody.appendChild(row);
            }
    
    
            table.appendChild(tbody);
            //document.body.appendChild(table);
    
    
            var oldHTML = document.body.innerHTML;
            document.body.innerHTML = "";
            document.body.appendChild(table);
            document.body.innerHTML += oldHTML;
        };
    
    
        var init = function()
        {
            generateTable();
            buildLookup();
        };
    
    
        if (window)
        {
            window.loadTool = init;
        }
    }(window));
    
    
    document.addEventListener("DOMContentLoaded", loadTool);
            </script>
        </head>
        <body>
            <div id="search-div">
                <form id="search-form">
                    <input id="search-input" type="text" action="#" value=""></input>
                </form>
            </div>
        </body>
    <html>

  11. #116
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by MutantJohn View Post
    Okay, this is driving me nuts.
    You could use the :focus pseudo-class instead of using Javascript to change the class. That way you only change the class names when you check each entry for matches.

  12. #117
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Hmm... I'm not entirely sure what you mean, Nominal.

    Unless I'm particularly mistaken, CSS doesn't have parent selectors yet and you can't focus() naturally on a row, nor would I want to in this application. My logic was to have the focus() event shift the class name so that the CSS would handle the rendering. Is this the wrong approach?

  13. #118
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by MutantJohn View Post
    Hmm... I'm not entirely sure what you mean, Nominal.
    If you have an absolutely-positioned negative-z-index div immediately after the select element, at least Firefox 38 on Linux x86-64 respects select:focus ~ div. A simple example:
    Code:
    <!DOCTYPE html>
    <html>
     <head>
      <title> Example </title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <style type="text/css">
    
       tr { position: relative; }
    
       .oddrow, .evenrow  { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: -1; }
    
       .oddrow  { background-color: #eef; border: 1px solid #fff; }
       .evenrow { background-color: #efe; border: 1px solid #fff; }
    
        select:hover ~ .oddrow  { background-color: #fee; border: 1px solid #f00; }
        select:hover ~ .evenrow { background-color: #fee; border: 1px solid #f00; }
    
        select:focus ~ .oddrow,  select:active ~ .oddrow  { background-color: #ccf; border: 1px solid #000; }
        select:focus ~ .evenrow, select:active ~ .evenrow { background-color: #cfc; border: 1px solid #000; }
    
      </style>
     </head>
     <body>
      <form method="POST" action="#" accept-charset="utf-8">
       <table>
        <tr><td>Name</td><td>Language</td></tr>
        <tr><td>Nominal Animal</td><td><select name="Nominal Animal"><option value=""></option><option value="C">C</option></select><div class="oddrow"></div></td></tr>
        <tr><td>MutantJohn</td><td><select name="MutantJohn"><option value=""></option><option value="C">C</option></select><div class="evenrow"></td></tr>
       </table>
      </form>
     </body>
    </html>
    For the above example, I only used two classes, one for odd and one for even rows, but you'd use four: odd matching rows, even matching rows, odd non-matching rows, and even non-matching rows.

    Also, this allows changing the visuals on the div, not on the table cell or row.

  14. #119
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Code:
    tr { position: relative; }
    O_o

    Using "position: relative" on table elements other than `table' relies on undefined behavior resulting in inconsistent behavior. The same code could serve to highlight the row, but you can also see the same code highlight the entire page. You could try adding "display: block" to the `tr' element, but you can't do that and keep all the formatting generally associated with tables.

    You should use CSS for styling, but you will need Javascript to add functionality.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  15. #120
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by phantomotap View Post
    Using "position: relative" on table elements other than `table' relies on undefined behavior resulting in inconsistent behavior.
    Right, dammit. How about
    Code:
    <!DOCTYPE html>
    <html>
     <head>
      <title> Example </title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <style type="text/css">
    
       .table    { width: 60em; text-align: center; }
    
       .entry {
        position: relative;
        top: 0;
        left: 0;
        clear: both;
        text-align: left; 
        padding: 0 0 0 0;
        border: 1px transparent;
        margin: 1px 1px 2px 1px;
       }
    
       br.endentry {
        clear: both;
       }
    
       .key { float: left;  padding: 0.1em 0.5em 0.1em 0.5em; }
       .opt { float: right; padding: 0 0 0 0; }
    
       .odd, .even {
        position: absolute;
        left: -1px; top: -1px;
        width: 100%;
        height: 100%;
        border: 1px transparent;
        z-index: -1;
       }
    
       .odd  { background-color: #efefff; border: 1px solid #ccc; }
       .even { background-color: #efffef; border: 1px solid #ccc; }
    
       select:hover ~ .odd  { background-color: #dfdfff; border: 1px solid #99c; }
       select:hover ~ .even { background-color: #dfffdf; border: 1px solid #9c9; }
    
       select:focus ~ .odd,  select:active ~ .odd  { background-color: #fee; border: 1px solid #000; }
       select:focus ~ .even, select:active ~ .even { background-color: #fee; border: 1px solid #000; }
    
       .entry:hover > .odd  { border: 1px solid #999; }
       .entry:hover > .even { border: 1px solid #999; }
    
      </style>
     </head>
     <body>
      <form method="POST" action="#" accept-charset="utf-8">
    
       <div class="table">
    
        <div class="entry">
         <div class="key"> Nominal Animal </div>
         <select class="opt" name="Nominal Animal"><option value=""></option><option value="C">C</option><option value="C++">C++</option><option value="Python">Python</option></select>
         <div class="odd"></div>
         <br class="endentry">
        </div>
     
        <div class="entry">
         <div class="key"> MutantJohn </div>
         <select class="opt" name="MutantJohn"><option value=""></option><option value="C">C</option><option value="C++">C++</option><option value="Python">Python</option></select>
         <div class="even"></div>
         <br class="endentry">
        </div>
    
        <div class="entry">
         <div class="key"> Phantomotap </div>
         <select class="opt" name="Phantomotap"><option value=""></option><option value="C">C</option><option value="C++">C++</option><option value="Python">Python</option></select>
         <div class="odd"></div>
         <br class="endentry">
        </div>
     
       </div>
    
      </form>
     </body>
    </html>
    instead?

    Quote Originally Posted by phantomotap View Post
    You should use CSS for styling, but you will need Javascript to add functionality.
    Sure. It's just that if hover/active/focus can be visualized using CSS only, it ought to be fast enough even on really old machines, and we'd avoid modifying any DOM properties except when doing the search. It just appeals to me, somehow.

    The above no-table method may be slower to layout on slow machines, though. I suspect browser engines use some kind of table layout widget for real tables (which ought to be somewhat optimized in most widget toolkits), so the above might turn out to be slower than a table + Javascript active/focus handling.

    So, using Javascript for the focus/active stuff may just turn out to work better anyway. Consider this and my previous two posts just wondering out aloud.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-11-2012, 12:25 AM
  2. Website Design....again
    By Sentral in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 10-29-2006, 05:47 AM
  3. Website design!
    By Sentral in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 10-07-2006, 12:38 AM
  4. website
    By the Wookie in forum Windows Programming
    Replies: 1
    Last Post: 11-07-2002, 02:25 PM