Mutually exclusive text inputs - resetter using jQuery?

I have 3 text elements on a form which cause an Ajax function to be called (returning a series of dates).

The html looks like this;


<form id="seriesForm">
<input type=text id="days" value="" />
<input type=text id="weeks" value="" />
<input type=text id="months" value="" />
</form>

There is a button element that when clicked then picks up the values from the form and sends it to the backend using Ajax. If “days” has a value then the next x days are presented, if “weeks” the same day for the next x weeks is presented and so on.

If a user enters 2 in “days”, and then decides that it should be 2 in “weeks” and removes the 2 in “days” then this works fine, but if they forget to remove the first value, then nothing appears to happen.

So, I would like the entry in that form of text inputs to behave mutually exclusively.

I do not want to use radio buttons for this part of the job.

I already load jQuery (1.4.2) so can anyone tell me is there something already in existence in jQuery which will help me with this?

I face this situation in a couple of places so I’m really looking for something capable of taking some arguments, or maybe something which will detect a class mutually “mutually_exclusive” or some other clever ruse.

I googled around, and hope that mutually exclusive is the correct term, and that turns up loads of code for radios and checkboxes, but nothing about plain text inputs. So I am sure I can hack something around that stuff, and I know I could quite easily pop up an alerts saying “you cannot enter 2 values, remove one” but that defies my wish to make this as user-friendly as I can.

I am pretty sure I am not alone in doing this, and wondered - can anyone give me a leg up?

If not can you suggest some code/links to code.

Thanks

You could add an onchange event on each of the inputs that clears the other inputs, like


$("#days").change( function() { $("#weeks,#months").val(""); } );

(and of course do the same for #weeks and #months)

And yes, mutually exclusive is the correct term here IMHO :slight_smile:

Yup, that looks like a simple way round the problem for this example, thank you.

Imagining you had say, 7 of such elements it’d be a right nonsense though - wordy and error prone.


// pseudo code
function zeroTheOthers( notme )
others = Array('day', 'week', 'month') ;

event.happened

so others.value='' ;

// but not me, the last clicked
notme = whateverItWas ;

}

So the next step would be to maybe have a function that you can write concrete values to.

Then to further “decouple and anonymize” this function, inject the array, or lift it from the DOM somehow?

Or you could forget about the function, wrap a <div id=“zero-out”> around all the fields, and use the following snippet:


$("#zero-out :input").each(function() {
  $(this).keydown(function() {
    $("#zero-out :input").not(this).val("");
  });
});

Gotta love jQuery :slight_smile:

Thats very nice, thank you, what do I need to do now to capture the onkeydown event on an input in the form surrounded by the zero-out div?

I tried to create a listener using:

$(‘#xero-out :input’).keydown(‘checkit’) ;

But I don’t seem to be able to get a hook into the DOM.

The code below works absolutely fine, but I am pretty sure I can eliminate these instructions

onkeydown=“checkit();”

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.1 Strict//EN">
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>test</title>
<meta http-equiv="expires" content="1 Aug 1990 01:00:00 GMT">
<script src='jquery-1.4.2.min.js'	type='text/Javascript'></script>

<script>
function checkit(){
$("#zero-out :input").each(function() {
 $(this).keydown(function() {
   $("#zero-out :input").not(this).val("");
 });
});
}
</script>
</head>
<body>

<form id="seriesForm" name="seriesForm" method="GET" 
action ="./test.htm">
<div id="zero-out">
<input type=text onkeydown="checkit();" name="days" id="days" value="" /><br /> 
<input type=text onkeydown="checkit();" name="weeks" id="weeks" value="" /><br /> 
<input type=text onkeydown="checkit();" name="months" id="months" value="" /><br /> 
</div>

<button onclick="document.seriesForm.submit();">Checkit</button>
</form>

<?php

if( isset( $_GET ) )
var_dump( $_GET ) ;

?>
</body>
</html>

Thanks again.

You can just put the javascript at the bottom of the <body>, or use $(document).ready()
No need for onkeydown in the HTML.

Just in case there are any other jquery n00bs out there …


<script>
function checkit(){
$("#zero-out :input").each(function() {
 $(this).keydown(function() {
   $("#zero-out :input").not(this).val("");
 });
});
}

$('document').ready( function(){
$("#zero-out :input").keydown(function(){checkit()});
});
</script>

Put that in your doc head, and wrap a div whose id is ‘zero-out’ round those text inputs who need to be made mutually exclusive.

Tada.

Thank you ScallioXTX

I actually meant:


$('document').ready( function() {
 $("#zero-out :input").each( function() {
  $(this).keydown( function() {
    $("#zero-out :input").not(this).val("");
   });
  });
});

No need to define onkeydown twice, and no need for extra functions, anonymous functions work just fine :slight_smile:

Yes, thats much better thank you.

Having to upgrade my thinking about how to use jQuery, thx :wink:

For me it helped to stop viewing jQuery as an “extension” to javascript, but to view it as a language on it’s own. I know it’s not technically correct, since jQuery is written in javascript, but when you start to view jQuery as it’s own language, and not first think out how the code would be in plain javascript and then “convert” it to jQuery, you can really get more of jQuery. As least that’s how it worked for me :slight_smile:

Just out of curiosity, why are you using the :input selector? It selects all form controls:

Surely just '#zero-out input' is better, or maybe '#zero-out input[type=text]'?

I use :input out of habit. I agree #zero-out[type=“text”] would be better here.