Getting jQuery.Knob to work with AngularJS

Everyone knows babies like a “busy box”:

image 

in the same way that managers like website “dashboards”:

image

Smile Ok – to be fair, everyone likes dashboards, but I do often refer them as busy boxes because that are colorful to look  at, but often aren’t terribly useful! Anyhow, as you are building out dashboards for websites, one common control that gets a lot of play is jQuery.Knob – which looks like this, in it’s most basic form:

image

You can of course change every aspect of the look of it, including color and whether it’s a full-circle, etc.

The Basics:
Now, if you wanted to use this feature in your .NET website, you’d add a couple of Nuget packages (packages.config):

<?xml version=1.0 encoding=utf-8?>
<packages>
  <package id=jQuery version=2.2.0 targetFramework=net452 />
  <package id=jquery.knob version=1.2.12 targetFramework=net452 />
</packages>

And then on your webpage, have at least:

<!DOCTYPE html>

<html>

<head>

    <script src=”Scripts/jquery-2.2.0.min.js”></script>

    <script src=”Scripts/jquery.knob.min.js”></script>

</head>

<body>

    <input class=”knob” value=”63″ />

    <script>

        $().ready(function () {

            $(“.knob”).knob();

        });

    </script>

</body>

</html>

and that would give you the dial you see above.

The Problem:
You might be wondering what the problem is. Well, if you are using AngularJS, the obvious and intuitive way to use this does not work. You might add the AngularJS Nuget package (packages.config):

<?xml version=1.0 encoding=utf-8?>

<packages>

  <package id=angularjs version=1.4.9 targetFramework=net452 />

  <package id=jQuery version=2.2.0 targetFramework=net452 />

  <package id=jquery.knob version=1.2.12 targetFramework=net452 />

</packages>

and then add the reference, a controller, etc. – you might think you could use the component like this:

<!DOCTYPE html>

<html ng-app=”app”>

<head>

    <script src=”Scripts/jquery-2.2.0.min.js”></script>

    <script src=”Scripts/angular.js”></script>

    <script src=”Scripts/jquery.knob.min.js”></script>

</head>

<body ng-controller=”sampleController“>

    <input class=”knob” value=”{{ knobValue }} />

    <script>

        $().ready(function () {

            $(“.knob”).knob();

        });

 

        var app = angular.module(‘app’, []);

 

        app.controller(‘sampleController’, [‘$scope’, function ($scope) {

            $scope.knobValue = 71;

        }]);

    </script>

</body>

</html>

But you’d find that you get NaN, or Not A Number:

image

One Solution – AngularJS-specific implementations!
OK, this should be easy. Do a google search for AngularJS-aware implementations of a knob or dial. In my experience, I did not find even one that worked correctly. I tried several, and I just could not get this working. In my case, I put this on hold while I was working on other things.

Working Solution:
Yesterday, in working with co-worker Stephen Shamakian, we came up with a solution which worked in all of the browsers, and isn’t terrible. The idea is to use an the regular jQuery Knob, and for the AngularJS part, “watch” for the scope variable to change. When it does, assign the value to the knob and then trigger the “change” event. For example:

app.controller(‘sampleController’, [‘$scope’, function ($scope) {

    $scope.knobValue = 0;

 

    $scope.$watch(

            “knobValue”,

            function (newValue, oldValue) {

                $(“#mainKnob”).val(newValue).trigger(“change”);

            }

        );

 

    $scope.knobValue = 71;

}]);

if you add an id=”mainKnob” to the the HTML, this will now correctly update the dial to show the current value, whenever it’s changed within the AngularJS controller scope.

Bottom Line:
Using the AngularJS $watch feature should be avoided and should only be needed very rarely, if ever. In this case though, to solve this very specific problem, it’s a pretty reasonable workaround and let’s you get your dial/knob components working on your dashboard!

Posted in ASP.NET, ASP.NET MVC, Computers and Internet, Development Tools, General, JQuery, Uncategorized
4 comments on “Getting jQuery.Knob to work with AngularJS
  1. Stephen Shamakian says:

    After our brainstorming session yesterday I was able to get dynamic “Configure” to work also using roughly the same method!

    To configure the JSknob (set max, min, colors, etc.): Use the following code:

    $scope.$watch(
    “KnobMax”,
    function onChange(newMaxValue, oldMaxValue) {
    $(“#knob”).trigger(
    ‘configure’,
    {
    “max”: newMaxValue
    }
    );

    $(“#knob”).val($scope.KnobValue).trigger(‘change’);
    });

    Now one thing to keep in mind! I kept running into a really strange bug! where if i didn’t fully refresh the page the next angular reload would cause the knob to use the “maxValue” as it’s “value”. To fix this i added a line at the bottom of the Angular Watch:

    $(“#knob”).val($scope.KnobValue).trigger(‘change’);

    Basically re-enforcing what the value should be after a JSKnob configure!

    Like

  2. Muni says:

    Rob, is there any option for doing this by using directives with On function, where we can change the values of the entire scope.

    I have not done yet, but my only doubt in my mind is like directives will work for $rootScope only.

    I saw one of the dashboard which uses full of this JQuery.Knob.component It will be like as you said playing with colours.

    This kind of dashboard is more useful in Data Analytic projects, I believe.

    Like

    • Robert Seder says:

      Well, in this case, I didn’t want to dig into it too deeply – I just wanted to get it working. AngularJS 2.0 is supposed to be wildly different than 1.x, so there is no sense in investing in learning the internals. It’s a superficial technology that is going to be extinct in 8 months!! I don’t really like Javascript because it’s such a loose, sloppy language, so I also try to write as little of it as possible too! haha 🙂

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 3 other followers

%d bloggers like this: