Tag: jquery

  • Why is toggling a search box in a header so difficult in Angular 2?

    In Angular 2 I have the following pseduocode…

    ...

    As you can see I have a header with a search form container that has the class ‘visible’ when the variable ‘showSearch’ is true, and ‘invisible’ otherwise. As a component by itself with this html, this works fine. When the user clicks the search icon showSearch is set to true and the form shows.

    Now the issue comes when I want to hide this container again. I want to set showSearch to false and thus hide the container when the user clicks anywhere that isn’t the header (ie. the body of the page).
    Now in jQuery, this would be easy. On click of the body, you would find the element with ‘.searchContainer’ and removeClass(‘visible’).addClass(‘invisible’) right? Easy.

    Except this is Angular 2. We don’t have jQuery (or want to use it) here. Normally what I would do in this case, is to have something like this in the parent component that contains the header component:




    ..

    That’s the HTML. I pass the showSearch variable down from the parent to the child and toggle it with the parent right? That’s how normally it works. One way binding. (If the child needs to talk to the parent it uses event emitters instead).


    @HostListener('click', ['$event'])
    closeSearchBox(event) {
    const toElement = event.toElement;
    let insideHeader = false;
    let node = toElement;
    while (node != null && node.classList !== undefined) {
    if (node.classList.contains('header-container')) {
    insideHeader = true;
    }
    node = node.parentNode;
    }

    if (!insideHeader) {
    const searchBox = this.elementRef.nativeElement.querySelector('.search-container');
    const searchMenu = this.elementRef.nativeElement.querySelector('.header-menu-list');
    if (searchBox.classList.contains('visible')) {
    this.showSearch = false;
    }
    }
    }

    So this should work right? I have an HostListener on the parent (that’s really the whole body of my app) so if the user clicks anywhere it will check to see if the element is outside the header (because we dont want to close it if its inside the header), and close the search container if it is.

    Problem is… it didn’t work. I don’t know why. I searched StackOverflow, Angular Docs, scoured Google etc nothing. I even tried using EventEmitter but thats usually only from child to parent and not parent to child. Two-way bindings? nope doesn’t work either. It *should* just work inherently as part of Angular’s single way binding. Maybe the HostListener is outside the Angular Zone and I can use ChangeDetectorRef to detectChanges? Nope. That didn’t work either.
    I *could* use a service and just subscribe to that service from the child component … but thats kind of overkill for ONE variable change to toggle a search box.

    So finally. I had to make a solution that is not so elegant, and doesn’t use any variables or bindings. But it works.

    So I took a jQuery-like approach of just toggling the class manually with ‘elementRef.nativeElement.classList’ instead. Its not as pretty as using bindings, but at least this way it works.


    toggleSearchHeader(showHeader) {

    if (showHeader) {
    this.searchHeaderMenu.nativeElement.classList.remove('visible');
    this.searchHeaderMenu.nativeElement.classList.add('invisible');
    this.searchHeaderBox.nativeElement.classList.remove('invisible');
    this.searchHeaderBox.nativeElement.classList.add('visible');
    } else {
    this.searchHeaderMenu.nativeElement.classList.remove('invisible');
    this.searchHeaderMenu.nativeElement.classList.add('visible');
    this.searchHeaderBox.nativeElement.classList.remove('visible');
    this.searchHeaderBox.nativeElement.classList.add('invisible');
    }

    }

    I have to substitute changing one variable showSearch with a whole method that does janky DOM crap and..


    @HostListener('click', ['$event'])
    closeSearchBox(event) {
    const toElement = event.toElement;
    let insideHeader = false;
    let node = toElement;
    while (node != null && node.classList !== undefined) {
    if (node.classList.contains('header-container')) {
    insideHeader = true;
    }
    node = node.parentNode;
    }

    if (!insideHeader) {
    const searchBox = this.elementRef.nativeElement.querySelector('.search-container');
    const searchMenu = this.elementRef.nativeElement.querySelector('.header-menu-list');
    if (searchBox.classList.contains('visible')) {
    searchBox.classList.remove('visible');
    searchBox.classList.add('invisible');
    searchMenu.classList.remove('invisible');
    searchMenu.classList.add('visible');
    }
    }
    }

    So yeah as you can see those are the changes I needed to get it to work. For some reason, using a variable inside `HostListener` and passing that down to the child component doesn’t reflect the bindings. So I have to use a more archaic way instead. Not only that but its much more difficult to test with unit tests now that it relies on the DOM instead of an Angular variable. Bleh. If anyone knows why this is, let me know please! comment on this post..

  • Javascript Framework/Library Reference

    Base libraries (animation, dom manipulation, event handling, ajax, utility)
    jQuery (this library is the most popular base library)
    Zepto
    Dojo
    Prototype
    MooTools

    Utility Libraries
    Underscore
    Lodash
    Sizzle
    Modernizr (feature detection)
    Yepnope (conditional loader)

    MVC Frameworks
    Angular
    Ember
    Backbone
    SproutCore
    ExtJS
    Batman
    Spine
    Meteor
    Exoskeleton
    ActiveJS
    StapesJS
    JS MVC

    View/Data binding frameworks
    Knockout
    CanJS
    React
    Rivets

    Backbone Libraries
    Thorax
    Epoxy
    Chaplin
    Marionette
    Quilt
    Backpack
    Rendr
    Backbone Boilerplate

    Templating Libraries
    Handlebars
    Mustache

    Widget libraries (animation, ui)
    jQueryUI
    YUI
    Bootstrap
    Scriptaculous
    Google Closure
    ShadowboxJS
    Lightbox

    Mobile libraries
    jQuery Mobile
    Dojo Mobile
    Sencha Touch

    Testing Libraries
    Chai
    Jasmine
    QUnit
    Mocha
    Sinon
    PhantomJS
    CasperJS
    Istanbul
    Karma

    Build development Libraries
    Grunt (task runner)
    Bower (package manager)
    RequireJS (module loader)
    Yeoman (scaffolding)

    Special use libraries (data-driven, graphics, maps, etc)
    D3 (document manipulation)
    Raphael (vector graphics)
    MediaElementJS (HTML5 video/audio)
    JPlayer (HTML5 video/audio)
    Leaflet (maps)
    ChartJS (charts)

    NodeJS Libraries
    Express
    MongooseJS
    BookshelfJS
    SocketIO
    Sequelize
    Sails
    Prerender

  • Google Glass Unboxing and Review, Jasmine-Jquery+SquireJS example

    Google Glass Review

    I just got my Google Glass Explorer 2.0 edition in not that long ago, and I know alot of people are curious about how this gadget works, so I’ve put up a video of it (an unboxing one, and a review).

    httpv://youtu.be/NPBNNwQB_Ss

    httpv://youtu.be/RHg-bnx7r3A

    Example client side Jasmine unit test using the jasmine-jquery + SquireJS libraries
    Ok, so I finally figured out these client side tests. I have an example test here that uses Backbone Models as objects, the Jasmine-jquery library to test DOM interactions and the SquireJS library to mock out requireJS dependencies. Hope this helps someone.

    //your jasmine test suite
    describe('Car View', function() {
    
            beforeEach(function () {
                this.injector = new Squire();
                this.car = new Car();
            });
    
            afterEach(function () {
                this.injector.clean();
                this.injector.remove();
            });
    
           it('test car creation with a mocked out owner', function () {
    
                var ownerInput, brandInput, modelInput;
                var carMock = this.car;
                var injector = this.injector;
    
                //squire injector runs asynchronously inside its own closure so we need to run synchronously in Jasmine via run and wait
                runs(function() {
                    carMock.set({
                        brand: 'Honda',
                        model: 'Civic',
                        owner: 'John Wayne',
                        url: '/car/civic/123456'
                    });
                    //Owner is some backbone model that is pulled in via requireJS that we want to mock because it can't be mocked normally
                    var ownerMock = new Owner({ name: 'John Wayne' });
                    injector.mock('dep/owner', ownerMock).require(['car.view'],function(CarView) {
                        var carView = new CarView({
                           model: carMock
                        });
                    //lets say on render, your car view populates some owner field with the owner name, and the brand and model fields the same way.
                    CarView.render(); 
                    ownerInput = carView.$el.find('.owner input');
                    brandInput = carView.$el.find('.brand input');
                    modelInput = carView.$el.find('.model input');            
                    });
                });
    
                //wait for dom to render 
                waits(1000);
    
                //do your assertions
                runs(function() {
                    expect(brandInput[0]).toHaveValue(carMock.get('brand'));
                    expect(modelInput[0]).toHaveValue(carMock.get('model'));
                    expect(ownerInput[0]).toHaveValue(carMock.get('owner'));
                });
    
            });
    
    });
  • Backbone Apps, Express Apps, Client side unit tests, Korean, Gadgets, Videos

    Thanksgiving is coming soon, and these days it does seem like I need a break.

    What an interesting year it’s been for me. Multiple broken friendships/relationships, lost over $5k in parking fines, lost over $10k in stock options, multiple missed opportunities, a broken wrist, failed drivers test, I could go on. This year has not been one of my better years.

    Just two months ago, I posted about how Bitcoin was a good investment, but never took the time to actually invest in it (due to confusion about how to actually buy them). Well now, Bitcoin is over $1200 (it was $135 at the time I posted that). So a potential windfall opportunity has gone past me.

    These days, what do I have to look forward to? Just work, and study. Pretty much my life these days.

    Client side unit tests
    On the work side, I’ve been writing a lot of client side javascript tests recently, and its really made me more interested in them. Originally, I was not too fond of writing unit tests, as I felt them tedious, but now I find them kind of challenging. Jasmine is a popular client side testing framework, and getting it to work well with Backbone models, routers and views, is a good challenge. I’ve also been using libraries like SinonJS to mock/stub/spy out functions/objects, ChaiJS to unify the TDD/BDD style assertions, Karma as a test-runner, and Jasmine-jquery to test out dom events. Now I’m trying to mock out RequireJS dependencies (Squire.js/). It’s been a frustrating but enlightening few weeks trying to get my head around client unit tests.

    BackboneJS extensions
    Also, been trying to move from using string based templates like handlebarsJS into using dom-based templates. I really really want to get RivetsJS to integrate with BackboneJS so we have computed properties and data bindings (thanks to dom templating) but it’ll have to wait until we refactor all our handlebars templates to use Rivets Views instead. What other things do I recommend for a large Backbone app? Controllers and Container Views. MarionetteJS provides those. Also, use lodash instead of underscoreJS (It has more features).

    NodeJS / express
    I’ve really gotten around to liking NodeJS / ExpressJS so far. Using the ExpressJS API is easier than having to learn Apache modules and servlet containers and all that stuff. To be sure though, its quite different than the usual JavaScript you’d expect.

    Korean
    On the studying side, is my Korean getting any better? I’ve been taking classes now, and it feels like they focus more on writing and reading, which are traditionally the pillars of language education. Recently though, I’ve been subscribing to the Pimsleur approach of focusing more on speaking and listening instead. In fact, speaking and listening are the hardest things for me right now, and I constantly struggle when I listen to Koreans and figure out what to say. These days, I’ve been using korean dramas (a la drama fever) to study by listening, and repeating what the actors are saying and watching multiple times with and without subtitles. It’s an exhausting job trying to learn Korean when everyone around you speaks English and the opportunities to meet Koreans are few and far between, seriously. And it also doesn’t help that what Koreans speak and what textbooks teach you are different. For example, my Korean friends told me that 당신 and 실례합니다 are not often used in real life, despite being in the book as ‘you’ and ‘excuse me’.

    Gadgets
    I bought an iPhone5S, an iPad Air, and also have the chance to get Google Glass (as a BitTorrent developer) as well. What do I think? I really like the iPhone of course, as I tend to prefer smaller screens and the iPhone5S probably has the best camera in the business. The TouchID thing is pretty cool too. The iPad Air also surprised me. I didn’t think an iPad could replace my MacBook, but after using the iPad a few days with a bluetooth keyboard, I can honestly say that 90% of the things I can do with the MacBook (except programming), I can do with the iPad, and the iPad has LTE on top of that and only weighs 1lb so I can use it anywhere. Surprising, I might have to sell my MacBook.

    Anyways, I haven’t updated recently because my life is fairly mundane so far. I did upload several videos though, so take a look:

    San Francisco’s Hidden Gems (my friend helped me with this one):
    httpv://www.youtube.com/watch?v=P2lw-yKA0CA

    iPad Air vs Kindle Fire HDX
    httpv://www.youtube.com/watch?v=JtpXyh542L4

    Sony HMZ-T3
    httpv://youtu.be/avIEWVmFEZQ

  • jQuery plugin for smooth back to top and follow me navigation, disabling Bootstrap popover caching, Modernizr IE detection extension

    I wrote some jQuery plugins for this site – to get smooth scrolling back to top and navigation that follows you down the page. Here’s the code. The usage is in the comments.

    /* jquery plugin to scroll window to the top */
    $(function() {
        var up_timer = 0;
        var viewportLeft;
        var viewportTop;
    
        $.getPosition = function() {
            viewportLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
            viewportTop = document.body.scrollTop || document.documentElement.scrollTop;
        };
    
        $.pageup = function(x, y) {
            if (up_timer) {
                clearTimeout(up_timer);
            }
            if (y >= 1) {
                $.getPosition();
                var divisionY = (viewportTop - (viewportTop / 5));
                var Y = Math.floor(divisionY);
                window.scrollTo(viewportLeft, Y);
                up_timer = setTimeout("$.pageup(" + viewportLeft + "," + Y + ")", 2);
            } else {
                window.scrollTo(viewportLeft, 0);
                clearTimeout(up_timer);
            }
        };
    
        $.scrollup = function() {
            $.getPosition();
            $.pageup(viewportLeft, viewportTop);
        };
    });
    
    /* Usage: call $.scrollup(); to scroll to the top smoothly */
    
    /* To enable an element to follow you down the page smoothly */
    function enableFollowNav(navElement,padding) {
                var $sidebar = navElement,
                    $window = $(window),
                    offset = $sidebar.offset(),
                    topPadding = padding;
    
                $window.scroll(function() {
                    if ($window.scrollTop() > offset.top) {
                        $sidebar.stop().animate({
                            marginTop: $window.scrollTop() - offset.top + topPadding
                        });
                    } else {
                        $sidebar.stop().animate({
                            marginTop: 0
                        });
                    }
                });
            }
    /* Usage: call enableFollowNav([jquery element],[amount of topPadding]) to make the element follow you down the page when you scroll. */
    

    Bootstrap popover caching
    Bootstrap popovers are very nifty and neat, and I love using them. So, Bootstrap popovers rely on the data-title and data-content attributes of the HTML5 elements its called upon. However, in one of my applications, I noticed that my popover content was not changing, despite the fact that I had changed the data-title and data-content of the element. Why am I changing the data-content of my element? well in my EmberJS view code, I have a computed property that is dynamically updating.

    popoverContent: function() {
                var quantity = this.get('controller.model.quantity');
                return "You have added " + quantity + " cases of beer to your basket."
                    + "
    Go to shopping basket"; }.property('controller.model.quantity'),

    And in my handlebars template, I have the data binding to that computed property defined:

    
    

    So in this case, I need the bootstrap popover to not cache my content. The solution to this is to just disable this feature of the plugin like so:

        $.fn.popoverNoCache = function(option) {
            return this.each(function() {
                var $this = $(this)
                    , data = $this.data('popover')
                    , options = typeof option == 'object' && option
                if (!data) {
                    $this.data('popover', (data = new Popover(this, options)))
                } else {
                    data.options.content = $(this).attr('data-content');
                    data.options.title = $(this).attr('data-title');
                }
                if (typeof option == 'string') {
                    data[option]()
                }
            })
        }
    

    This way, this caching feature of the bootstrap popover is disabled, and it will update with fresh content every time your data attributes change. Of course this is not for everyone, which is why I’m not going to submit a pull request to the github or anything, but its useful if other people are using data bindings for their popovers (a similar solution exists for bootstrap tooltips as well).

    Modernizr IE detection
    Modernizr is a really good feature detection library, and for the most part you should use its built in detection for properties.
    But there might be a time where you just need to detect IE in general. So Here’s an extension for Modernizr to detect that. It works up to IE10. Usage is in the comments.

    /** IE detection **/
    // ----------------------------------------------------------
    // If you're not in IE (or IE version is less than 5) then:
    // Modernizr.ie === undefined
    // If you're in IE (>=5) then you can determine which version:
    // Modernizr.ie === 7; // IE7
    // Thus, to detect IE:
    // if (Modernizr.ie) {}
    // And to detect the version:
    // Modernizr.ie === 6 // IE6
    // Modernizr.ie > 7 // IE8, IE9, IE10 ...
    // Modernizr.ie < 9 // Anything less than IE9
    // ----------------------------------------------------------
    Modernizr.ie = (function(){
        var undef,rv = -1; // Return value assumes failure.
        if (navigator.appName == 'Microsoft Internet Explorer')
        {
            var ua = navigator.userAgent;
            var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
            if (re.exec(ua) != null)
                rv = parseFloat( RegExp.$1 );
        }
    
        return ((rv > -1) ? rv : undef);
    }());
    

    Videos
    I made some miscellaneous videos I forgot to post last month. Here is one on imitating a northeastern accent, a review of my pedalboard, and a music video I did for a one direction song.

    httpv://youtu.be/zIMVNZ9I46o
    httpv://youtu.be/k4W5u5G4L2k
    httpv://youtu.be/v5wcJigYyBw
    httpv://youtu.be/Vfd_EP20UOQ

    My wrist also healed (yay!) so now I can go back to jamming… here’s a nice little funky blues jam with my wah pedal.
    httpv://youtu.be/g0fyaX8RAcA

    And here’s a nice piano cover of Coldplay as well 🙂
    httpv://youtu.be/ZRnt6ySLueU

  • Proliferation of Javascript libraries and bad start to the year

    Ah, good old O'Reilly Rhino
    Ah, good old O’Reilly Rhino

    As a front-end developer, I can’t help but notice all the innovation going on. Especially compared to the backend, I feel that front end technologies these days are developing at quite a rapid pace. In particular, the areas of HTML, CSS and JavaScript.

    HTML5
    HTML5 has of course been the hot technology as of late, which I regret not using more HTML5, because my company has to support legacy browsers like IE6/7 (which of course cannot support HTML5).
    “But Tong, why don’t you use Modernizr or another shim to take advantage of graceful degradation?”
    Well, the fact is that we are lazy, so we don’t want to rewrite a lot of our code for graceful degradation / progressive enhancement. And I’ve also noticed new templating technologies such as HAML, Jinja, JST, Mustache, and Handlebars, which uses JS to compile Handlebars templates, which itself is built on top of Mustache.

    CSS3
    Another area is CSS. Of course my company can’t use CSS3 for much of the same reason as HTML5; support for legacy browsers. Take note that like HTML5, CSS3 is continually expanding and browser support is very inconsistent (so just look to W3C for guidance for now). However, there is also much innovation in the realm of styling as well. There’s LESS, which extends CSS with variables, mixins, operations and functions, much like a scripting language, and SASS, which adds much of the same things. Then we have frameworks that build on top of LESS/SASS, like Compass.
    Notice how alot of new technologies are themselves improved or extended by even newer technologies, and so forth.

    jQuery
    Nowhere is this more evident than in JavaScript. A little bit of history: Netscape originally developed JavaScript to be a lightweight interpreted language for amateurs (ie. users of VB). They named it JavaScript to take advantage of Java’s popularity, not that the two languages share anything in common. It was very popular, and because Microsoft had their own standards of the language, it wasn’t standardized until the late 90s into ECMAScript. In the late 90s/early 2000s, JS was mainly used for light scripting events such as submitting forms, animating icons, etc. It wasn’t until DHTML and AJAX came about that JS really started to take off, especially with professional programmers.

    Hence, where we are at now. Ajax took off, and JS libraries (some may say polyfills) came out that significantly expanded JS’s use in everyday browser scripting. My company uses Prototype.js and Scriptaculous for UI. And certainly there were other popular libraries at the time like MooTools, and widget libraries like Dojo and YUI.

    But the most popular JS library that came out in 2006 that really started web 2.0 computing was jQuery. Every web developer knows it, and 91% of websites probably use it. Jquery made ajax applications and dynamic application scripting as easy as cake. Hence my point now is that 90% of libraries today is built on top of, using, or extending jquery. It’s so ubiquitous. Want some boilerplate for your code? Bootstrap uses it. Want to add some structure to your single page app? Backbone.js uses it. How about mobile? Well jQuery mobile has got you covered. And jQueryUI has most of your UI needs down. jQuery has become a foundation of modern JS frameworks and libraries.

    And now you can pretty much build your entire app, full stack, using only JavaScript. Rails developers can be more productive using CoffeeScript and Batman.js. BackboneJS, AngularJS and EmberJS have got you covered on your client side MVC needs. Need a utility library without Prototype.js’s namespace interference and object pollution? UnderscoreJS is there (while also being a dependency for Backbone). Modular JS components? RequireJS is there. Making vector graphics? Sure, RaphaelJS is there. UI widgets? How about Google Closure, jQueryUI, ExtJS, or the aforementioned YUI? Maps? Yup, LeafletJS handles that. Need just CSS selectors? SizzleJS does that. What about media overlays? Yes we have both ShadowboxJS and LightboxJS on each side of the force. In fact you can even build server side JS using NodeJS and SocketIO, as well as frameworks building on top of those, like ExpressJS. Mobile browsers? How about ZeptoJS, Dojo Mobile, or the aforementioned jQuery mobile? Or how about giving me a full stack framework like Meteor? And yes, JS can even compile templates on the client side without being horrible slow using Handlebars and JST. Unit testing frameworks similar to server side programming languages have appeared for JS, such as Qunit and Jasmine, themselves written in JS. And yes, there’s even JS Dependency Injection.

    All this to show that, there are way too many JS libraries out there. Not that its a bad thing, but it seems to have exploded recently. Backbone.js wasn’t released that long ago, and there’s already extensions like Backpack.js and MarionetteJS built on top of Backbone, which itself is built on top of jQuery, which itself is written in native JS. My concern is that modern front end devs are forgetting the important foundations of JavaScript and the native JS API, when they are using all these libraries which seem too magical and obfuscate how JS works. We used to DOM-script, now we have two way data bindings, which do updating and ajax calls for you. Soon, front end devs won’t even know what an ActiveX object is, or how to handle IE specific bugs, because its all done in the background. And its all happening a bit fast… what might be the hot library of today might be the legacy library of tomorrow… my company experienced this first hand using prototype.js… which at the time was as popular as jquery but now is used by less and less websites. This makes it all difficult for front-end devs to absorb, which libraries are considered the front-runners and will be viable in the future. Who knows? It’s a concern I have…

    HTML validation
    Thanks to my friend Chris (the Polish juggernaut) for this tip:
    [Unix commands] use xmllint –html *.html to check if your html document is well formed, but use tidy *.html for full on HTML validation. Little known unix commands, but useful.

    Other news
    And in other news, I’ve been having a terrible year so far, compared to last year. So far, in just January alone, I had:

    -At the very start of the year, the power on my Mac went out and all the pictures I took in San Diego on the Mac guest account were deleted and cannot be recovered (this is a “feature” of unix guest accounts and works differently than windows guest accounts).
    -alot of my good Korean friends went back to Korea.
    -lost 6k in stock market options (each time the market went the other direction – go figure)
    -pay $1340 in parking fines and traffic fines (because I had high beams on? geez)
    -had to come in late for work or missing from work many times due to the stress of my new apartment, mortgage loans, escrow, new bank, etc.
    -Didn’t get internet for two weeks due to no cable wiring
    -Didn’t have electricity in the living room for two weeks due to faulty circuit breaker.
    -Toilet cannot flush – now have to use the lobby restroom until a repairman fixes it.
    -washer and dryer doesn’t work – all my clothes come out smelly and unwashed
    -After doing tax returns, found out I owe the government $2600 in taxes.. ugh…

    So yeah. In one month, I had more bad news that all of last year. Happy year of the snake.