【问题标题】:Angular directive for horizontal Bootstrap form水平引导形式的角度指令
【发布时间】:2015-06-05 12:49:23
【问题描述】:

我正在尝试为我的 Angular 构建一个指令,以帮助集成表单字段。我已经从他的 Angular playbook 中实现了 Scott Allens 的解决方案,它适用于正常的堆叠形式。

但是,我需要将其改为水平形式。这是我的代码:

标记

<div form-group>
    <label for="name">Name</label>
    <input type="text" id="name" ng-model="vm.name">
</div>

formGroup 指令

function link(scope, element) {
    setupDom(element[0]);
}

function setupDom(element) {
    var label = element.querySelector("label");
    label.classList.add("control-label");

    var input = element.querySelector("input, textarea, select");
    var type = input.getAttribute("type");
    if (type !== "radio" && type !== "checkbox"){
        input.classList.add("form-control");
    }

    element.classList.add("form-group");
}

function formGroup() {
    return {
        restrict: "A",
        link: link
    }
}

输出变成:

<div form-group="" class="form-group">
    <label for="name" class="control-label">Name</label>
    <input type="text" id="name" ng-model="vm.name" class="form-control">
</div>

这对于堆叠形式来说很好。由于我需要一个水平表格,我的输出需要如下所示:

<div form-group="" class="form-group">
    <label for="name" class="control-label col-sm-3">Name</label>

    <div class="col-sm-9">
        <input type="text" id="name" ng-model="vm.name" class="form-control">
    </div>
</div>

我尝试了许多解决方案,我可以让它与单个元素一起工作,例如输入、文本区域或选择。当我的标记中有两个单选按钮时,它变得更加棘手,如下所示:

<div form-group>
    <label>Active</label>

    <div class="radio">
        <label>
            <input type="radio" name="active" ng-value="true" ng-model="vm.active"> Yes
        </label>
    </div>
    <div class="radio">
        <label>
            <input type="radio" name="active" ng-value="false" ng-model="vm.active"> No
        </label>
    </div>
</div>

上述代码的期望输出应该是:

<div form-group class="form-group">
    <label class="control-label col-sm-3">Active</label>

    <div class="col-sm-9">
        <div class="radio">
            <label>
                <input type="radio" name="active" ng-value="true" ng-model="vm.active"> Yes
            </label>
        </div>
        <div class="radio">
            <label>
                <input type="radio" name="active" ng-value="false" ng-model="vm.active"> No
            </label>
        </div>
    </div>
</div>

请注意表单组中的输入不是固定的。它可以是单个输入、文本区域、选择、一组单选按钮或复选框。我不知道如何才能做到这一点。任何帮助表示赞赏。谢谢!

更新

我对 Mark Veenstra 的代码做了一些小改动,以使其(在某种程度上)工作:

function setupDom(element) {
    element.classList.add("form-group");

    var label = element.querySelector("label");
    label.classList.add("control-label", "col-sm-3");

    var input = element.querySelector("input, textarea, select");
    var type = input.getAttribute("type");
    if (type !== "radio" && type !== "checkbox"){
        input.classList.add("form-control");
        angular.element(input).wrap(angular.element('<div class="col-sm-9"></div>'));
    }

    var div_radio = element.querySelector("div[class='radio']");
    angular.element(div_radio).wrap(angular.element('<div class="col-sm-9"></div>'));
}

这不能完全按预期使用多个无线电输入,因为它仅将 &lt;div&gt; 包装在第一个无线电输入元素上。

在我的原始帖子中使用标记代码的单选按钮示例的输出是:

<div form-group="" class="form-group">
    <label class="control-label col-sm-3">Active</label>

    <div class="col-sm-9">
        <div class="radio">
            <label>
                <input type="radio" name="active" ng-value="true" ng-model="vm.active" value="true"> Yes
            </label>
        </div>
    </div>
    <div class="radio">
        <label>
            <input type="radio" name="active" ng-value="false" ng-model="vm.active" value="false"> No
        </label>
    </div>
</div>

解决方案

查看 Plunker 的最终结果:http://plnkr.co/edit/Wv6V86hHTCz3URS9DhdU?p=preview

【问题讨论】:

  • 你能分享一个 plunker 来展示你实现这一目标的尝试吗?这样就更容易看出哪里出错了。
  • @AbhishekJain 查看此Plunker 了解最终结果,如果您有兴趣

标签: angularjs forms twitter-bootstrap angularjs-directive


【解决方案1】:

angular.elementdocumentation 中,您可以找到wrap() 方法,以便能够将HTML 包裹在选定元素周围。或查看this直接链接。

因此,您可以在指令中执行的操作是更改 setupDom() 函数以匹配您对每种表单元素类型的要求。

function link(scope, element) {
    setupDom(element[0]);
}

function setupDom(element) {
    element.classList.add("form-group");

    var label = element.querySelector("label");
    label.classList.add("control-label col-sm-3");

    var input = element.querySelector("input, textarea, select");
    var type = input.getAttribute("type");
    if (type !== "radio" && type !== "checkbox"){
        input.classList.add("form-control");
        input.wrap(angular.element('<div class="col-sm-9"></div>'));
    }

    var div_radio = element.querySelectorAll("div[class='radio']");
    div_radio.wrap(angular.element('<div class="col-sm-9"></div>'));
}

function formGroup() {
    return {
        restrict: "A",
        link: link
    }
}

注意:此代码未经测试,可能有一些小错误,但我想你现在明白了。

【讨论】:

  • 谢谢你的建议,@mark。请看我下面的帖子。
  • 也许把element.querySelector("div[class='radio']")改成element.querySelectorAll("div[class='radio']")
  • 试过了,但它把每个广播组都包裹在自己的div中。我用解决方案更新了我原来的问题并链接到 Plunker。
  • 看起来你在我向正确方向提出了一些提示后让它工作了。如果你能给我一些信任,那就太好了。
【解决方案2】:

Mark 的建议很接近,但并没有完全解决我的问题。我最终在我的 formGroup 指令中使用了以下代码:

(function (module) {
    "use strict";

    function link(scope, element) {
        setupDom(element[0]);
    }

    function setupDom(element) {
        element.classList.add("form-group");

        var children = angular.element(element).children();
        var labels = children.splice(0, 1);

        // Set label classes
        labels[0].classList.add("control-label", "col-sm-3");

        // Wrap children in div
        angular.element(children).wrapAll(angular.element("<div class='col-sm-9'></div>"));

        // Handle inputs
        var inputs = element.querySelectorAll("input, textarea, select");
        for (var i = 0, len = inputs.length; i < len; i++) {
            var input = inputs[i],
                type = input.getAttribute("type");

            if (type !== "radio" && type !== "checkbox") {
                input.classList.add("form-control");
            }
        }
    }

    function formGroup() {
        return {
            restrict: "A",
            link: link
        }
    }

    module.directive("formGroup", formGroup);

}(angular.module("app.core")));

看看这个 Plunker 看看它的实际效果:http://plnkr.co/edit/Wv6V86hHTCz3URS9DhdU?p=preview

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多