Simple java script help

jakeselectronics

New Member
Messages
38
Reaction score
0
Points
0
I need some help with some Javascript code...

This is what I want to do.

I have a number of groups of radio buttons, for which i want to use to output some numbers.

This is the webpage here on which i want to do it.
Have a look just to get a rought idea....http://jakeselectronics.x10hosting.com/a.php


Now, I'll explain it a little better, I will refer to the picture below....
Example:
I check the radio button corresponding to 1, of bit 0 (bit 0 = 1)
I check the radio button corresponding to 0, of bit 1 (bit 1 = 0)
I check the radio button corresponding to 1, of bit 2 (bit 2 = 1)
Now I want to display these numbers in a line.... like... "101"
dsc06796e.jpg


I know there must be a simple way to do this and have been reading up on javascript and am just getting confused....

Can anyone give me a rough idea of the code

Thanks,
Jake.
 

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
Thought process....



radio buttons mean a form. Give it a name and id so I can reference it. I want the display to change when a radio button is clicked. I can add an 'onclick' handler to each radio button, but I think I will just add one to the form.

HTML:
<form id="theform" name="theform" onclick='test();'>
</form>



Ok, now add some radio buttons...Groups of two, a group having the same name (no ids here, ids have to be unique). There is no quick way to see the value of the checked button of a group, like bit01.value , so the 'value' attribute is more for documentation than programming.



HTML:
<form id="theform" name="theform" onclick='test();'>
<input type="radio" name="bit01" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit01" value="1" /> 1
<hr>
<input type="radio" name="bit02" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit02" value="1" /> 1
<hr>
<input type="radio" name="bit03" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit03" value="1"  /> 1
<hr>
<input type="radio" name="bit04" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit04" value="1"  /> 1
</form>



Now to the function test().

Javascript can access the form by 'document.theform' . You can then look at individual radio button groups by looking at 'document.theform.bit01' , etc. But javascript can also access all the elements of a form by using 'document.theform.elements' . If the form only has radio buttons, this is a list of the buttons, in order. So....



HTML:
  function test(){

    var binary_text_string = '' ;  // string of 0's and 1's to build

    var len = document.theform.elements.length ;

  }



Since you know how many radio buttons you have, you could just set len to 8 in this case. But if you add more buttons, you have to remember to change it. This way you don't have to bother.

Now you want to check out buttons two by two. If the first is checked, the digit is 0. If the second is checked (same as the first not checked), the digit is 1. So I will use a 'for' loop, incrementing by 2 instead of the usual 1



HTML:
  function test(){

    var binary_text_string = '' ;  // string of 0's and 1's to build

    var len = document.theform.elements.length ;

    for( i = 0; i < len ; i = i + 2 ){ // every 2 radio buttons

       val = document.theform.elements[i].checked ? '0' : '1' 

    }

  }



I used the ternary



test ? val1 : val2



operator which is more compact than an if-else construct.

So val is '0' or '1' depending on that radio button, now I add it to the output string...





HTML:
  function test(){

    var binary_text_string = '' ;  // string of 0's and 1's to build

    var len = document.theform.elements.length ;

    for( i = 0; i < len ; i = i + 2 ){

       val = document.theform.elements[i].checked ? '0' : '1' 

       binary_text_string = binary_text_string  +  val ;

    }
  }



Now the only thing left is to display the binary string. Easiest is to put a <span> element with an id as a target...

HTML:
<span id="binarydisplay" />0000</span>

And then insert the final value into the span... use document.getElementById() to grab the span and then use .innerHTML to insert the text...
HTML:
  function test(){

    var binary_text_string = '' ;  // string of 0's and 1's to build

    var len = document.theform.elements.length ;

    for( i = 0; i < len ; i = i + 2 ){

       val = document.theform.elements[i].checked ? '0' : '1' 

       binary_text_string = binary_text_string  +  val ;

    }
     document.getElementById('binarydisplay').innerHTML =  binary_text_string  ;
  }

The whole thing...

HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<title>JavaScipt Test Page</title>
<script type="text/javascript">

  function test(){

    var binary_text_string = '' ;

    var len = document.theform.elements.length ;
    for( i = 0; i < len ; i = i + 2 ){
       val = document.theform.elements[i].checked ? '0' : '1' 
       binary_text_string = binary_text_string  +  val ;
       
    }
    document.getElementById('binarydisplay').innerHTML =  binary_text_string  ;

  }

</script>

<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
<form id="theform" name="theform" onclick='test();'>

<input type="radio" name="bit01" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit01" value="1" /> 1

<hr>

<input type="radio" name="bit02" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit02" value="1" /> 1

<hr>

<input type="radio" name="bit03" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit03" value="1"  /> 1

<hr>

<input type="radio" name="bit04" value="0"  checked='checked'/> 0
<br />
<input type="radio" name="bit04" value="1"  /> 1

<hr>
</form>

<span id="binarydisplay" />0000</span>

</body>
</html>
 

jakeselectronics

New Member
Messages
38
Reaction score
0
Points
0
Thanks descalzo ,this works well.

But I have a problem.
If you look at my webpage again (http://www.jakeselectronics.x10hosting.com/a.php), You will notice that the last 8 radio buttons are for the selection of bits 4,1, and 0....
As in, they fit here within the 14bit number.
xxxxxxxxxxxxxx (bit 13 is far left, bit 0 is far right)

So can I take the value of the radio button, test it in an IF statment and store the number as 3 seperate variables. Then display the variables in the order they need to appear....

Something like this to store them as 3 separte variables......

Code:
if (bit410=111)
  {
  x=1, y=1, z=1
  }
else if (bit410=110)
  {
  x=1, y=1, z=0
  }
else if (bit410=101)
  {
  x=1, y=0, z=1
  }
else if (bit410=100)
  {
  x=1, y=0, z=0
  }
else if (bit410=011)
  {
  x=0, y=1, z=1
  }
else if (bit410=010)
  {
  x=0, y=1, z=0
  }
else if (bit410=001)
  {
  x=0, y=0, z=1
  }
else if (bit410=000)
  {
  x=0, y=0, z=0
  }
else
  {
  x=0, y=0, z=0
  }




Edit:
have a look at this link too
http://www.jakeselectronics.x10hosting.com/b.php
This give the idea of what I want to happen...
except the section i mentioned above isnt working.

Thanks for the help by the way...
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Instead of a giant "if" sequence, try mask-and-shift (or shift-and-mask). For one thing, octal literals won't bite you on the ass (011 is 9 decimal).

Code:
<input type="radio" name="bit410" value="7" onclick="count()">111 = ...
<input type="radio" name="bit410" value="6" onclick="count()">110 = ...
...
   x = bit410.value >> 2;
   y = (bit410.value >> 1)&1;
   z = bit410.value & 1;
...
Far from optimal, but better than all the if blocks. Are you going to have pages for more than one microcontroller?

Also, a table based layout? Really?
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
I dont know any other way :s

The other way is to define solely the structure of the document using HTML, then apply layout using a style sheet.

What follows is an alternative implementation of both the script and document style. You can reuse it on any number of pages. For the script to work, you start an input's name with "bit" (or "b" or "bits"), followed by a list of bit positions to set or clear using the input's value. In the list, use an underscore or a dash to separate positions, where an underscore will skip intervening positions and a dash will include them. For example, "<input name='bit5_7_9-12' value='57'/>" will set bits 5,10,11,12 to 1 and bits 7,9 to 0 (57 == 0b111001). Also, have an input named "display" and call initPICForm(...) on the form with the radio buttons. The script takes care of the rest, including sizing the display field and registering the event listeners. It still needs to be tested on all IE versions.

Note you could easily have PHP (or other server side script) generate the form from a fairly terse description of the bit fields.
HTML:
   ...
  <link href="style/PIC.css" rel="stylesheet" type="text/css">
</head>
<body>
   ...
    <form name="PICbits" onsubmit="update(this); return false;">
      <ul class="bitfields">
        <li>bit 13: <span class="bitName">CP</span>: Flash Program Memory Code Protection bit(2)<ul>
            <li><input type="radio" name="bit13" value="1" />1 = Code protection off</li>
            <li><input type="radio" name="bit13" value="0" checked/>
                0 = 0000h to 0FFFh (<span class="controller">PIC16F648A</span>), 
                             07FFh (<span class="controller">PIC16F628A</span>) or 
                             03FFh (<span class="controller">PIC16F627A</span>) code protected</li>
        </ul></li>

        <li>bits 12-9: unused</li>

        <li>bit 8: <ul>
            <li><input type="radio" name="bit8" value="1" checked/>1 = </li>
            <li><input type="radio" name="bit8" value="0"/>0 = </li>
        </ul></li>
....
        <li>bit 4,1,0: <span class="bitName">FOSC2:FOSC0</span>:Oscillator Selection bits(4)<ul>
            <li><input type="radio" name="bit0_1_4" value="7"/>111 = </li>
            <li><input type="radio" name="bit0_1_4" value="6"/>110 = </li>
            <li><input type="radio" name="bit0_1_4" value="5"/>101 = ...</li>
            <li><input type="radio" name="bit0_1_4" value="4"/>100 = ...</li>
            <li><input type="radio" name="bit0_1_4" value="3"/>011 = ...</li>
            <li><input type="radio" name="bit0_1_4" value="2"/>010 = ...</li>
            <li><input type="radio" name="bit0_1_4" value="1"/>001 = ...</li>
            <li><input type="radio" name="bit0_1_4" value="0"/>000 = ...</li>
        </ul></li>
      </ul>
      <input name="display" readonly size='0' />
    </form>
    <script src="js/PIC.js"></script>
    <script type="text/javascript">
      initPICForm(document.forms.PICbits);
    </script>

PIC.js:
Code:
function BitVector(n) {
    this.length = n || 16;
    this.data=0;
}
BitVector.prototype.put = function(i, v) {
    this.data = (this.data & ~(1 << i)) | (v << i);
};
BitVector.prototype.putAll = function(pos, val) {
    pos = pos.sort();
    for (p in pos) {
        this.put(pos[p], val & 1);
        val >>= 1;
    }
};
BitVector.prototype.at = function(i) {
    (this.data >> i) & 1;
};
BitVector.prototype.toString_big = function() {
    return this.data.toString(2).pad(this.length, '0');
};
BitVector.prototype.toString_little = function() {
    return this.toString_big().reverse();
};
BitVector.prototype.toString = BitVector.prototype.toString_little;



String.prototype.pad = function(minWidth, padChar) {
    padChar = padChar || ' ';
    pad = Math.max(0, minWidth - this.length);
    /* quick 'n' dirty padding. Could also define a String.repeat(n) method, 
	   using peasant multiplication */
    return (new Array(pad+1)).join(padChar) + this;
};
String.prototype.reverse = function() {
    return this.split('').reverse().join('');
};


function initPICForm(form) {
    var size=0, indices;
    form.bits=new BitVector();
    form.bitFields = {};
    for (i in form.elements) {
        el = form.elements[i];
        if (/^b(?:its?)?\d([-_0-9]*\d)?$/.test(el.name)) {
            if (!form.bitFields[el.name]) {
                indices=form.bitFields[el.name]=bitIndices(el.name);
                size = Math.max(size, indices[indices.length-1]);
            }
            el.indices=form.bitFields[el.name];
            if ('radio' == el.type) {
                el.onclick = function() {setBits(this);};
            }
            if (el.checked) {
                setBits(el);
            }
        }
    }
	++size;
    form.bits.length = size;
    form.display.size = Math.max(size, form.display.size);
    display(form);
}


function bitIndices(name) {
    var indices = [],
        spec, n,
        specs = name.match(/\d+(?:-\d+)?/g);
    for (s in specs) {
        if (spec = specs[s].match(/(\d+)-(\d+)/)) {
            n = parseInt(spec[2]);
            for (var m=parseInt(spec[1]); m <= n;++m) {
                indices.push(m);
            }
        } else {
            indices.push(specs[s]);
        }
    }
    return indices.sort();
}

function setBits(input) {
    input.form.bits.putAll(
        input.indices || (input.indices=bitIndices(input.name)), 
        input.value);
    display(input.form);
}

function display(form) {
    form.display.value = form.bits.toString();
}

function update(form) {
    for (i in form.elements) {
        if (form.elements[i].indices) {
            form.bits.putAll(form.elements[i].indices, form.elements[i].indices);
        }
    }
    return false;
}

The maximum length of a BitVector (as implemented) is limited to the size of a platform integer (probably 32 bits). As you're probably not dealing with 64 bit microcontrollers, this isn't an issue. If you don't like the implementation of BitVector, you can easily replace it with one based on an Array. As long as you don't change the BitVector API (in particular, BitVector.put, .putAll, .toString and .length), you don't need to change anything else.

You could have a checkbox to easily toggle between bit endianness in the display. You could also change the display from a simple field to a labeled table, rather like the first two rows of the current table.
HTML:
  <thead>
    <tr><th>CP</th><th>-</th><th>CPD</th>...</tr>
  </thead>
  <tbody>
    <tr><td id="b13">0</td><td id="b9-12">00000</td><td id="b8">0</td>...</tr>
  </tbody>
</table>

PIC.css:
Code:
ul.bitfields, .bitfields ul {
    list-style-type: none;
}
span.controller {
    text-decoration: underline;
}
.bitName {
    font-weight: bold;
}

// ...
 
Last edited:
Top