How do I stop a count

I have create a spinnrer (numeric up and down field) in my form. Below is the code for it:

 <form action="create_session.php" method="post" name="createsession">        <!-- This will post the form to its own page"-->
     
      <table cellpadding="0" cellspacing="0" border="0">
<tr>
<td rowspan="2"><input type="text" name="number" value="0" style="width:50px;height:23px;font-weight:bold;" /></td>
<td><input type="button" value=" ^ " onclick="this.form.number.value++;" style="font-size:7px;margin:0;padding:0;width:20px;height:13px;" ></td>
</tr>
<tr>
<td><input type=button value=" v " onclick="this.form.number.value--;" style="font-size:7px;margin:0;padding:0;width:20px;height:12px;" ></td>
</tr>
</table>
      <p><input type="submit" value="Submit" name="submit" /></p>
    </form>

Now what my question is that if my numeric field can go below 0 into the minus numbers. I don’t want this, I want the count to stop at 0 but I do not know how to do this. It will obviously involve an if statment for if count = 0 but how do you say stop to a count?

Thank You

A similar question came up last week.

The spinner in this code allows you to optionally hold down the mouse key on the up/down arrows and the spinner values will automatically “spin” up or down.

The range of the spinner values is 1-24, but you can change to suit.

<!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>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title></title>
        <style type="text/css">
            #hrsCont {
                width: 70px;
            }
            #hrsCont textarea {
                overflow: hidden;
            }
            .btnScrollHrs {
                clear: both;
                float: right;
            }
        </style>
        <script type="text/javascript">
            var maxHrs = 24;
            var minHrs = 1;
            var timer;
            var speed = 200;  //milliseconds between scroll values

            function scrollHrs(dir){
                txtHoursO.value = validateHrs(Number(txtHoursO.value) + dir);
                timer = setTimeout(function(){scrollHrs(dir);},speed);
            }

            function validateHrs(hrs) {
                if(hrs > maxHrs) {hrs = maxHrs;}
                if(hrs < minHrs) {hrs = minHrs;}
                return hrs;
            }

            window.onload=function(){
                txtHoursO = document.getElementById('txtHours');
                txtHoursO.value = minHrs;
                txtHoursO.onkeyup=function(){
                    var regex = /^[0-9]*$/;
                    if(!regex.test(this.value)){
                        this.value = this.value.substring(0,this.value.length-1);
                        return;
                    }
                    this.value = validateHrs(Number(txtHoursO.value));
                }
                var btnScrollHrsO = document.getElementsByClassName('btnScrollHrs');
                btnScrollHrsO[0].onmousedown = function(){scrollHrs(1);}
                btnScrollHrsO[1].onmousedown = function(){scrollHrs(-1);}
                btnScrollHrsO[0].onmouseup = btnScrollHrsO[1].onmouseup = function(){clearTimeout(timer);}
                btnScrollHrsO[0].onclick = btnScrollHrsO[1].onclick = function(){return false;}
            }
        </script>
    </head>
    <body>
        <form action="" method="post">
            <p>
                Hold down the left mouse key on either the up or down arrow to scroll values up or down<br />
                or enter a number directly in the box.
            </p>
            <fieldset id="hrsCont">
                <textarea name="txtHours" id="txtHours" cols="2" rows="1"></textarea>
                <button class="btnScrollHrs">^</button>
                <button class="btnScrollHrs">v</button>
            </fieldset>
        </form>
    </body>
</html>

Sorry about that, I will next time edit any previous question if I have a question in that particular field.

Thank You

I don’t understand what you are sorry about :(. I wasn’t having a go at you.

Someone else asked a question about a spinner last week and I just posted the same code in reply to your post here as I did to the other query last week.

Edit:

ok I just twigged :slight_smile:

It was your thread last week that I originally replied to :smiley:

Hi,

No I meant I knew I shouldn’t of posted a new thread and I should of editted the rrevious question I asked so that it does not cause duplicate threads. By the way the example you showed me is very good but what I want to do is add another spinner (for minutes) next to the spinner you have gave me. I simply just copied the code in the css and pasted it below in the <style> tag which is fine.

But when I copy the functions and paste it below the original finctions and change the function names (from hrs to mins), my second spinner works correctly but my first spinner does not display zero in the text area or follow the rest of the function.

Where am I suppose to paste the coped function so that both spinners are working?

Thank You

So long as you don’t mind it being available only to those who support HTML5, you can use the number spinner that’s built in to HTML forms, with no scripting at all.


<input type="number" min="0" max="24">

There’s a few ways you can do this:

  1. use a HTML5 specific element

  2. create separate functions and variables as per my original demo code for each spinner. But this can be a real pain to maintain with future changes.

  3. (my preferred option) create a spinner javascript object and then create instances of it for each spinner in your html. This is much easier to maintain because if you want to add methods or properties to the spinner object you only need to do it once rather than for each spinner function as would be required with option 2.

Something like this:

<!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>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title></title>
        <style type="text/css">
            .spinnerCont {
                clear: both;
                width: 70px;
            }
            .spinnerCont textarea {
                overflow: hidden;
            }
            .btnScroll {
                clear: both;
                float: right;
            }
        </style>
        <script type="text/javascript">
            function Spinner(elem,min, max){
                this.elem = elem;
                this.elem.value = min;
                this.min = min;
                this.max = max;
                this.timer;
                this.speed = 100; //milliseconds between scroll values
                var selfO = this;

                this.elem.onkeyup = function(){
                    var regex = /^[0-9]*$/;
                    if(!regex.test(selfO.elem.value)){
                        selfO.elem.value = selfO.elem.value.substring(0,selfO.elem.value.length-1);
                        return;
                    }
                    selfO.validateValue();
                }

                this.validateValue = function(){
                    if(Number(selfO.elem.value) > selfO.max) {selfO.elem.value = selfO.max;}
                    if(Number(selfO.elem.value) < selfO.min) {selfO.elem.value = selfO.min;}
                }

                this.stopSpinning = function(){
                    clearTimeout(selfO.timer);
                }

                this.spinVal = function(dir){
                    selfO.elem.value = Number(selfO.elem.value) + dir;
                    selfO.validateValue();
                    selfO.timer = setTimeout(function(){selfO.spinVal(dir);},selfO.speed);
                }

            }

            window.onload=function(){
                //create the Spinner objects
                var SpinnerHrs = new Spinner(document.getElementById('txtHours'),0,23);
                var SpinnerMins = new Spinner(document.getElementById('txtMins'),0,59);

                //assign the scoll buttons' events
                var btnHrsUpO = document.getElementById('btnHrsUp');
                btnHrsUpO.onmousedown = function(){SpinnerHrs.spinVal(1);}
                btnHrsUpO.onmouseup = function(){SpinnerHrs.stopSpinning();}

                var btnHrsDownO = document.getElementById('btnHrsDown');
                btnHrsDownO.onmousedown = function(){SpinnerHrs.spinVal(-1);}
                btnHrsDownO.onmouseup = function(){SpinnerHrs.stopSpinning();}

                var btnMinUpO = document.getElementById('btnMinUp');
                btnMinUpO.onmousedown = function(){SpinnerMins.spinVal(1);}
                btnMinUpO.onmouseup = function(){SpinnerMins.stopSpinning();}

                var btnMinDownO = document.getElementById('btnMinDown');
                btnMinDownO.onmousedown = function(){SpinnerMins.spinVal(-1);}
                btnMinDownO.onmouseup = function(){SpinnerMins.stopSpinning();}

                var btnScrollO = document.getElementsByClassName('btnScroll');
                for(i=0; i < btnScrollO.length; i++){
                    btnScrollO[i].onclick = function(){return false;}
                }
            }
        </script>
    </head>
    <body>
        <form action="" method="post">
            <p>
                Hold down the left mouse key on either the up or down arrow to scroll values up or down<br />
                or enter a number directly in the box.
            </p>
            <div class="spinnerCont">
                <p>Hours <br /> (0-23)</p>
                <textarea class="spinner" name="txtHours" id="txtHours" cols="2" rows="1"></textarea>
                <button class="btnScroll" id="btnHrsUp">^</button>
                <button class="btnScroll" id="btnHrsDown">v</button>
            </div>
            <div class="spinnerCont">
                <p>Minutes <br /> (0-59)</p>
                <textarea class="spinner" name="txtmins" id="txtMins" cols="2" rows="1"></textarea>
                <button class="btnScroll" id="btnMinUp">^</button>
                <button class="btnScroll" id="btnMinDown">v</button>
            </div>
        </form>
    </body>
</html>

hmmmmm…:scratch:

yep, browser support for HTML5 varies greatly.

<input type="number" min="0" max="24">

is not supported (as a spinner) in my IE9 or FF8 but it is supported in my Opera 11. An even in Opera, if I enter a value of 89, even though 24 is supposed to be the max, it accepts 89 :eek:

Probably better sticking with the javascript object for now until HTML5 is eventually released and support for it in the browsers increases.

Hi,

I will be better off going through the javascript code you have showed me then risking it going for HTML5 spinner because I need my application to work on internet explorer, google chrome and safari. Thank you for the post webdev 1958 and thank you paul_wilkins for your reply as well. :slight_smile:

I have just realised one thing though on the two spinners created thaks to your javascript code. If I enter 0000045 for the minutes spinner, it aceppts it. Same if I did 000022 for the hours spinner? In the first code you sent me on creating just one spinner between 1-24, if I entered 022 it quickly changes it to 22. Why is this difference between both the codes.

In the first code any values with leading zeros will initially be set to the min value, in this case a value of 1 due to this line


if(hrs < minHrs) {hrs = minHrs;}

The current spinner has a fixed increment of 1.

The next step, if you are planning to make the spinner more flexible, is to allow each instance of the spinner to increment at different values. For example, you might have a spinner incrementing at 0.5 and another incrementing at 0.25

In this case, the spinner object would need another property called “incr” or “step” or something similar and then include that property where you calculate the next spinner value depending on whether you are spinning up or down. The validation code would also need to be altered a little.

If you need more help, post the code you have so far and we can try to help.

Hi,

I can see what you mean by creating a couple of vaiables and call them one the highest nubmer and one the lowest number and the state if number entered in spinner is lower that the minimum from the variable then go back to minimum value and same with maximum value but how does it know which spinner it is referring to, to sort out this problem. That is the only problem I can see.

Below is current 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></title>
        <style type="text/css">
            .spinner {
                clear: both;
                width: 30px;
                height:20px;
            }
            .spinner textarea {
                overflow: hidden;
                resize:none;
                font-size:18px;
                font-weight:bold;
            }
            .scrollBtn {
                clear: both;
                float: right;
            }
        </style>
        <script type="text/javascript">
            function Spinner(elem,min, max){
                this.elem = elem;
                this.elem.value = min;
                this.min = min;
                this.max = max;
                this.timer;
                this.speed = 150; //milliseconds between scroll values
                var selfO = this;
 
                this.elem.onkeyup = function(){
                    var regex = /^[0-9]*$/;
                    if(!regex.test(selfO.elem.value)){
                        selfO.elem.value = selfO.elem.value.substring(0,selfO.elem.value.length-1);
                        return;
                    }
                    selfO.validateValue();
                }
 
                this.validateValue = function(){
                    if(Number(selfO.elem.value) > selfO.max) {selfO.elem.value = selfO.max;}
                    if(Number(selfO.elem.value) < selfO.min) {selfO.elem.value = selfO.min;}
                }
 
                this.stopSpinning = function(){
                    clearTimeout(selfO.timer);
                }
 
                this.spinValue = function(dir){
                    selfO.elem.value = Number(selfO.elem.value) + dir;
                    selfO.validateValue();
                    selfO.timer = setTimeout(function(){selfO.spinValue(dir);},selfO.speed);
                }
 
            }
 
            window.onload=function(){
                //create the Spinner objects
                var SpinnerHours = new Spinner(document.getElementById('txtHours'),0,23);
                var SpinnerMins = new Spinner(document.getElementById('txtMins'),0,59);
                var SpinnerSecs = new Spinner(document.getElementById('txtSecs'),0,59);
 
                //assign the scoll buttons' events
                var btnHoursUpO = document.getElementById('btnHoursUp');
                btnHoursUpO.onmousedown = function(){SpinnerHours.spinValue(1);}
                btnHoursUpO.onmouseup = function(){SpinnerHours.stopSpinning();}
 
                var btnHoursDownO = document.getElementById('btnHoursDown');
                btnHoursDownO.onmousedown = function(){SpinnerHours.spinValue(-1);}
                btnHoursDownO.onmouseup = function(){SpinnerHours.stopSpinning();}
 
                var btnMinsUpO = document.getElementById('btnMinsUp');
                btnMinsUpO.onmousedown = function(){SpinnerMins.spinValue(1);}
                btnMinsUpO.onmouseup = function(){SpinnerMins.stopSpinning();}
 
                var btnMinsDownO = document.getElementById('btnMinsDown');
                btnMinsDownO.onmousedown = function(){SpinnerMins.spinValue(-1);}
                btnMinsDownO.onmouseup = function(){SpinnerMins.stopSpinning();}
 
                var btnSecsUpO = document.getElementById('btnSecsUp');
                btnSecsUpO.onmousedown = function(){SpinnerSecs.spinValue(1);}
                btnSecsUpO.onmouseup = function(){SpinnerSecs.stopSpinning();}
 
                var btnSecsDownO = document.getElementById('btnSecsDown');
                btnSecsDownO.onmousedown = function(){SpinnerSecs.spinValue(-1);}
                btnSecsDownO.onmouseup = function(){SpinnerSecs.stopSpinning();}
                
                var scrollBtnO = document.getElementsByClassName('scrollBtn');
                for(i=0; i < scrollBtnO.length; i++){
                    scrollBtnO[i].onclick = function(){return false;}
                }
            }
        </script>
    </head>
    <body>
        <form action="" method="post">
            <p>
                Hold down the left mouse key on either the up or down arrow to scroll values up or down<br />
                or enter a number directly in the box.
            </p>
            <table>
                <tr>
                <td>Hrs</td>
                <td class="spinner"><textarea class="spinner" name="txtHours" id="txtHours" cols="2" rows="1"></textarea></td>
                <td><button class="scrollBtn" id="btnHoursUp"><img src="Images/black_uppointing_triangle.png" alt="Increase" /></button>
                <button class="scrollBtn" id="btnHoursDown"><img src="Images/black_downpointing_triangle.png" alt="Decrease" /></button></td>
                <td>Mins</td>
                <td class="spinner"><textarea class="spinner" name="txtmins" id="txtMins" cols="2" rows="1"></textarea></td>
                <td><button class="scrollBtn" id="btnMinsUp"><img src="Images/black_uppointing_triangle.png" alt="Increase" /></button>
                <button class="scrollBtn" id="btnMinsDown"><img src="Images/black_downpointing_triangle.png" alt="Decrease" /></button></td>
                <td>Secs</td>
                <td class="spinner"><textarea class="spinner" name="txtsecs" id="txtSecs" cols="2" rows="1"></textarea></td>
                <td><button class="scrollBtn" id="btnSecsUp"><img src="Images/black_uppointing_triangle.png" alt="Increase" /></button>
                <button class="scrollBtn" id="btnSecsDown"><img src="Images/black_downpointing_triangle.png" alt="Decrease" /></button></td>
            </tr>
            </table>
        </form>
    </body>
</html>

You are creating an instance of the Spinner for each pair of up/down spinner buttons…eg… the up/down arrows for the minutes spinner are controlling the SpinnerMins instance

var SpinnerMins = new Spinner(document.getElementById('txtMins'),0,59);

The up arrow of the minutes spinner is assigned to run the spinVal() function of the SpinnerMins instance when the mouse key is pressed down.


btnMinsUpO.onmousedown = function(){SpinnerMins.spinValue(1);}

Also each spinner instance has it’s own values, separate from the other instances, for the min/max etc properties.

so do you write the code like this:

if(SpinnerMins < min) {min = SpinnerMins;}
if(SpinnerHours < min) {min = SpinnerHours;}
if(SpinnerSecs < min) {min = SpinnerSecs;}

I don’t follow what you are trying to do.

If you are trying to make sure that any manually entered value in the spinner is between the min and max values for that instance of the spinner, the spinner object already does that in the validateValue() function.
[URL=“http://www.javascriptkit.com/javatutors/oopjs2.shtml”]
This tutorial on javascript OOP might help you understand objects and instances of an object.

No what I mean is that it works fine the spinner but I don’t want the spinner to let me enter 000045 or 00000000000034, if I can put a length for each spinner then that will be better so that 000045 is displayed as 45 and 0000000000034 is displayed as 34. I think that will be better.

ok, then all you need to do is remove any leading 0’s as the user is manually entering a value.


              this.elem.onkeyup = function(){
                    [COLOR=#ff0000]selfO.elem.value.replace(/^0/g,'');
                    var regex = /^[1-9]*$/;[/COLOR]
                    if(!regex.test(selfO.elem.value)){
                        selfO.elem.value = selfO.elem.value.substring(0,selfO.elem.value.length-1);
                        return;
                    }
                    selfO.validateValue();
                }

Hi,

Thanks that worked really well. Thank You :slight_smile:

glad it’s sorted :slight_smile:

One other thing you need to be aware of, especially if the form data is going into a database, is that you really should also validate all the form data in the server side script (php) as well because:

  1. not all browsers will have javascript enabled

  2. some users might deliberately turn off javascript in their browser for whatever reason.

  3. some malicious users might send bogus data directly to your server side script, bypassing the html <form> altogether.