Diego Victor de Jesus
Diego Victor de Jesus

Reputation: 3003

Angular - Use row class on outside div with child custom components

I have a customized component with bootstrap columns as input parameters that works like this:

<div *ngIf="isColumn" [ngClass]="'col-md-' + labelColumns">
    <label>
        {{label}}
        <i *ngIf="isRequired" class="required-asterisk">*</i>:
    </label>
</div>

<div *ngIf="isColumn" [ngClass]="'col-md-' + inputColumns">
    <input [attr.maxlength]="maxLength" [(ngModel)]="value" [eds-required]="isRequired" />
</div>

I want to control the row class from outside this template so i can create multiple inline components like this one. So i did this:

<div class="row no-gutters">
    <quick-text-input isColumn="true" isRequired="true" label="TESTE"></quick-text-input>
</div>

However, the text input components are appearing above each other, as if the template didn't recognize the outside div's row class.

Is there a way for bootstrap div rows to align custom templates with columns?

Edit: labelColumns and inputColumns are two input variables with default values

Upvotes: 1

Views: 1637

Answers (3)

nash11
nash11

Reputation: 8660

In Bootstrap 3, the CSS used for the row class was display: table. The code you have written would work if used with Bootstrap 3 (along with the right Bootstrap 3 class names). Bootstrap 4, on the other hand, is built with flexbox, so the row class now uses display: flex instead. When display: flex; is used, it only applies to its direct children. In your code, the direct children of the container that uses row contain quick-text-input and the first element within quick-text-input contains the col-md- classes, so your grid will break since the contents of quick-text-input are not direct children of the row container.

From the docs:

To create a flex container, we set the value of the area's container's display property to flex or inline-flex. As soon as we do this the direct children of that container become flex items.

What you need is basically a nested flexbox where the inner flexbox would be quick-text-input and the outer one would be the div in your parent component which encapsulates the quick-text-input elements.

quick-text-input.component.html

<div class="row">
    <div *ngIf="isColumn" class="col-4">
        <label>
            {{label}}<i *ngIf="isRequired" class="required-asterisk">*</i> :
        </label>
    </div>

    <div *ngIf="isColumn" class="col-8">
        <input class="form-control" [attr.maxlength]="maxLength" [(ngModel)]="value" />
    </div>
</div>

You don't seem to be passing labelColumns and inputColumns as @Input so I have just changed them to col-md-4 and col-md-8 respectively. You can used labelColumns and inputColumns if you need them.

Now, in the parent component, depending on how many elements we need in a row, we need to set the col- class in our quick-text-input element.

<div class="row">
    <span class="mb-2 mx-3">Single element in row</span>
    <quick-text-input class="col-12" isColumn="true" isRequired="true" label="TESTE"></quick-text-input>

    <span class="w-100 mb-2 mx-3">Two elements in a row</span>
    <quick-text-input class="col-6" isColumn="true" isRequired="true" label="TESTE"></quick-text-input>
    <quick-text-input class="col-6" isColumn="true" isRequired="true" label="TESTE"></quick-text-input>
</div>

Here is an example on StackBlitz. This is how the output will look.

Upvotes: 3

deelde
deelde

Reputation: 1591

you are right , this sholud work like in this example:

https://stackblitz.com/edit/angular-4qn1de

Even if your "labelColumns" is undefined, the input-field are aligned in a row.

But, if i'm removing the boostrap-import from style.css, then the input-fields are align amonng themselves.

Upvotes: 0

Naren Murali
Naren Murali

Reputation: 56868

You could move the row class of bootstrap directly to the component tag and also if you're using bootstrap 4, you need to use col-3 instead of col-md-3, below is a working example, please let me know if this fixes your issue!

// app.component.html
<app-test class="row no-gutters" isColumn="true" isRequired="true" label="TESTE"></app-test>

// test.component.html
<div *ngIf="isColumn" class="col-{{ labelColumns }}">
    <label>{{label}}<i *ngIf="isRequired" class="required-asterisk">*</i>:</label>
</div>

<div *ngIf="isColumn" class="col-{{ inputColumns }}">
    <input [attr.maxlength]="maxLength" [(ngModel)]="value" />
</div>

StackBlitz

Upvotes: 0

Related Questions