Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #32791

Re: Alternative and fast option to some very useful jQuery features?

From Richard Maher <maher_rjSPAMLESS@hotmail.com>
Newsgroups comp.lang.javascript
Subject Re: Alternative and fast option to some very useful jQuery features?
Date 2017-03-17 20:11 +0800
Organization Aioe.org NNTP Server
Message-ID <oagjpe$1s27$1@gioia.aioe.org> (permalink)
References <c2c625c3-edf6-440a-8460-73d8e3d5c287@googlegroups.com>

Show all headers | View raw


On 17-Mar-17 9:09 AM, justaguy wrote:
> Hi,
>
> jQuery is neat

No it's not! Now I have to learn React for some reason after the fads of 
Angular, bootstrap, et al :-(

>
> Doable?  With pure JS, how do we go about doing this?
>

I do it this way: -

/**
  * Copyright (c) Richard Maher. All rights reserved.
  *
  * Generic predictive text utility for Text and Select elements.
  */
     function Tier3Suggest(
              targetElement,
              lovDetent,
              divClass,
              selClass,
              maxRows,
              dataFetch,
              singleton)
     {
       var lovTarget              = targetElement;

       if (arguments.length < 7)
         throw new Error("Insufficient arguments for Tier3Suggest");

       if (!lovTarget.id)
         throw new Error('"id" attribute must be defined for element');

       if (Tier3Suggest.LOV[lovTarget.id])
         throw new Error("A list of values is already defined for this 
element");

       var lovDetent              = lovDetent || 0;
       var stagger                = null;
       var currVintage            = 0;
       var lastSearch             = "";
       var lastSelected           = -1;
       var dataFetch              = dataFetch;
       var singleton              = singleton;
       var lovMax                 = maxRows || 10;
       var targetStyle            = getStyle(targetElement);
       var selClass               = selClass || "";

       var targetDiv              = document.createElement("div");
       targetDiv.className        = divClass || lovTarget.className;
       targetDiv.style.visibility = "hidden";
       targetDiv.style.position   = "absolute";
       targetDiv.style.width      = "auto";
       targetDiv.style.height     = "0px";
       targetDiv.style.overflowY  = "auto";
       targetDiv.style.overflowX  = "hidden";
       targetDiv.style.padding    = targetStyle.padding;
       targetDiv.style.whiteSpace = "nowrap";

       var dimTarget  = lovTarget;
       var offsetTop  = dimTarget.offsetTop  + dimTarget.offsetHeight;
       var offsetLeft = dimTarget.offsetLeft;

       while(dimTarget = dimTarget.offsetParent){
         offsetTop  += dimTarget.offsetTop;
         offsetLeft += dimTarget.offsetLeft;
       }

       targetDiv.style.top        = offsetTop  + "px";
       targetDiv.style.left       = offsetLeft + "px";

       document.body.appendChild(targetDiv);
       var divStyle               = getStyle(targetDiv);

       var suggestList            = document.createElement("ul");
       suggestList.style.padding  = "0px";
       suggestList.style.margin   = "0px";
       suggestList.style.listStyleType
                                  = "none";

       var getLOV =
         function()
           {
           var lovVintage  = ++currVintage;
           var rowCnt      = 0;
           targetDiv.style.height     = "0px";
           targetDiv.style.visibility = "hidden";
           return function(rowKey, rowData)
                  {
                    if (lovVintage != currVintage)
                      return;

                    var listItem = document.createElement("li");
                    var listData = document.createTextNode(rowData.rTrim());

                    listItem.appendChild(listData);
                    listItem._key = rowKey;

                    suggestList.appendChild(listItem);
                    rowCnt++;

                    if (rowCnt == 1) {
                      targetDiv.style.height     = "auto";
                      targetDiv.style.visibility = "visible";
                    }

                    if (rowCnt == lovMax)
                      targetDiv.style.height = targetDiv.clientHeight + 
"px";

                    if (targetDiv.clientWidth < targetDiv.scrollWidth)
                      targetDiv.style.width = (targetDiv.scrollWidth
                                            + (targetDiv.scrollWidth - 
targetDiv.clientWidth)) + "px";
                  }
         }

       var clickHandler =
         function(evt)
         {
           var lclTarget = evt.target || evt.srcElement;

           if (lclTarget.tagName.toLowerCase() == "option")
             lclTarget = lclTarget.parentNode;

           if (lclTarget.tagName.toLowerCase() != "select")
             return;

           if (lclTarget.selectedIndex == lastSelected) {
             lclTarget.selectedIndex = -1;
             lastSelected = -1;
             targetDiv.style.height    = "0px";
             targetDiv.style.visibility="hidden";
             return;
           }

           lastSelected = lovTarget.selectedIndex;

           newLOV();
        }

       var keyHandler =
         function()
         {
           if (falseAlarm())
             return;

           if (stagger)
             clearTimeout(stagger);

           stagger = setTimeout(newKey, lovDetent);
        };

        function newKey()
        {
           stagger = null;

           if (falseAlarm())
             return;

           lastSearch = lovTarget.value;

           newLOV();
        }

        function falseAlarm()
        {
           if (lovTarget.value == lastSearch &&
               targetDiv.style.visibility == "visible")
             return true;

           if (lovTarget.value.length == 0) {
             targetDiv.style.height    = "0px";
             targetDiv.style.visibility="hidden";
             lastSearch = "";
             return true;
           }

           return false;
        }

        function newLOV()
        {
           targetDiv.style.height = "auto";
           targetDiv.style.width  = "auto";

           while (suggestList.lastChild) {
             suggestList.removeChild(suggestList.lastChild);
           }

           rowCallback = getLOV();
           dataFetch.call(this, lovTarget, rowCallback);

         };

       var listHandler =
         function(evt) {
           var lclTarget = evt.target || evt.srcElement;
           if (lclTarget.nodeType == 3)
             lcltarget = lclTarget.parentNode;

           if (lclTarget.tagName.toLowerCase() == "li") {
             if (evt.type == "mouseover") {
               if (selClass != "") {
                 lclTarget.className = selClass;
               }else{
                 lclTarget.style.color           = divStyle.backgroundColor;
                 lclTarget.style.backgroundColor = divStyle.color;
               }
             }
             if (evt.type == "mouseout") {
               if (selClass != "") {
                 lclTarget.className = "";
               }else{
                 lclTarget.style.color           = "";
                 lclTarget.style.backgroundColor = "";
               }
             }
             if (evt.type == "click") {
               singleton.call(this, lovTarget, lclTarget._key, 
lclTarget.firstChild.nodeValue);
               lovTarget.focus();
               if (lovTarget.type.toLowerCase() == "text")
                 lovTarget.value = lovTarget.value;
             }
           }
         }

       var hideLOV =
         function(e) {
           var evt = e || window.event;
           var lclTarget = evt.target || evt.srcElement;
           if (lclTarget.nodeType != 1)
             return;

           if (lclTarget != lovTarget &&
               lclTarget != targetDiv &&
               targetDiv.style.visibility == "visible") {
             targetDiv.style.height     = "0px";
             targetDiv.style.visibility = "hidden";
             currVintage++;
             resetCriteria();
           }
         }

       listenerRegistry.checkIn(suggestList,"mouseover",listHandler);
       listenerRegistry.checkIn(suggestList,"mouseout", listHandler);
       listenerRegistry.checkIn(suggestList,"click",    listHandler);

       if (window.addEventListener) {
         document.addEventListener("focus", hideLOV, true);
       } else {
         if (!document.attachEvent('onfocusin', hideLOV))
           throw new Error("Unable to focusin listener");
       }

       switch (lovTarget.type.toLowerCase())
       {
         case "text":
              listenerRegistry.checkIn(lovTarget,"keyup",keyHandler);
              var resetCriteria =
                  function() {
                    lovTarget.value = "";
                    lastSearch      = "";
                  }
              break;
         case "select-one":
              listenerRegistry.checkIn(lovTarget,"click",clickHandler);
              var resetCriteria =
                  function() {
                    lovTarget.selectedIndex = -1;
                    lastSelected            = -1;
                  }
              break;
         default:
              throw new Error("Unsupported field type for LOV");
       }

       targetDiv.appendChild(suggestList);

       Tier3Suggest.LOV[lovTarget.id] = this;

       return this;
     }

Tier3Suggest.LOV = {};

Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-16 18:09 -0700
  Re: Alternative and fast option to some very useful jQuery features? jonas.thornvall@gmail.com - 2017-03-17 01:27 -0700
    Re: Alternative and fast option to some very useful jQuery features? jonas.thornvall@gmail.com - 2017-03-17 01:48 -0700
  Re: Alternative and fast option to some very useful jQuery features? JJ <jj4public@vfemail.net> - 2017-03-17 15:29 +0700
    Re: Alternative and fast option to some very useful jQuery features? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-03-17 14:00 +0100
      Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-18 21:27 -0700
    Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-18 21:03 -0700
  Re: Alternative and fast option to some very useful jQuery features? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-17 11:29 +0000
    Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-18 21:25 -0700
      Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-18 21:32 -0700
        Re: Alternative and fast option to some very useful jQuery features? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-19 10:53 +0000
          Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-19 18:13 -0700
          Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-19 18:49 -0700
            Re: Alternative and fast option to some very useful jQuery features? "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2017-03-20 11:03 +0100
              Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-21 20:16 -0700
                Re: Alternative and fast option to some very useful jQuery features? "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2017-03-22 09:12 +0100
                Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-23 15:51 -0700
                Re: Alternative and fast option to some very useful jQuery features? "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2017-03-24 09:15 +0100
            Re: Alternative and fast option to some very useful jQuery features? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-20 10:41 +0000
              Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-20 17:23 -0700
                Re: Alternative and fast option to some very useful jQuery features? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-21 01:33 +0000
                Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-21 20:09 -0700
  Re: Alternative and fast option to some very useful jQuery features? Richard Maher <maher_rjSPAMLESS@hotmail.com> - 2017-03-17 20:11 +0800
    Re: Alternative and fast option to some very useful jQuery features? justaguy <lichunshen84@gmail.com> - 2017-03-18 21:26 -0700
      Re: Alternative and fast option to some very useful jQuery features? Richard Maher <maher_rjSPAMLESS@hotmail.com> - 2017-03-19 17:39 +0800

csiph-web