<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
  <script data-require="angular.js@*" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <script data-require="jquery@*" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
  <script data-require="bootstrap@*" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="style.css" />

  <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
  <script src="app.js"></script>
</head>

<body ng-app="app" ng-controller="IndexController">
  <nav class="navbar navbar-default">
    <div class="container-fluid">
      <!-- Brand and toggle get grouped for better mobile display -->
      <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#myButtons" aria-expanded="false">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#"><img  class="angular-icon" src="http://luisfarzati.github.io/angulartics/images/angularjs.png" alt="angular-icon"></a>
      </div>
      <!-- Collect the nav links, forms, and other content for toggling -->
      <div class="collapse navbar-collapse" id="myButtons">
        <ul class="nav navbar-nav btn-group navbar-right" role="group" aria-label="...">
          <li class="active"> 
            <button type="button" class="btn btn-default">Button 1 </button>
          </li>
          <li class="active">
            <button type="button" class="btn btn-default">Button 2 </button>
          </li>
          <li class="active">
            <button type="button" class="btn btn-default">Button 3 </button>
          </li>
        </ul>
      </div>
      <!-- /.navbar-collapse -->
    </div>
    <!-- /.container-fluid -->
  </nav>

  <div class="container-fluid">
    <div class="row">
      <div class="col-lg-6">
        <h4 class="labelName" ng-show="!showNameField">
              {{name}}
              <button ng-click="editNameValue()" class=" btn btn-default hovered-icon"><i class="glyphicon glyphicon-pencil"></i></button>
            </h4>
        <custom-input type="'text'" place-holder="'Ingrese un nombre'" session-key="storageKeys.Name" shared-property="name"  show="showNameField"></custom-input>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-6">
        <h4 class="labelName" ng-show="!showGenderSelect">
              {{gender}}
              <button ng-click="editGenderValue()" class="btn btn-default hovered-icon"><i class="glyphicon glyphicon-pencil"></i></button>
            </h4>
        <custom-input type="'select'" select-options="selectOptions" session-key="storageKeys.Gender" shared-property="gender" place-holder="''" show="showGenderSelect"></custom-input>
      </div>
    </div>

    <div class="row">
      <div class="col-lg-6">
        <h4 class="labelName" ng-show="!showAgeField">
              {{age}}
              <button ng-click="editAgeValue()" class="btn btn-default hovered-icon"><i class="glyphicon glyphicon-pencil"></i></button>  
            </h4>
        <custom-input type="'number'"  place-holder="'Ingrese su edad'" session-key="storageKeys.Age" shared-property="age" show="showAgeField"></custom-input>
      </div>
    </div>
  </div>

  <span>{{example}}</span>
</body>


</html>
// Declaring angular app module
var app = angular.module('app', []);


// Declaring angular index controller
// Controller will handle initial property values
app.controller('IndexController', ['$scope', 'storageService', function($scope, storageService) {
  $scope.selectOptions = [{
    value: '',
    display: '-- Seleccione genero --'
  }, {
    value: 'Masculino',
    display: 'Masculino'
  }, {
    value: 'Femenino',
    display: 'Femenino'
  }];
  
  
  $scope.name = 'Nombre';
  $scope.gender = 'Sexo';
  $scope.age = 'Edad';
  $scope.showNameField = false;
  $scope.showGenderSelect = false;
  $scope.showAgeField = false;

  //These keys should be on an constant string by Environment file
  $scope.storageKeys = {
    Name: 'Name',
    Gender: 'Gender',
    Age: 'Age'
  };


  $scope.editNameValue = function() {
    $scope.showNameField = !$scope.showNameField;
  };

  $scope.editAgeValue = function() {
    $scope.showAgeField = !$scope.showAgeField;
  };

  $scope.editGenderValue = function() {
    $scope.showGenderSelect = !$scope.showGenderSelect;
  }

  function init() {
    // if values are stored in storage
    var storage = storageService.get();

    if (storage.Name) {
      $scope.name = storage.Name;
    }
 
    if (storage.Gender) {
      $scope.gender = storage.Gender;
    }

    if (storage.Age) {
      $scope.age = storage.Age;
    }


  }

  init();
}]);

//
// Declaring angular directive 
// I inject storageService into the directive in order to set new values 
// 
app.directive('customInput', ['storageService', function(storageService) {
  return {
    restrict: 'E',
    scope: {
      type: '=',
      placeHolder: '=?',
      title: '=?',
      selectOptions: '=?',
      show: "=",
      sharedProperty: '=',
      sessionKey: '='
    },
    replace: true,
    transclude: true,
    link: function(scope, element, attrs) {

      // Action for save icon
      scope.saveInput = function() {
        switch (scope.type) {
          case 'select':
            saveSelectValue();
            break;
          default:
            saveInputValue();
            break;
        }
        scope.show = false;
      };


      // Private functions
      function saveInputValue() {
 
        if(scope.sessionKey === 'Age'){
          var age = scope.inputNumber + ' aƱos';
          
          storageService.set(scope.sessionKey, age);
          scope.sharedProperty = age;
          return;
        }
        //update session key with new value
        storageService.set(scope.sessionKey, scope.inputText);

        //update property shared with parent scope
        scope.sharedProperty = scope.inputText;
        
        return;
      }

      function saveSelectValue() {
        
        storageService.set(scope.sessionKey, scope.selectValue);
        
        //update property shared with parent scope
        scope.sharedProperty = scope.selectValue;
        
        return;
      }



    },
    templateUrl: 'custom-input-directive.html'
  };
}]);

app.directive('stringToNumber', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(value) {
        return '' + value;
      });
      ngModel.$formatters.push(function(value) {
        return parseFloat(value, 10); 
      });
    }
  };
});

// Declaring angular factory for local storage management
app.factory('storageService', function() {
  var that = this;
  var storage = localStorage;


  that.set = function(key, value) {
    if (typeof value === 'object') {
      value = JSON.stringify(value);
    }
    if (storage) {
      storage.setItem(key, value);
    }
  };

  that.get = function(key) {
    if (key) {
      return getItem(key);
    }

    var result = {};

    for (var property in storage) {
      result[property] = getItem(property);
    }

    return result;
  }

  function getItem(key) {
    if (key) {
      try {
        return JSON.parse(storage.getItem(key));
      } catch (e) {
        return storage.getItem(key);
      }
    }
  }

  return that;
});
/* Styles go here */

#myButtons {
  padding: 15px;
}

.labelName .hovered-icon {
  display: none;
}

.labelName {
  padding: 15px;
  cursor: pointer;
  display: inline-block;
  border-radius: 5px;
}

.labelName:hover {
  background-color: #c7d0d1;
}

.labelName:hover .hovered-icon {
  display: inline-block;
}


.angular-icon{
  width: 30px;
  height: 30px;
}


/*
  This snippet helps to remove arrows from input number 
*/
input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button { 
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    margin: 0; 
}
This example app was made from the description given by Luciano Mollar. 

1.  The header was made using bootstrap nav tag, which already resolves icon (brand) placement

2. Bootstrap already resolves the requirement in which content should vary when viewport
is less than 768px. By using collapsed and collapse classes, it resolves which content to show and
which to hide.

3. HTML content was added to show requested labels.

4. Used CSS :hover on text labels in order to add background color and to show or hide the edit icon. 

5. When clicking the edit button, the label content in the page is hidden and the angular directive
"<custom-input>" is shown in order to allow user to enter a value and persist it to the local storage
on save. This "<custom-input>" directive allows the controller to show either an input-text control, 
an input-number control or a select control by specifying the type property. Also just by "cut-pasting" the custom input tag, you can reuse this control anywhere in the application.

6. I created an angular factory, used as an storageService, injected into the controller and the directive
in order to have quick access to localstorage operations such as set and get. When the app initializes, 
it retrieves values from the session and if available, replaces default vaules as requested.




<div class="row" ng-show="show">
  <div class="col-lg-6">
    <div class="input-group input-group-lg" ng-show="type === 'text'">
      <input class="form-control" type="text" string-to-number ng-model="inputText" placeholder="{{placeHolder}}">
      <span class="input-group-addon">
      <button class="glyphicon glyphicon-floppy-save" ng-click="saveInput()"></button>
    </span>
    </div>
    <div class="input-group input-group-lg" ng-show="type === 'number'">
      <input class="form-control" type="number" ng-model="inputNumber" placeholder="{{placeHolder}}">
      <span class="input-group-addon">
      <button class="glyphicon glyphicon-floppy-save" ng-click="saveInput()"></button>
    </span>
    </div> 
    <div class="input-group input-group-lg" ng-show="type === 'select'">
      <select ng-model="selectValue" class="form-control">
        <option ng-repeat="item in selectOptions" value="{{item.value}}">{{item.display}}</option>
      </select>
      <span class="input-group-addon">
      <button class="glyphicon glyphicon-floppy-save" ng-click="saveInput()"></button>
    </span>
    </div>
  </div>



</div>