5

What I'm basically trying to do is wrap grid element divs into angular components. The effort is to reduce typing strokes and get a standard for inputs:

<bootstrap-row>
   <bootstrap-input-text col=6 ng-model="$ctrl.model" label="hey!">
</bootstrap-row>

Which would render something like the following

<div class="row">
   <div class="col-md-6">
       <label>hey!</label>
       <input type="text" ng-model="$ctrl.model">
    </div>
</div>

It works, kind of. The javascript works fine with the model binding, it's just that the CSS gets mangled. I have a codeopen here: https://codepen.io/anon/pen/JmxmoY?editors=1111

It has something to do with how the browser renders the <bootstrap-input-text> in between the row div and the column div. If I open up dev tools and inspect the difference between <bootstrap-row> and <bootstrap-input-text>, there are none. Is there a way around this or am I SOL?

2
  • In your codepen you're wraping the input in a .form-group. I think that is what you missed Commented Oct 26, 2018 at 20:40
  • @graciano - that does not do anything. I updated codeopen to reflect wrapping the elements around .form-group Commented Oct 26, 2018 at 21:20

2 Answers 2

3

Try this one

.component('bootstrapColumn', {
    bindings: {
        column: "@"
    },
    transclude: true,
    template: function ($element, $attrs) {
        $element.addClass('col-md-' + $attrs.column);
        return '<div ng-transclude></div>';
    }
})

Are you trying to apply a specific solution with components? Cause you can try this as a Directive

.directive('bootstrapCol', function () {
    return {
        restrict: 'EAC',
        scope: {
            column: '@'
        },
        link: function (scope, element) {
            var tc = 'col-md-' + scope.column;
            element.addClass(tc);
        }
    }

})

It gives you plenty of properties either use it in your custom component

<bootstrap-row>
        <bootstrap-col column="4">
            <label>Input 5</label>
            <input type="text" class="form-control">
        </bootstrap-col>
        <div class="bootstrap-col" column="4">
            <label>Class</label>
            <input type="text" class="form-control">
        </div>

        <div bootstrap-col column="4">
            <label>Property</label>
            <input type="text" class="form-control">
        </div>
    </bootstrap-row>

(function () {
    'use strict';
    angular
        .module('test', [])
        .component('bootstrapRow', {
            transclude: true,
            template: '<div class="row" ng-transclude></div>'
        })
        .component('bootstrapColumn', {
            bindings: { column: "@"},
            transclude: true,
            template: function ($element, $attrs) {
                $element.addClass('col-md-' + $attrs.column);
                return '<div ng-transclude></div>';
            }
        }).directive('bootstrapCol', function () {
            return {
                restrict: 'EAC',
                scope: { column: '@' },
                link: function (scope, element) {
                    var tc = 'col-md-' + scope.column;
                    element.addClass(tc);
                }
            };
        });
})();
<html>
<head>
    <title>fun with bootstrap and elements</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.js"></script>
</head>
<body ng-app="test">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6">
                <div class="form-group">
                    <label>Input 1</label>
                    <input type="text" class="form-control">
                </div>
            </div>
            <div class="col-md-6">
                <div class="form-group">
                    <label>Input 2</label>
                    <input type="text" class="form-control">
                </div>
            </div>
        </div>

        <bootstrap-row>
            <bootstrap-column column="6">
                <div class="form-group">
                    <label>Input 3</label>
                    <input type="text" class="form-control">
                </div>
            </bootstrap-column>

            <bootstrap-column column="6">
                <div class="form-group">
                    <label>Input 4</label>
                    <input type="text" class="form-control">
                </div>
            </bootstrap-column>
        </bootstrap-row>

        <bootstrap-row>
            <bootstrap-col column="4">
                <div class="form-group">
                    <label>Element-As Component</label>
                    <input type="text" class="form-control">
                </div>
            </bootstrap-col>
            <div class="bootstrap-col" column="4">
                <div class="form-group">
                    <label>Class</label>
                    <input type="text" class="form-control">
                </div>
            </div>
            <div bootstrap-col column="4">
                <div class="form-group">
                    <label>Property</label>
                    <input type="text" class="form-control">
                </div>
            </div>
        </bootstrap-row>
    </div>
</body>
</html>

Sign up to request clarification or add additional context in comments.

4 Comments

From my understanding components kind of get rid of directives for the most part. You really don't need directives much anymore with the addition of components in 1.5. However, can you put that in a codepen doc or plunkr or something to demonstrate that it doesn't screw up CSS styles for the row/col width values?
Never mind I just did that. What's kind of neat about this solution is that I can apply the col-md-6 to the <bootstrap-col> tag itself and skip the <div> template. I guess the next question is, is it ok to have a class styled around <div> applied to a custom element instead?
I have just started to reply on stack overflow. ill have in mind. Although I made it on your codepen ref. In AngularJs i used AngularMaterialJs[1] for its flexible components which you can use them with bootstrap. Take in mind your devises layout on your template you may need xs sm lg etc properties of grid. I use to avoid styling on elements cause i had overlaps on custom plugins in the past. GL far well [1]: material.angularjs.org/latest/layout/alignment
FYI - this is a bootstrap css grid not an angular materials one. In fact the client does not like how Material looks as far as it's form inputs are concerned.
-2
<div class="row" ng-controller="PortfolioCtrl">
      <div class="col-lg-4 col-md-4 col-sm-6 mb-3" ng-repeat-start="stuff in profile track by $index">
        <div class="card">
          <div class="card-header">
            {{stuff.name}}
          </div>
          <div class="card-body">
            <h5 class="card-title">{{stuff.title}}</h5>
            <p class="card-text text-justify">{{stuff.desc}}</p>
          </div>
        </div>
      </div>
      <div ng-repeat-end>
        <div class="clearfix visible-lg-block" ng-if="($index+1) % 6 == 0"></div>
        <div class="clearfix visible-md-block" ng-if="($index+1) % 3 == 0"></div>
        <div class="clearfix visible-sm-block" ng-if="($index+1) % 2 == 0"></div>
    </div>
</div>

1 Comment

This isn't a very good answer to this question. Not only is it very poorly formatted, but even if it were formatted better, there are no descriptions of what this does or what parts of it are relevant to the question; Instead, it's just a code paste, which isn't really helpful to people in the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.