【问题标题】:How to implement a (dynamic-width) text input with ellipsis and label in Angular?如何在Angular中使用省略号和标签实现(动态宽度)文本输入?
【发布时间】:2016-11-11 07:38:40
【问题描述】:

如果用户提供的值太长而无法在 UI 中显示,我希望在 Angular 应用程序中有一个 <input type="text"> 来显示省略号(如果不是在编辑中)。

文本输入将具有动态宽度,旁边有一个文本标签,并且输入应占用标签后的所有可用空间。

无论长度如何,标签都应该是一行。

但是,我知道 HTML 文本输入 (<input>) 不能有省略号,只有像 <div> 这样的常规 HTML 元素可以。 这能以某种方式实现吗?

【问题讨论】:

    标签: javascript angularjs ellipsis


    【解决方案1】:

    看看this plunk

    有很多事情在起作用:

    • 该值显示为常规的<span>(以便能够显示省略号),单击时会显示<input>(由editing 变量控制)
    • focusMe 指令用于在创建 <input> 以替换 <span> 时为它提供焦点
    • nonBreaking过滤让文字标签显示在一行
    • 各种基于 flexbox 的 CSS 规则控制显示
    • overflow, text-overflow 注意省略号
    • white-space: nowrapflex-shrink: 0 确保文本标签没有分成多行
    • flex-grow: 1 确保 <input> 占用所有额外空间

    缺点:

    • 当用户第一次点击静态<span>时,光标放在<input>的开头,而不是用户点击的地方(如果他点击了中间)
    • 当标签长于视口宽度时,不会显示文本输入(假设视口宽度总是比标签长度宽得多)

    其他信息:

    添加验证时,如果模型处于无效状态,您可能希望保持<input> 显示,否则绑定值为空,span 将为空。

    这样做:

    • 将“名称”传递给指令并在内部执行<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;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-05
      • 2016-09-02
      • 2015-02-03
      • 2013-05-02
      • 2020-09-24
      • 1970-01-01
      • 2019-10-31
      • 1970-01-01
      • 2017-11-22
      相关资源
      最近更新 更多