0

I have a timeframe control that increments/decrements the a certain input whose values are in months. There is a right arrow that increments the value of the input (i.e. January -> February), a left arrow that decrements it, and users can edit the input itself to enter in a different month.

However, the behavior of the timeframe control is really odd. When I click on either of the errors, it will change the value of the input to "". When I click again, it will go to the correct month. When I click again, it clears the input, and back and forth between clearing the input and going to the correct month.

For example: If I click the right arrow 5 times in succession, the value of the input will be:

January
""
March
""
May

What could this bug be? Here's my relevant code:

myApp.controller('TimeframeCtrl', ['$scope',
    '$cookieStore',

function ($scope, $cookieStore) {

    // Create array of month names
    var month_dictionary = [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December'];

    // If month cookie doesn't exist
    if ($cookieStore.get('month') == null) {

        // Create month cookie
        $cookieStore.put('month', 0);
    }

    // If year cookie doesn't exist
    if ($cookieStore.get('year') == null) {

        // Create year cookie
        $cookieStore.put('year', 2014);
    }

    // Go to the previous month
    $scope.prevMonth = function () {

        // Handle corner cases of month looping
        var month_helper = (
        $cookieStore.get('month') - 1 == -1) ? 11 : $cookieStore.get('month') - 1;

        // Update month scope variable
        $scope.month = month_dictionary[month_helper];

        // Update month cookie
        $cookieStore.put('month', month_dictionary[month_helper]);
    }

    // Go to the next month
    $scope.nextMonth = function () {

        // Handle corner cases of month looping
        var month_helper = ($cookieStore.get('month') + 1 == 12) ? 0 : $cookieStore.get('month') + 1;

        // Update month scope variable
        $scope.month = month_dictionary[month_helper];

        // Update month cookie
        $cookieStore.put('month', month_helper);
    }

    // Watch for manual editing of month
    $scope.$watch('month', function () {

        // Update month cookie
        $cookieStore.put('month', month_dictionary.indexOf($scope.month));

        // Remove warning class
        $('.month-control').removeClass('warning-input');

    });

    // Set timeframe control values
    $scope.month = month_dictionary[$cookieStore.get('month')];

    // Test whether or not form inputs are valid
    $scope.submitForm = function ($valid) {

        // If so, update graphs
        if ($valid) {

            // Update graphs

            // If not, add proper warning classes
        } else {
            if ($scope.month == undefined) {
                $('.month-control').addClass('warning-input');
            }
        }
    }
}]);

If anyone needs the HTML too I can add that in. Thanks a ton.

EDIT: HTML

<form class="navbar-form pull-left" name="timeframeForm" ng-controller="TimeframeCtrl" ng-submit="submitForm(timeframeForm.$valid)">
  <div class="timeframe"><i class="fa fa-calendar fa-l"></i>Timeframe</div>
  <i class="fa fa-angle-left" ng-click="prevMonth()"></i>
  <input class="form-control month-control" type="text" value="{{month}}" placeholder="Month" ng-model="month" ng-pattern="/January|February|March|April|May|June|July|August|September|November|December/g"/>
  <i class="fa fa-angle-right" ng-click="nextMonth()"></i>
  <button class="btn btn-refresh"><i class="fa fa-refresh"></i></button>
</form>
sir_thursday
  • 4,820
  • 8
  • 55
  • 102
  • 1
    Dunno if it's related to your problem, but the line `$cookieStore.put('month', month_dictionary[month_helper]);` should be `$cookieStore.put('month', month_helper);` in `prevMonth` shouldn't it? – Robert Jun 19 '14 at 13:45
  • Yeah whoops.. just changed that. Didn't seem to fix the problem but good find. – sir_thursday Jun 19 '14 at 13:46
  • 1
    Works for me: http://jsfiddle.net/9Vydw/ (mocked `$scope` and `$cookieStore`). So either the issue is in some code you've not shown us or something else is happening here. – Sergiu Paraschiv Jun 19 '14 at 15:31
  • Okay. Yeah I've been tracking the value of $scope.month itself, and it is working perfectly. Mind if I post the HTML? I'm new to Angular, so maybe there's something obvious. If not, it's probably some rogue script somewhere. :\ – sir_thursday Jun 19 '14 at 15:34
  • Quite a lot happening there. Could you post a fiddle with the setup you are using? There are too many things to go wrong here... – Sergiu Paraschiv Jun 19 '14 at 21:05

1 Answers1

0

Solution:

The problem was the g character at the end of the ng-pattern regex in the HTML. Removing the g from both of the regex expressions solved the problem. Not sure exactly why (this resource explains it better: What does the regular expression /_/g mean?), but it seems like the g was replacing the months with spaces. Not entirely sure why it was doing it on every other click of the arrow keys, but glad the problem is solved

Community
  • 1
  • 1
sir_thursday
  • 4,820
  • 8
  • 55
  • 102