2016-07-08 5 views
0

Я хочу иметь <input type="text"> в Угловом приложении, которое отображает многоточие (если не под редактированием), если значение, предоставленное пользователем, слишком длинное для отображения в пользовательском интерфейсе.Как реализовать (динамическую ширину) текстовый ввод с эллипсисом и меткой в ​​Angular?

Ввод текста будет иметь динамическую ширину, рядом с ним будет текстовая метка, а вход должен быть занят всем свободным пространством после метки.

Этикетки должны быть однострочными независимо от длины.

Однако Я знаю, что HTML текст входы (<input>) не может иметь многоточие, только регулярные HTML элементы, такие как <div> может. Может ли это быть достигнуто?

ответ

0

Посмотрите this plunk

Angular text input with ellipsis

Есть много вещей в игре:

  • значение отображается как обычный <span> (чтобы быть в состоянии показать многоточие), и когда (editing)
  • focusMe директива используется t о сфокусировать внимание на <input>, когда он создан, чтобы заменить фильтр на <span>
  • nonBreaking, чтобы текст метки отображается в одной строке
  • различные правила CSS на основе управления Flexbox На дисплее
  • overflow, text-overflow заботиться о многоточие
  • white-space: nowrap и flex-shrink: 0 убедитесь, что текст метки не разбивается на несколько строк
  • flex-grow: 1 гарантирует, что <input> берет на себя все лишние места

Недостатки:

  • , когда пользователь нажимает на статическую <span> в первый раз, курсор помещается в начале <input>, не в том месте, где пользователь нажал (если он нажал в середине)
  • , когда метки длиннее ширины окна просмотра, не будет отображаться TextInput (предположение, что ширина окна просмотра всегда гораздо шире длины этикетки)

Дополнительная информация:

При добавлении проверки, вы, вероятно, хотите сохранить <input> отображаться, если модель находится в нерабочем состоянии, иначе связанное значение пусто и продолжительность будет пустым.

Чтобы сделать это:

  • проход "имя" в директиве, так и внутри сделать <input name="{{name}}">
  • изменение <span ng-show="!editing && form.{{name}}.$valid">
  • изменение <input ng-show="editing || !form.{{name}}.$valid">

Полный код:

HTML:

<!doctype html> 
<html ng-app="plunker"> 
<head> 
    <meta charset="utf-8"> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script> 
    <script src="script.js"></script> 
    <link rel="stylesheet" href="style.css"> 
    <script type="text/ng-template" id="InputTextWithEllipsis.html"> 
    <div class="input-text-with-ellipsis-wrapper"> 
     <label class="mylabel" ng-bind-html="mylabel | nonBreaking"></label> 
     <span class="dual-input-wrapper"> 
     <span 
      ng-show="!editing" 
      ng-click="editing = true" 
      class="static-text-with-ellipsis">{{mymodel}}</span> 
     <input 
      ng-show="editing" 
      ng-focus="editing = true" 
      ng-blur="editing = false" 
      focus-me="editing" 
      ng-model="mymodel" 
      class="editable-textinput" /> 
     </span> 
    </div> 
    </script> 
</head> 
<body ng-controller="MainCtrl"> 
    <form name="profile"> 
    <input-text-with-ellipsis 
     mylabel="'Name'" 
     mymodel="dataModel.name" 
    ></input-text-with-ellipsis> 

    <input-text-with-ellipsis 
     mylabel="'Last Name'" 
     mymodel="dataModel.lastName" 
    ></input-text-with-ellipsis> 

    <input-text-with-ellipsis 
     mylabel="'A very long label here'" 
     mymodel="dataModel.lastName" 
    ></input-text-with-ellipsis> 
    </form> 
</body> 
</html> 

JS:

var myModule = angular.module('plunker', []); 

myModule.filter('nonBreaking', function($sce) { 
    return function(inputStr) { 
    var outputStr = inputStr.replace(/\s/g, '&nbsp;'); 
    return $sce.trustAsHtml(outputStr); 
    }; 
}); 

/* 
* http://stackoverflow.com/a/14837021/245966 
*/ 
myModule.directive('focusMe', function($timeout, $parse) { 
    return { 
    link: function(scope, element, attrs) { 
     var model = $parse(attrs.focusMe); 
     scope.$watch(model, function(value) { 
     if (value === true) { 
      $timeout(function() { 
      element[0].focus(); 
      }); 
     } 
     }); 
    } 
    }; 
}); 

myModule.controller('MainCtrl', function($scope) { 
    $scope.dataModel = { 
    name: "Fernando", 
    lastName: "Fernandez Sanchez de la Frontera" 
    } 
}); 

myModule.directive('inputTextWithEllipsis', function(){ 
    return { 
    restrict: 'E', 
    templateUrl: 'InputTextWithEllipsis.html', 
    require: ['^form'], 
    scope: { 
     mylabel: '=', 
     mymodel: '=' 
    }, 
    link: function(scope, element, attrs, ctrls) { 
     scope.editing = false; 
    } 
    }; 
}); 

CSS:

* { 
    font: 16pt sans-serif; 
    border: 0; 
    padding: 0; 
    margin: 0; 
    outline: 0; 
} 

.input-text-with-ellipsis-wrapper { 
    background-color: linen; 
    padding: 10px; 

    display: flex; 
    flex-direction: row; 
    align-items: flex-start; 
    justify-content: space-between; 
} 

.mylabel { 
    background-color: #ffddcc; 
    margin-right: 10px; 

    flex-basis: auto; 
    flex-shrink: 0; 
    min-width: 50px; 
} 

.dual-input-wrapper { 
    flex-basis: auto; 
    flex-grow: 1; 
    overflow: hidden; 
    white-space: nowrap; 
    text-align: right; 
} 

.editable-textinput { 
    background-color: #ddf; 

    width: 100%; 
    text-align: right; 
} 

.static-text-with-ellipsis { 
    background-color: #eeccbb; 

    display: block; 
    overflow: hidden; 
    text-overflow: ellipsis; 
}