CSS:行/列操作按钮对齐问题

时间:2018-08-10 16:07:48

标签: html css

我有一个HTML表,其中的行和列由angular js动态创建。 添加行/列后,我希望有一个选项,当用户将鼠标悬停在该行或列上时,将显示一个单击删除按钮的图标,这将删除该行/列。在大多数情况下,它可以很好地解决以下一些问题。

这是我创建的代码笔。 https://codepen.io/anon/pen/PBVoOb

这是我的表格代码:

<table class="table table-bordered">        
      <thead>
        <tr class="actions">
          <th class="unique-id hidden-border" colspan="1"></th>
          <th ng-class="{'active': showColumnActions(c)}" ng-repeat="c in targetTable.columns track by $index"><span>
                     <a class="btn btn-xs"><i class="fa fa fa-pencil" aria-hidden="true"></i></a>
                     <a class="btn btn-xs" ng-click="removeColumn($index)"><i class="fa fa-times-circle" aria-hidden="true"></i></a></span>
          </th>
        </tr>
        <tr>

          <th class="unique-id">ID #</th>
          <th contenteditable="true" ng-repeat="c in targetTable.columns" ng-model="c.label"></th>
          <th class="view-next-set"><a href="#">...</a></th>
          <td class="center add-column"><a href="#" ng-click="addColumn()">+ Add Column</a></td>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="r in targetTable.rows" ng-mouseover="row = $index" ng-mouseleave="row = -1">

          <td class="unique-id" ng-model="r.id">{{r.id}}<div class="btn-group btn-group-xs">
              <button ng-show="row == $index" type="button" class="btn" ng-click="deleteRow($index)"><span class="glyphicon glyphicon-remove"></span></button>
            </div></td>
          <td contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-blur="!r.id? addNewRow(r[column.id], r): undefined" ng-mouseover="setActiveColumn(column)"></td>
          <td class="blank" colspan="2"></td>
        </tr>
        <!--<tr>
                 <td class="unique-id"></td>
                 <td contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="entry" ng-blur="addRow(entry, column.id)"></td>
                 <td class="blank" colspan="2"></td>
              </tr> -->
      </tbody>
    </table>

问题:

  • 对于行:如果将鼠标悬停在ID列上,它将显示删除(X)图标。当他们将鼠标悬停在ID列上时,我希望此图标显示在表格的左侧。我该怎么办。

  • 对于列: 表格上方还有一个顶部边框,当我们继续单击“添加列”按钮时,顶部边框会继续延伸。不知道是什么原因造成的。如何摆脱多余的边界。

1 个答案:

答案 0 :(得分:1)

您可以使用绝对定位来避免调整单元格的大小,并让您将按钮设置在所需的位置。

对于多余的空行,删除:

  {}

来自

var table = {
    id: 0,
    name: "table 14",
    columns: [{ id: 0, label: "Name" }, { id: 1, label: "Age" }],
    rows: [ 

// ... your datas 

],
    uniqueIdCounter: 1037
  };

没有要打印的数据,但会创建一个额外的空行。

示例

td {
  position: relative;/* be the reference for the absolute child */
}
div.btn-group {
  position: absolute ;/* do not disturb the flow */
  left: 0;/* let me be on the far left of my td parent */
}

在一个演示代码段下面。

// Define the `ReportsMockUpsApp` module
angular.module("customControl", ["ngSanitize"]).directive("contenteditable", [
  "$sce",
  function($sce) {
    return {
      restrict: "A", // only activate on element attribute
      require: "?ngModel", // get a hold of NgModelController
      link: function(scope, element, attrs, ngModel) {
        var disable =
          attrs.contenteditable === "false" || !Boolean(attrs.contenteditable);
        if (!ngModel || disable) return; // do nothing if no ng-model

        // Write data to the model
        var read = function(value) {
          var html = element.html() || (typeof value === "string" ? value : "");

          // When we clear the content editable the browser leaves a <br> behind
          // If strip-br attribute is provided then we strip this out
          if (attrs.stripBr && html == "<br>") {
            html = "";
          }
          ngModel.$setViewValue(html);
        };

        // Specify how UI should be updated
        ngModel.$render = function() {
          element.html($sce.getTrustedHtml(ngModel.$viewValue || ""));
        };

        // Listen for change events to enable binding
        element.on("blur keyup change", function() {
          scope.$evalAsync(read);
        });

        setTimeout(function() {
          read(ngModel.$modelValue); // initialize
        });
      }
    };
  }
]);

var app = angular.module("myApp", ["customControl"]);

// Define the `appController` controller on the `ReportsMockUpsApp` module
app.controller("ctrl", function($scope) {
  var table = {
    id: 0,
    name: "table 14",
    columns: [{
      id: 0,
      label: "Name"
    }, {
      id: 1,
      label: "Age"
    }],
    rows: [{
        "0": "Mark Smith",
        "1": 10,
        id: 1035
      },
      {
        "0": "Mathew Coley",
        "1": 54,
        id: 1036
      },
      // add a few to play with delete
      {
        "0": "Mark Smith",
        "1": 10,
        id: 1035
      },
      {
        "0": "Mathew Coley",
        "1": 54,
        id: 1036
      },
      {
        "0": "Mark Smith",
        "1": 10,
        id: 1035
      },
      {
        "0": "Mathew Coley",
        "1": 54,
        id: 1036
      },
    ],
    uniqueIdCounter: 1037
  };

  $scope.tables = [table];
  $scope.targetTable = $scope.tables[0];

  $scope.select = function(tbl) {
    $scope.selectedTable = tbl;
  };

  $scope.addColumn = function() {
    var columns = $scope.targetTable.columns,
      id = columns.length;
    $scope.targetTable.columns.push({
      id: columns.length,
      label: `Column ${id}`
    });
  };

  $scope.targetColumn = null;

  $scope.select = tbl => {
    $scope.selectedTable = tbl;
  };
  $scope.setActiveColumn = (column, active) => {
    $scope.targetColumn = active || active == null ? column : null;
  };
  $scope.showColumnActions = column => {
    return column && $scope.targetColumn == column && column.id != null;
  };
  $scope.deleteRow = function(index) {
    $scope.targetTable.rows.splice(index, 1);
  };
  $scope.updateColumn = (column, index) => {
    var label = column.label;

    if (column.id === undefined && label) {
      // new column
      var columns = $scope.targetTable.columns;
      column.id = columns.length;
      $scope.targetTable.columns.push({});
      return;
    } else if (column.id && label == "") {
      //remove existing column
      $scope.removeColumn(index);
    }
  };
  $scope.setColumnInactive = () => {
    $scope.targetColumn = null;
  };

  $scope.removeColumn = index => {
    //remove existing column
    $scope.targetTable.columns.splice(index, 1);
  };
  $scope.addNewRow = function(value, row) {
    if (!value || value === "" || typeof value !== "string") return;
    $scope.targetTable.rows.push({});
    debugger;
    row.id = $scope.targetTable.uniqueIdCounter++;
  };

  /*$scope.addRow = function(value, column) {    
    if(!value || value === "" || typeof value !== 'string') return;
    else if(column === "") return;
    
    // create new row
    var row = { id: 2000 };
    row[column] = value;
    $scope.targetTable.rows.push(row); 
    
    // clear last row cell..
    this.entry = "";   
    debugger;
  };*/

  /*$scope.viewColumns = function(start, end) {
    var columns = [];
    for (var i = min; i <= max; i ++) {
        columns.push(i);
    }
    return input;
  };*/

  $scope.read = function() {
    return JSON.stringify(table);
  };
});
body {
  margin: 60px 0px;
}

.data-table .nav-pills li {
  text-transform: capitalize;
}

.nav.nav-pills li span {
  padding: 20px;
}

.table .unique-id {
  width: 10px !important;
  text-align: center;
  background-color: #f5f5f5;
}

.table td,
.table th {
  width: 120px;
}

.table .center {
  text-align: center;
}

.table th.font-normal {
  font-weight: normal;
}

.table .view-next-set {
  width: 5px;
  text-align: center;
  font-size: 0.9em;
}

.table .add-column {
  width: 60px;
  font-size: 1em;
  vertical-align: middle;
}

.table .unique-id,
.table td.blank {
  background-color: #f5f5f5;
}

.table tr.actions th {
  border: 0 !important;
  background-color: white !important;
  position: relative;
}

.table tr.actions th>span {
  display: none;
}

.table tr.actions th.active>span {
  display: block;
}

.table tr.actions th a {
  color: #4371bb;
}

.table tr.actions th a:hover {
  color: #28497d;
}

.table th span {
  display: block;
  padding: 2px;
  margin: 0 auto;
  text-align: center;
  position: absolute;
  top: -9px;
  right: -1px;
  background-color: #a6c8ff;
  -webkit-border-top-left-radius: 7px;
  -webkit-border-top-right-radius: 7px;
  -moz-border-radius-topleft: 7px;
  -moz-border-radius-topright: 7px;
  border-top-left-radius: 7px;
  border-top-right-radius: 7px;
}

.table th.hidden-border {
  border: 0 !important;
  border-top: 3;
}

td {
  position: relative;
}

div.btn-group {
  position: absolute;
  left: 0;
}
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular-sanitize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /></script>
<div class="container" ng-app="myApp">
  <div ng-controller="ctrl">
    <div class="panel panel-default data-table">
      <div class="panel-heading">
        <ul class="nav nav-pills">
          <li role="presentation" ng-class="{'active': targetTable == t}" ng-repeat="t in tables"><a href="#" ng-click="select(t)">{{t.name}}</a></li>
          <li><a href="#" ng-click="select(t)">+ Add Table</a></li>
        </ul>
      </div>
      <div class="panel-body">
        <table class="table table-bordered">
          <thead>
            <tr class="actions">
              <th class="unique-id hidden-border" colspan="1"></th>
              <th ng-class="{'active': showColumnActions(c)}" ng-repeat="c in targetTable.columns track by $index" ng-mouseover="setActiveColumn(c)" ng-mouseout="setColumnInactive()"><span>
                         <a class="btn btn-xs"><i class="fa fa fa-pencil" aria-hidden="true"></i></a>
                         <a class="btn btn-xs" ng-click="removeColumn($index)"><i class="fa fa-times-circle" aria-hidden="true"></i></a></span>
              </th>
            </tr>
            <tr>

              <th class="unique-id">ID #</th>
              <th contenteditable="true" ng-repeat="c in targetTable.columns" ng-model="c.label"></th>
              <th class="view-next-set"><a href="#">...</a></th>
              <td class="center add-column"><a href="#" ng-click="addColumn()">+ Add Column</a></td>
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="r in targetTable.rows" ng-mouseover="row = $index" ng-mouseleave="row = -1">

              <td class="unique-id" ng-model="r.id">{{r.id}}
                <div class="btn-group btn-group-xs">
                  <button ng-show="row == $index" type="button" class="btn" ng-click="deleteRow($index)"><span class="glyphicon glyphicon-remove"></span></button>
                </div>
              </td>
              <td contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-blur="!r.id? addNewRow(r[column.id], r): undefined"></td>
              <td class="blank" colspan="2"></td>
            </tr>
            <!--<tr>
                     <td class="unique-id"></td>
                     <td contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="entry" ng-blur="addRow(entry, column.id)"></td>
                     <td class="blank" colspan="2"></td>
                  </tr> -->
          </tbody>
        </table>
      </div>
    </div>
    <div class="well well-sm"><code>{{read()}}</code></div>

  </div>
</div>