LOADING...

Preview

Pen ID
Unlock Campus Themeforest adv

 

Code

  
  
  
  

Angled Navbar
(AngularJS & Bootstrap 3)

The element <angled-navbar> is a directive built in AngularJS that when used in its simpliest form will produce a blank navigation bar with default branding ( ) using Bootstrap 3 markup and styles.

Use the following attributes to add menus, search forms, branding and more...

  • menus: when supplied with a JS array of objects in the following form:
    [
      {
        title: 'With Dropdown',
        menu: [
          {title: 'Item One',action: 'myAction'},
          {divider: true},
          {title: 'Item Two',action: 'otherAction'}
        ]
      },
      {title: 'Nav Link',action: 'navLinkAction'}
    ]
    Two items in the navigation bar will be created, the first will have a drop down menu and the latter will only be a navigation link.
  • brand: A string to place in the branding area of Bootstrap's navbar. If branding is not supplied then the default icon will appear.
  • affixed: A string describing the placement of a fixed navbar, values are either top, bottom, [anything]. Any string other than "top" or "bottom" will result in the navbar not being affixed at all. Affixing the navbar requires additional CSS, please include the body.navbar-affixed-top & body.navbar-affixed-bottom CSS classes.
  • search: A JS object with two properties:
    1. show: A boolean value (true/false) on whether to show the default search form in the navbar. Currently always right aligned.
    2. terms: The search object is two way bound, this is the ngModel for the search form and can be used directly in the parent controller.
  • inverse: A boolean value (true/false) on which Bootstrap style to use for the navbar, either normal or inverse.
  • navfn: A function passed to the directive from the parent that the directive should call when a selection is made from a menu. The action string of a menu item will be passed to this function. If this function is undefined the directive will emit an event as nav.menu with a data object containing the 'action.'
  • searchfn: A function passed to the directive to be called when the search form's button is clicked. If the function is undefined the directive will emit an event as nav.search.execute.

Tests


Menu item selected: {{item}} Select something from the menus in the navbar.

Change the navbar branding by changing the text above. You can enter HTML in as well.

Navbar styling

Use the toggle button to change the navbar styling.

Add another menu on the fly

Because the menu array is two way bound you can manipulate the menus' array and add or subtract from it on the fly, dynamically changing your navbar when your application does.

Search form

Hide and show the search form.

Search terms: {{search.terms}}

The search button for these tests will just display an alert box informing you of your search terms, but it does show that the search function was passed and executed correctly.

Affixed

Cycle through navbar affixed states by continuously clicking button above.

CSS
/* If you plan on using affixed states, you need to include these in your CSS */
body.navbar-affixed-top { padding-top: 70px; }
body.navbar-affixed-bottom { padding-bottom: 70px; }

/* Bootstrap relies on HREF property of the A tag to be present to display the correct cursor but since we're using ng-click we need to have the following CSS */
.navbar a { cursor: pointer; }

/* For looks, following is not necessary, although I recommend including the statements for the search form */
.navbar { 
  border-radius: 0; 
  border-bottom: 1px solid #bbb;
  box-shadow: 0 6px 12px rgba(0,0,0,.175);
}
form[role=search], form[role=search]:before, form[role=search]:after {
  border: 0;
  box-shadow: none;
}
form[role=search] button, form[role=search] input { 
  margin: 0; 
  border-radius: 0px;
  border: 0;
}
form[role=search] input {
  border-top-left-radius: 2px;
  border-bottom-left-radius: 2px;
  height: auto;
}
form[role=search] button {
  border-top-right-radius: 2px;
  border-bottom-right-radius: 2px;
  border: 0;
  border-left: 1px solid #ccc;
}
form[role=search] .form-group {
  border-radius: 4px;
  border: 1px solid #ccc;
  white-space: nowrap;
  box-shadow: 0 3px 6px rgba(0,0,0,.175);
}

@media (max-width: 767px){
  form[role=search] input {
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
  }
  form[role=search] button {
    display: none;
  }
  .navbar-nav .open .dropdown-menu {
    border-radius: 0;
    box-shadow: inset 0 3px 6px rgba(0,0,0,.175), inset 0 -3px 6px rgba(0,0,0,.175);
  }
  .navbar-inverse .open .dropdown-menu {
    border-top: 1px solid #333;
    border-bottom: 1px solid #333;
  }
}
JS
angular.module('navbarTest',['ngSanitize'])

.controller('navbarDirectiveTestCtrl',function($scope){
  //=== Variables ===//
  
  $scope.affixed = 'top';
  $scope.search = {
    show : true,
    terms : ''
  };
  $scope.brand = " Brand";
  $scope.inverse = true;
  $scope.menus = [
    {
      title : "Dropdown Menu",
      menu : [
        {
          title : "Menu Item One",
          action : "item.one"
        },
        {
          title : "Menu Item Two",
          action : "item.two"
        },
        {
          divider: true
        },
        {
          title : "Menu Item Three",
          action : "item.three"
        }
      ]
    },
    {
      title : "Singular Menu Item",
      action : "singular"
    }
  ]; // end menus
  
  $scope.item = '';
  $scope.styling = 'Inverse';
  $scope.searchDisplay = 'Visible';
  
  $scope.searchfn = function(){
    alert('Attempting search on: "' + $scope.search.terms + '"');
  }; // searchfn
  
  $scope.navfn = function(action){
    switch(action){
      case 'item.one':
        $scope.item = 'Item one selected.';
        break;
      case 'item.two':
        $scope.item = 'Item two selected.';
        break;
      case 'item.three':
        $scope.item = 'Item three selected.';
        break;
      case 'singular':
        $scope.item = 'Singular link item selected.';
        break;
      default:
        $scope.item = 'Default selection.';
        break;
    }; // end switch
  }; // end navfn
  
  $scope.toggleStyling = function(){
    $scope.inverse = !$scope.inverse;
    if(angular.equals($scope.inverse,true))
      $scope.styling = 'Inverse';
    else
      $scope.styling = 'Default';
  }; // end toggleStyling
  
  $scope.toggleSearchForm = function(){
    $scope.search.show = !$scope.search.show;
    if(angular.equals($scope.search.show,true))
      $scope.searchDisplay = 'Visible';
    else
      $scope.searchDisplay = 'Hidden';
  }; // end toggleSearchForm
  
  $scope.addMenu = function(){
    $scope.menus.push({
        title : "Added On The Fly!",
        action : "default"
    });
  }; // end test
  
  $scope.toggleAffixed = function(){
    switch($scope.affixed){
      case 'top':
        $scope.affixed = 'bottom';
        break;
      case 'bottom':
        $scope.affixed = 'none';
        break;
      case 'none':
        $scope.affixed = 'top';
        break;
    };
  }; // end toggleAffixed
}) // end navbarDirectiveTestCtrl

/**
 * Angled Navbar Directive
 *
 * @requires: ngSanitize, Bootstrap 3 (jQuery & Bootstrap's JS - responseive features require the inclusion of the Bootstrap JS)
 **/
.directive('angledNavbar',function(){
  return {
    restrict : 'AE',
    scope : {
      brand : '=',
      menus : '=',
      affixed : '=',
      search : '=',
      searchfn : '&',
      navfn : '&',
      inverse : '='
    },
    templateUrl : 'tmpls/nav/navbar.html',
    controller : function($scope,$element,$attrs){
      //=== Scope/Attributes Defaults ===//
      
      $scope.defaults = {
        brand : '',
        menus : [],
        search : {
          show : false
        }
      }; // end defaults
      
      // if no parent function was passed to directive for navfn, then create one to emit an event
      if(angular.isUndefined($attrs.navfn)){
        $scope.navfn = function(action){
          if(angular.isObject(action))
            $scope.$emit('nav.menu',action);  
          else
            $scope.$emit('nav.menu',{'action' : action});
        }; // end navfn
      }
      
      // if no parent function was passed to directive for searchfn, then create one to emit a search event
      if(angular.isUndefined($attrs.searchfn)){
        $scope.searchfn = function(){
          $scope.$emit('nav.search.execute');
        }; // end searchfn
      }
      
      //=== Observers & Listeners ===//
      
      $scope.$watch('affixed',function(val,old){
        var b = angular.element('body');
        // affixed top
        if(angular.equals(val,'top') && !b.hasClass('navbar-affixed-top')){
          if(b.hasClass('navbar-affixed-bottom'))
            b.removeClass('navbar-affixed-bottom');
          b.addClass('navbar-affixed-top');
        //affixed bottom
        }else if(angular.equals(val,'bottom') && !b.hasClass('navbar-affixed-bottom')){
          if(b.hasClass('navbar-affixed-top'))
            b.removeClass('navbar-affixed-top');
          b.addClass('navbar-affixed-bottom');
        // not affixed
        }else{
          if(b.hasClass('navbar-affixed-top'))
            b.removeClass('navbar-affixed-top');
          if(b.hasClass('navbar-affixed-bottom'))
            b.removeClass('navbar-affixed-bottom');
        }
      }); // end watch(affixed)
      
      //=== Methods ===//
      
      $scope.noop = function(){
        angular.noop();
      }; // end noop
      
      $scope.navAction = function(action){
        $scope.navfn({'action' : action});
      }; // end navAction
      
      /**
       * Have Branding
       * Checks to see if the "brand" attribute was passed, if not use the default
       * @result  string
       */
      $scope.haveBranding = function(){
        return (angular.isDefined($attrs.brand)) ? $scope.brand : $scope.defaults.brand;
      }; 
      
      /**
       * Has Menus
       * Checks to see if there were menus passed in for the navbar.
       * @result  boolean
       */
      $scope.hasMenus = function(){
        return (angular.isDefined($attrs.menus));
      };
      
      /**
       * Has Dropdown Menu
       * Check to see if navbar item should have a dropdown menu
       * @param  object  menu
       * @result  boolean
       */
      $scope.hasDropdownMenu = function(menu){
        return (angular.isDefined(menu.menu) && angular.isArray(menu.menu));
      }; // end hasDropdownMenu
      
      /**
       * Is Divider
       * Check to see if dropdown menu item is to be a menu divider.
       * @param  object  item
       * @result  boolean
       */
      $scope.isDivider = function(item){
        return (angular.isDefined(item.divider) && angular.equals(item.divider,true));
      }; // end isDivider
    }
  };
}) // end navbar

.run(function($templateCache){
  $templateCache.put('tmpls/nav/navbar.html','');
});

Description

A navbar directive to recreate the Bootstrap navbar by feeding the directive attributes rather than having to recreate the Bootstrap navbar example every time when writing a new application. Two way binding between the navbar's menu items and the controller allows for dynamic creation and editting of the navbar's menus.
Term
Mon, 11/27/2017 - 21:28

Related Codes

Pen ID
Pen ID
Pen ID
Square Adv