-3

We need to let the user enter a number in an <input type='number'> and, if it's negative, the negative style will apply, which will make the displayed text red. However, I am having trouble getting the if statement to work.

HTML:

<span class="input">
    <input type="text" value="-">
    <input type="number" class="hidden">
</span><br>
<span class="input">
    <input type="text" value="-">
    <input type="number" class="hidden">
</span>

$(this).prev().addClass('negative'); doesn't work in the if statement in the following:

$(document).ready(function(){
    $('.input [type="text"]').on('focus', function(){
        $(this).next().removeClass().focus();
        $(this).addClass('hidden');
    });
    $('.input [type="number"]').on('blur', function(){
        var number = Math.round($(this).val() * 100) / 100;
        var text = number.toFixed().toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        if (number < 0) {
            $(this).prev().addClass('negative');
            text = "("+text.replace(/-/g,"")+")";
        }
        if (!number) {text = "-";}
        $(this).prev().val(text);
        $(this).prev().removeClass();
        $(this).addClass('hidden');
    });
});

Fiddle. It will work if you take it out of the if statement, so the issue seems to be that $(this) is not making its way into the if statement. (Edit: Seems my assumption about this was incorrect. See the comments below.) These two similar questions made use of .filter to resolve this issue, but I couldn't figure out how to make that work with the code above.

So how do I get this to work?

Community
  • 1
  • 1
Vincent
  • 2,689
  • 3
  • 24
  • 40
  • Your problem is elsewhere, the use of `$(this)` inside the if statement is correct. What is your fiddle supposed to do? Every time I click on the yellow input it just disappears – Huangism Nov 27 '14 at 20:51
  • 3
    if statement blocks do not have a different scope so `$(this)` _"not making its way into the if"_ is not true – Patrick Evans Nov 27 '14 at 20:51
  • Now I'm truly at a loss. The `.replace()` function is working within the `if` statement, and `$(this).prev().addClass('negative');` works when outside of the `if` statement, so I thought I had narrowed down what was causing the issue. – Vincent Nov 27 '14 at 20:54
  • Is this http://jsfiddle.net/00pxe49t/8/ what you want? – Huangism Nov 27 '14 at 21:00
  • 3
    `removeClass()` is your problem without an argument it removes all classes, so your line `$(this).prev().removeClass();` is removing your `negative` class after you have added it – Patrick Evans Nov 27 '14 at 21:03
  • @PatrickEvans Thanks, that fixed it... and that mistake merits a total facepalm. – Vincent Nov 27 '14 at 21:19
  • @Huangism Not quite. The `number` field should only be visible when focus is on that particular `text`/`number` pair. Otherwise, the `text` field is visible. Based on the other input here, this is now working in Chrome but not yet in Firefox. – Vincent Nov 28 '14 at 04:08

2 Answers2

2

Your problem isn't the scope of $this or even the if. The problem is that you are adding class negative to the textbox with $(this).prev().addClass('negative'); and about 5 lines later removing it again when you do $(this).prev().removeClass();

You need to specify that you only want to remove class hidden and that bit works fine.

After that you also need to handle if they change from negative to positive, so add another block to remove the negative class.

Lastly it is probably safer to check if(!number) first and do the other paths after.

$(document).ready(function(){
    $('.input [type="text"]').on('focus', function(){
        $(this).next().removeClass().focus();
        $(this).addClass('hidden');
    });
    $('.input [type="number"]').on('blur', function(){
        var number = Math.round($(this).val() * 100) / 100;
        var text = number.toFixed().toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
        if (!number) {
            text = "-";
            $(this).prev().removeClass('negative');
        }
        else if (number < 0) {
            $(this).prev().addClass('negative');
            text = "("+text.replace(/-/g,"")+")";
        } else {
            $(this).prev().removeClass('negative');
        }

        $(this).prev().val(text);
        $(this).prev().removeClass('hidden');
        $(this).addClass('hidden');
    });
});
input {
    text-align:right;
    width:10em;
    /* box-sizing keeps width fixed when adding padding (http://stackoverflow.com/a/9484932/1652620) */
    -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    box-sizing: border-box;         /* Opera/IE 8+ */
}

.input [type='text'] {
    background-color:yellow;
    padding-right:14px; /* line up with number text */
    -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    box-sizing: border-box;         /* Opera/IE 8+ */
}
.input [type='number'] {background-color:orange;}
.hidden {display:none;}
.negative {color:red;}

/* Formatting to add $ sign (http://stackoverflow.com/q/8222528/1652620) */
.input {position: relative;}
.currency_symbol {
 font-size:0.6em;
    position:absolute;
    top:7px;
    left:5px;
}
.currency_symbol::before {content:"$"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<span class="input">
    <input type="text" value="-" />
    <input type="number" class="hidden" />
</span>
<br/>
<span class="input">
    <input type="text" value="-" />
    <input type="number" class="hidden" />
</span>

Updated Fiddle

Rhumborl
  • 16,349
  • 4
  • 39
  • 45
  • The inputs also disappears when you click on them, if you don't remove the `.focus()` it will always disappear on FF mac – Huangism Nov 27 '14 at 21:07
  • @Huangism seems to work fine for me in Chrome - i think the idea is to switch viewing text and number. Which browser are you using - maybe it is interpreting number inputs as text – Rhumborl Nov 27 '14 at 21:11
  • Updated my comment, FF is having the disappearing act with focus – Huangism Nov 27 '14 at 21:13
  • 1
    This FF Mac issue has me scratching my head so much that I've posted [a separate question](http://stackoverflow.com/q/27181708/1652620) about it. The code above can't be deployed if I can't get it to function on Firefox. @Huangism, if you have any insight, I'd very much appreciate your input on that question. – Vincent Nov 28 '14 at 04:06
0

You can simply isolate the $(this) inside a variable like so :

$('.input [type="number"]').on('blur', function(){
    var number = Math.round($(this).val() * 100) / 100;
    var number = Math.round($(this).val() * 100) / 100;
    var text = number.toFixed().toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    var this$ = $(this);
    if (number < 0) {
         this$.prev().addClass('negative');
        text = "("+text.replace(/-/g,"")+")";
    }
[...]
Sebastien B.
  • 476
  • 3
  • 10