0

I have a input field which is a percent value, i am trying for it to display as % when not focused in and when focused in it will loose the %, also the input field needs to avoid chars on it. I'm using a type"text" input field with some jQuery.

$(document).ready(function() {
  $('input.percent').percentInput();
});
(function($) {
          $.fn.percentInput = function() {
            $(this).change(function(){
              var c = this.selectionStart,
                  r = /[^0-9]/gi,
                  v = $(this).val();
              if(r.test(v)) {
                $(this).val(v.replace(r, ''));
                c--;
              }
              this.setSelectionRange(c, c);
            });
            $(this).focusout(function(){
              $(this).val(this.value + "%");
            });
            $(this).focusin(function(){
              $(this).val(this.value.replace('%',''));
            });
          };
        })(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="percent" value="2"></input>
<input class="percent" value="4"></input>

on the snippet it does not behave the same as on my app, not sure why but the intended result is for it to erase any char that is not a digit or "only" 1 % sign.

4
  • I notice that you are leaving the type="text" attribute out of your html input elements. I didn't know you could do that. Do inputs default to "text" when you leave that out? I wouldn't rely on that unless you know the specification defaults to "text". Commented Jan 21, 2020 at 0:28
  • 1
    @LonnieBest They do, although it is better practice to explicitly specify them Commented Jan 21, 2020 at 0:29
  • If you want it to prevent the non-numeric characters as you type, you could use the keydown event instead of change. Commented Jan 21, 2020 at 0:34
  • So, the snippet works as you wish, but it doesn't work in your app. What does it do instead (in your app)? Commented Jan 21, 2020 at 0:38

2 Answers 2

1

Would change this approach only slightly:

  • use keypress (and eventually paste) to block invalid characters
  • use parseFloat (or int if you don't allow decimals) to remove leading 0's --> '00009.6' => '9.6%'

However I'd use <input type="number"> (btw: </input> closing tag is invalid HTML) these days with a % sign just after the input. (number type has better display on mobile)

(function($) {
  $.fn.percentInput = function() {
    $(this)
      // remove formatting on focus
      .focus(function(){
        this.value = this.value.replace('%','');
      })
      // add formatting on blur, do parseFloat so values like '00009.6' => '9.6%'
      .blur(function(){
        var r = /[^\d.]/g,
            v = this.value;
        this.value = parseFloat(v.replace(r, '')) + '%';
      })
      // prevent invalid chars
      .keypress(function(e) {
        if (/[^\d.%]/g.test(String.fromCharCode(e.keyCode)))
          e.preventDefault();
      });
  };
})(jQuery);

$(document).ready(function() {
  $('input.percent').percentInput();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="percent" value="2%">
<input class="percent" value="4%">

Sign up to request clarification or add additional context in comments.

1 Comment

that works properly, the only issue that could be better is that it allows multiple percent signs one after the other
0

It is my understanding that the snippet you provided is the desired behavior, but your app isn't behaving in the desired way you've demonstrated. So, the question is: what's different between this snippet and your app? Does your app throw any errors into the console?

When I encounter problems like this, I'll usually run my page through an HTML validator. Sometimes, invalid html can corrupt more than you'd think.

When I put your html into a standard HTML5 template, the validator finds these errors in your snippet: enter image description here

Basically, it is saying that you don't need </input>. Do this instead:

<input class="percent" value="2">
<input class="percent" value="4">

Perhaps this is completely unrelated, but I thought I'd mention it. I'd put your actual app through the html validator to see if you find more errors that could be ultimately corrupting your javascript's ability to achieve the desired behavior showcased by your snippet.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.