2
$\begingroup$

Is it possible to declare a type in InputFunction to only accept positive Integers as input?

I know i can create an InputField only allowing numbers and check if the value is a positive integer:

InputField[Dynamic[x], Number]

Then i could check the value later:

If[Positive@x && IntegerQ@x,...

But is it also possible to already limit the allowed input in the InputField to match those conditions? So - and . are not allowed.

$\endgroup$
4
$\begingroup$

To control the precise behavior of InputFields for various keyboard interactions is not exactly something where Mathematica shines, but there are some possbilities with which you can achieve what you want:

If you want to do certain checks of the user input you can do so with a second argument to Dynamic, which will not only work for InputField but also for other gui elements. Here is how you can only allow input which is larger than zero:

InputField[Dynamic[x, Function[If[# >= 0, x = #]]], Number]

you'll note that for invalid input this will just keep the old value. Here is a variation that will only allow values between 0 and 1 and change the input you give to the nearest value in that interval:

InputField[Dynamic[x, Function[x = Clip[#, {0, 1}]]], Number]

If you want to disable certain characters in the input, there are two ways (with many variations) which I know. You can either switch to a String InputField with ContinuousAction->True like this:

InputField[
  Dynamic[ToString[x],
    Function[x = ToExpression@StringReplace[#, {
      d : DigitCharacter :> d,
      _ :> ""
    }]]], 
  String, ContinuousAction -> True
]

again you can adopt the code in the second argument to Dynamic to meet your needs, but my experience is that this will often behave strange concerning focus and the cursor position.

The other possibility which is probably somewhat more limited but I think does behave much better is to only pass those keyboard events to the InputField which you want it to see, like so:

EventHandler[
  InputField[Dynamic[x], Number], 
  {
    {"KeyDown", "."} :> Null, 
    {"KeyDown", "-"} :> Null
  }, PassEventsDown -> False
]

note that I did set the PassEventsDown to False explicitly to make more clear what actually happens, but as it is the default setting you'd not necessarily need it. Of course you could combine this with a second argument for Dynamic to make more checks/restrictions.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ I really like the EvenHandler solution. I'll try this out, but it already looks really promising. $\endgroup$ – kon Apr 4 '15 at 20:27
  • $\begingroup$ yes, for exactly this problem it seems to be a good solution. Unfortunatly it isn't easy to generalize for more complicated cases... $\endgroup$ – Albert Retey Apr 4 '15 at 21:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.