Option Menu Not Working When I Add Javascript Function

91 views Asked by At

I need help with an option menu not working when I add javascript.

I found a tutorial for this type of drop-down menu and the menu/drop-down function is working except I can’t get it to do what I need when an option is selected.

When "Not Free" is selected I want 2 divs to open under the menu. I have code that works for that on a regular option menu that isn’t using the javascript code from the first example below, but it is not working when I try to add additional function code to this menu. There is something I am not seeing or understanding in the javascript that makes the menu work.

Here is the original code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<style>
/*Form*/

* {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
form > div {
    clear: both;
    overflow: hidden;
    padding: 1px;
    margin: 0;
}
input[type=text]:focus, input[type=email]:focus, input[type=url]:focus, input[type=password]:focus, textarea:focus {
    outline: 0;
    border: #f76e00 1px solid;
}

/*Dropdown*/

#dropdown {
    background-color: #d8f3ff;
    width: 100%;
    padding: 10px;
    text-align: left;
}
#dropdown2 {
    background-color: #eaeaea;
    width: 100%;
    padding: 10px;
    text-align: left;
}
#dropdown3 {
    background-color: #d8f3ff;
    width: 100%;
    padding: 10px;
    text-align: left;
}
.dropcont {
    position: relative;
    font-size: 12px;
    color: #666;
    text-decoration: none;
    text-align: left;
}
.trigger {
    color: #666;
    padding: 10px;
    font-size: 12px;
    width: 100%;
    background: #fff url(../images/select-arrow-open.png) 98% center no-repeat;
    display: block;
    border: 1px solid #ccc;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
    text-decoration: none;
    text-align: left;
}
.trigger:hover {
    color: #666;
    background: #f5f5f5 url(../images/select-arrow-open.png) 98% center no-repeat;
    border: #f76e00 1px solid;
    text-decoration: none;
    text-align: left;
}
.activetrigger {
    color: #666;
    padding: 10px;
    font-size: 12px;
    width: 100%;
    background: #f5f5f5 url(../images/select-arrow-close.png) 98% center no-repeat;
    display: block;
    border: #f76e00 1px solid;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    text-decoration: none;
    text-align: left;
}
.activetrigger:hover {
    background: #f5f5f5 url(../images/select-arrow-close.png) 98% center no-repeat;
    color: #666;
    text-decoration: none;
}
.activetrigger:active {
    background: #f5f5f5 url(../images/select-arrow-close.png) 98% center no-repeat;
    color: #666;
    text-decoration: none;
}
.dropcont ul {
    font-size: 12px;
    border: #f76e00 1px solid;
    border-top: none;
    background: #fff;
    list-style-type: none;
    padding: 10px;
    margin: 0;
    width: 100%;
    z-index: 100;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    text-decoration: none;
    text-align: left;
}
.dropcont ul li {
    padding: 5px;
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
    text-decoration: none;
    text-align: left;
}
.dropcont ul li:hover {
    background: #f5f5f5;
    outline: none;
    text-decoration: none;
}
.dropcont ul li:first-child {
    display: none;
}
.dropcont ul li:last-child {
    border-bottom: none;
}
.dropdownhidden {
    display: none;
}
.dropdownvisible {
    height: auto;
}
.dropdownvisible {
    height: 100px;
    overflow-y: scroll;
    text-decoration: none;
    text-align: left;
}
.label {
    color: #666;
    font-size: 12px;
    margin-bottom: 5px;
    display: block;
    text-align: left;
}
a {
    color: #666;
    text-decoration: none;
}
a:hover {
    color: #f76e00;
}
/* Navigation */

nav ul {
    padding: 0 20px;
}
nav li {
    list-style: none;
    float: left;
    margin-right: 20px;
    padding: 10px;
    font-weight: 300;
}
nav li.current {
    background: #f5f5f5;
    border: 1px solid #ccc;
    border-bottom: none;
}
nav li.current a {
    color: #777;
    cursor: default;
}
#audiobook {
    position: relative;
    height: 200px;
    width: 100%;
    background-color: #6FF;
}
</style>

<script>
function tamingselect()
{
    if(!document.getElementById && !document.createTextNode){return;}

// Classes for the link and the visible dropdown
    var ts_selectclass='turnintodpdn';  // class to identify selects
    var ts_listclass='turnintoselect';      // class to identify ULs
    var ts_boxclass='dropcont';         // parent element
    var ts_triggeron='activetrigger';       // class for the active trigger link
    var ts_triggeroff='trigger';            // class for the inactive trigger link
    var ts_dropdownclosed='dropdownhidden'; // closed dropdown
    var ts_dropdownopen='dropdownvisible';  // open dropdown
/*
    Turn all selects into DOM dropdowns
*/
    var count=0;
    var toreplace=new Array();
    var sels=document.getElementsByTagName('select');
    for(var i=0;i<sels.length;i++){
        if (ts_check(sels[i],ts_selectclass))
        {
            var hiddenfield=document.createElement('input');
            hiddenfield.name=sels[i].name;
            hiddenfield.type='hidden';
            hiddenfield.id=sels[i].id;
            hiddenfield.value=sels[i].options[0].value;
            sels[i].parentNode.insertBefore(hiddenfield,sels[i])
            var trigger=document.createElement('a');
            ts_addclass(trigger,ts_triggeroff);
            trigger.href='#';
            trigger.onclick=function(){
                ts_swapclass(this,ts_triggeroff,ts_triggeron)
                ts_swapclass(this.parentNode.getElementsByTagName('ul')[0],ts_dropdownclosed,ts_dropdownopen);
                return false;
            }
            trigger.appendChild(document.createTextNode(sels[i].options[0].text));
            sels[i].parentNode.insertBefore(trigger,sels[i]);
            var replaceUL=document.createElement('ul');
            for(var j=0;j<sels[i].getElementsByTagName('option').length;j++)
            {
                var newli=document.createElement('li');
                var newa=document.createElement('a');
                newli.v=sels[i].getElementsByTagName('option')[j].value;
                newli.elm=hiddenfield;
                newli.istrigger=trigger;
                newa.href='#';
                newa.appendChild(document.createTextNode(
                sels[i].getElementsByTagName('option')[j].text));
                newli.onclick=function(){ 
                    this.elm.value=this.v;
                    ts_swapclass(this.istrigger,ts_triggeron,ts_triggeroff);
                    ts_swapclass(this.parentNode,ts_dropdownopen,ts_dropdownclosed)
                    this.istrigger.firstChild.nodeValue=this.firstChild.firstChild.nodeValue;
                    return false;
                }
                newli.appendChild(newa);
                replaceUL.appendChild(newli);
            }
            ts_addclass(replaceUL,ts_dropdownclosed);
            var div=document.createElement('div');
            div.appendChild(replaceUL);
            ts_addclass(div,ts_boxclass);
            sels[i].parentNode.insertBefore(div,sels[i])
            toreplace[count]=sels[i];
            count++;
        }
    }

/*
    Turn all ULs with the class defined above into dropdown navigations
*/  

    var uls=document.getElementsByTagName('ul');
    for(var i=0;i<uls.length;i++)
    {
        if(ts_check(uls[i],ts_listclass))
        {
            var newform=document.createElement('form');
            var newselect=document.createElement('select');
            for(j=0;j<uls[i].getElementsByTagName('a').length;j++)
            {
                var newopt=document.createElement('option');
                newopt.value=uls[i].getElementsByTagName('a')[j].href;  
                newopt.appendChild(document.createTextNode(uls[i].getElementsByTagName('a')[j].innerHTML)); 
                newselect.appendChild(newopt);
            }
            newselect.onchange=function()
            {
                window.location=this.options[this.selectedIndex].value;
            }
            newform.appendChild(newselect);
            uls[i].parentNode.insertBefore(newform,uls[i]);
            toreplace[count]=uls[i];
            count++;
        }
    }
    for(i=0;i<count;i++){
        toreplace[i].parentNode.removeChild(toreplace[i]);
    }
    function ts_check(o,c)
    {
        return new RegExp('\\b'+c+'\\b').test(o.className);
    }
    function ts_swapclass(o,c1,c2)
    {
        var cn=o.className
        o.className=!ts_check(o,c1)?cn.replace(c2,c1):cn.replace(c1,c2);
    }
    function ts_addclass(o,c)
    {
        if(!ts_check(o,c)){o.className+=o.className==''?c:' '+c;}
    }
}

window.onload=function()
{
    tamingselect();
    // add more functions if necessary
}
</script>

</head>

<body>

<div id="dropdown2">
  <form action="">
    <label class="label">What is cost?</label>
    <select class="turnintodpdn">
      <option>This is:</option>
      <option value="1">Free</option>
      <option value="2">Not free</option>
    </select>
  </form>
</div>

</body>
</html>

In the head of the document I am adding this:

<script>
function NotFreeSelectCheck(nfSelect)
{
    if(nfSelect){
        slctOptionValue = document.getElementById("slctOption").value;
        if(slctOptionValue == nfSelect.value){
            document.getElementById("NotFreeDivCheck").style.display = "block";
            document.getElementById("ppaddrss").style.display = "block";
        }
        else{
            document.getElementById("NotFreeDivCheck").style.display = "none";
            document.getElementById("ppaddrss").style.display = "none";
        }
    }
    else{
        document.getElementById("NotFreeDivCheck").style.display = "none";
        document.getElementById("ppaddrss").style.display = "none";
    }
}
</script>

And here is the updated html:

<div id="dropdown2">
                  <form action="">
                    <label class="label">What is cost?</label>
                    <select class="turnintodpdn" id="getFvalue" onchange="NotFreeSelectCheck(this);">
                      <option>This is:</option>
                      <option value="1">Free</option>

<option id="slctOption" value="2">Not free</option>
                    </select>
                  </form>
                </div>


<div id="NotFreeDivCheck" style="display:none;">
Price field
</div>

<div id="ppaddrss" style="display:none;">
Payment Address
</div>

No matter what I do, I cannot get the divs to open when "Not free" is selected in the menu if it is added with the javascript in the first code example. If I remove the styling and javascript functions from the first example and make the menu a plain menu, the code works and the divs "NotFreeDivCheck" and "ppaddrss" are shown. What do I need to do to make this work?

Just to be clear, as you can see, this code works if the javascript from the first example is removed:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>

<script>
function NotFreeSelectCheck(nfSelect)
{
    if(nfSelect){
        slctOptionValue = document.getElementById("slctOption").value;
        if(slctOptionValue == nfSelect.value){
            document.getElementById("NotFreeDivCheck").style.display = "block";
            document.getElementById("ppaddrss").style.display = "block";
        }
        else{
            document.getElementById("NotFreeDivCheck").style.display = "none";
            document.getElementById("ppaddrss").style.display = "none";
        }
    }
    else{
        document.getElementById("NotFreeDivCheck").style.display = "none";
        document.getElementById("ppaddrss").style.display = "none";
    }
}
</script>

</head>

<body>

<div id="dropdown2">
  <form action="">
    <label class="label">What is cost?</label>
    <select id="getFvalue" onchange="NotFreeSelectCheck(this);">
      <option>This is:</option>
      <option value="1">Free</option>
      <option id="slctOption" value="2">Not free</option>
    </select>
  </form>
</div>

<div id="NotFreeDivCheck" style="display:none;"> Price field </div>

<div id="ppaddrss" style="display:none;"> Payment Address </div>

</body>
</html>

Please help and thanks!

1

There are 1 answers

2
Mark Leiber On BEST ANSWER

The script you're using converts all of the SELECT elements into DOM dropdowns, so this line of your function doesn't work:

slctOptionValue = document.getElementById("slctOption").value;

Because document.getElementById("slctOption") is not defined. You can hard-code that since it's just a single value:

slctOptionValue = 2;

Also, your onchange will never fire since the SELECT is being replaced. Instead modify this code:

newli.onclick=function(){ 
    this.elm.value=this.v;
    NotFreeSelectCheck(this.elm); /* Added this line */
    ts_swapclass(this.istrigger,ts_triggeron,ts_triggeroff);
    ts_swapclass(this.parentNode,ts_dropdownopen,ts_dropdownclosed)
    this.istrigger.firstChild.nodeValue=this.firstChild.firstChild.nodeValue;
    return false;
}

You should also run your script through JSHint. It is missing a few semicolons and has other issues that would be good to clean up.

Here is a jsfiddle: http://jsfiddle.net/3k6795dm/17/