ngIf always evaluates as true - javascript

I'm developing an AngularJS application, using v1.3.9. I have a couple ng-if directives which are always evaluating true, and I can't figure out why.
<tr data-ng-repeat="line in chat">
<td class="message-timestamp">{{line.time | date:'short'}}</td>
<div ng-if="line.type === 'gist'">
<td class="message-nick">{{line.nick}}</td>
<td class="message-text">{{line.message}}
<p>
<code ng-show="showGist" walrus-auto-gistify data-gist-id="{{line.options[0]}}"></code>
<br>
<button ng-click="showGist = !showGist" class="btn btn-primary btn-xs">Show/Hide</button>
</p>
</td>
</div>
<div ng-if="false">
<td class="message-nick"><span class="glyphicon glyphicon-arrow-right"></span></td>
<td class="message-text">{{line.message}}</td>
</div>
</tr>
When I run this, both ng-if directives are evaluated as true, so both divs are displayed.
chat is just an array of objects.

I'm pretty sure it has to do with the fact that you have a <div> as a direct child of a <tr>. I've had issues with this type of design in the past where it causes strange behavior.
A solution to this is to put the <div>'s within the <td>, like below:
<tr data-ng-repeat="line in chat">
<td class="message-timestamp">{{line.time | date:'short'}}</td>
<td class="message-nick">
<div ng-if="line.type === 'gist'">{{line.nick}}</div>
<div ng-if="line.type !== 'gist'"><span class="glyphicon glyphicon-arrow-right"></span></div>
</td>
<td class="message-text">
<div ng-if="line.type === 'gist'">
<p>
<code ng-show="showGist" walrus-auto-gistify data-gist-id="{{line.options[0]}}"></code>
<br />
<button ng-click="showGist = !showGist" class="btn btn-primary btn-xs">Show/Hide</button>
</p>
</div>
<div ng-if="line.type !== 'gist'">{line.message}}</div>
</td>
</tr>
EDIT: Attempt at a JSFiddle here

Related

How to add HTML tags using jQuery?

I am a Beginner trying to learn jQuery. I did research about jQuery .wrap(), before(), after() but still don't know how to fix the issue. Check out the below HTML table.
<table id="tlist" class="firstleft">
<tbody>
<td>
<div class="inline-flex">
<span class="inline">1.</span>
<h3 class="nostyle"><span itemprop="name"> Idhuvum Kadandhu Pogum </span></h3>
</div>
<br />
<b>Singers: </b><span itemprop="byArtist">Sid Sriram</span>
</td>
<td>
<a class="dlink anim" href="https://dslink.xyz/Masstamilan.In/Netrikann/Idhuvum-Kadandhu-Pogum-MassTamilan.In.mp3" rel="noopener noreferrer">Download</a>
</td>
<td>
<div class="inline-flex">
<span class="inline">2.</span>
<h3 class="nostyle"><span itemprop="name"> Idhuvum Kadandhu Pogum (Reprise) </span></h3>
</div>
<br />
<b>Singers: </b><span itemprop="byArtist">Girishh,Bombay Jayashri,Amrit Ramnath</span>
</td>
<td>
<a class="dlink anim" href="https://dslink.xyz/Masstamilan.In/Netrikann/Idhuvum-Kadandhu-Pogum-%28Reprise%29-masstamilan.in.mp3" rel="noopener noreferrer">Download</a>
</td>
<td>
<div class="inline-flex">
<span class="inline">3.</span>
<h3 class="nostyle"><span itemprop="name"> Netrikann Title Track </span></h3>
</div>
<br />
<b>Singers: </b><span itemprop="byArtist">Girishh,Poorvi Koutish</span>
</td>
<td>
<a class="dlink anim" href="https://dslink.xyz/Masstamilan.In/Netrikann/Netrikann-Title-Track-masstamilan.in.mp3" rel="noopener noreferrer">Download</a>
</td>
<td>
<div class="inline-flex">
<span class="inline">4.</span>
<h3 class="nostyle"><span itemprop="name"> Po Nilladhe </span></h3>
</div>
<br />
<b>Singers: </b><span itemprop="byArtist">Girishh,Sharanya Gopinath,Syan Saheer</span>
</td>
<td>
<a class="dlink anim" href="https://dslink.xyz/Masstamilan.In/Netrikann/Po-Nilladhe-masstamilan.in.mp3" rel="noopener noreferrer">Download</a>
</td>
</tbody>
You can find the <td> tag before class inline-flex and </td> tag after dlink anim. I want to add <tr> before that particular <td> and </tr> after that particular </td> I want to do this for all items. Please help me guys!
Here's a simple solution that does not require jQuery, just plain JavaScript:
tbd = document.querySelector('tbody')
tds = document.querySelectorAll('tbody td')
for (let i=0; i < tds.length/2; i++) {
tr = document.createElement('tr')
tbd.appendChild(tr)
tr.appendChild(tds[2*i])
tr.appendChild(tds[2*i+1])
}
Note that, although your example does not include a <tr> element under the <tbody>, the browser will add one, so after running this code you'll be left with an empty <tr> (the first one) under the <tbody>.

How to display child component custom display elements in parent component html table

I have a html table where I am showing all of my data from a previous saved state. I have the main component called Options-Grid, where there can be multiple options for each label (options = columns, labels = rows). The labels are statically defined, but the data in each subsequent option varies by option.
I have a component that I want to display in the grid with custom html elements, but when I use the selector tag for that component inside of the table, the display from the component is all forced into one cell. I want the content from the inserted component to match the display of the parent component (options-grid).
Here's options grid that is home to the main table:
<table>
<tbody *ngFor="let section of template?.type[1].option[0].sections; let i = index">
<tr *ngFor="let label of section.labels"
id="row-tag">
<td *ngIf="(label.label != 'Expense')">
{{label.label}}
</td>
<td *ngFor="let option of this.service.c.options; let x = index">
<div *ngIf="i == 0">
<f [label]="label.label"
[code]="label.code"
[num]="x">
</f>
</div>
<div *ngIf="i == 1">
<f [label]="label.label"
[description]="label.description"
[num]="x"
[type]="label.type">
</f>
</div>
</td>
</tr>
</tbody>
<tbody>
**<i-f [label]="label"></i-f>**
</tbody>
</table>
Here's the i-f component with a subset of the table data
<tr id="row-tag">
<td>
{{label}}
</td>
<td *ngFor="let option of this.service.c.options">
<div class="col-sm-12">
<div *ngIf="fModel">
{{ range }}
</div>
<div class="input-group">
<input type="number"/>
<div class="input-group-addon">%</div>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div>
<app-ex (exSaveButtonClick)="toggleAndBindEx($event)"
[modExModalValues]="modExModalValues">
</app-ex>
</div>
</td>
<td *ngFor="let option of this.service.c.options">
<div class="col-sm-12">
<div *ngIf="fModel">
{{ exRange }}
</div>
<div class="input-group input-group-sm">
<input type="number"/>
<div class="input-group-addon">%</div>
</div>
</div>
</td>
</tr>

Cloning objects in jquery

When you click on the buttons + Добавить место работы and + Добавить учебное заведение this object should be copied and appear for information input. 1 click = 1 clone. But I get a lot of clones. What was I wrong about? http://test.bikstart.ru/niz-vac/index2.html
$('.add-study').on('click', function() {
$('.table-vac--study').clone([true]).appendTo(".form__item__study");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form__item form__item__study">
<div class="form__item__wrap">
<img src="img/numer-quest.png" alt="">
<!--<span>1</span>-->
<div class="form__wrap">
<h2 class="h2-quest">Образование</h2>
<span>Укажите учебные заведения, в которых Вы учились или учитесь</span>
</div>
</div>
<table class='table-vac table-vac--study table-vac-none'>
<tr class='tr-vac'>
<td class='td-vac quest-title'>Учебное заведение</td>
<td class='td-vac'><input type="text" placeholder="Учебное заведение" required id="study"></td>
</tr>
<tr class='tr-vac'>
<td class='td-vac quest-title'><span class='star'>*</span> Специальность</td>
<td class='td-vac'><input type="text" placeholder="Специальность" required id="specialty"></td>
</tr>
<tr class='tr-vac'>
<td class='td-vac quest-title'><span class='star'>*</span> Год окончания</td>
<td class='td-vac'><input type="number" required id="year-ending"></td>
</tr>
<tr class='tr-vac'>
<td></td>
<td class="add-study">+ Добавить учебное заведение</td>
</tr>
</table>
<div class="pseudo-table">
<div class="pseudo-table__item">
<pseudo-table-title>Учебное заведение</pseudo-table-title>
<input type="text" placeholder="Учебное заведение" required id="study1">
</div>
<div class="pseudo-table__item">
<pseudo-table-title><span class='star'>*</span> Специальность</pseudo-table-title>
<input type="text" placeholder="Специальность" required id="specialty1">
</div>
<div class="pseudo-table__item">
<pseudo-table-title><span class='star'>*</span> Год окончания</pseudo-table-title>
<input type="number" required id="year-ending1">
</div>
</div>
<!--<span class="add-study">+ Добавить учебное заведение</span>-->
</div>
Your problem is that you have multiple elements with the class table-vac--study after you have added the first clone to the DOM:
$('.table-vac--study') //this gets all elements with the class
If you only want one element with the class, you need to specify what element in the class you want.
If you want to the closest element with the class table-vac--study, you can use DOM traversal:
$(this).closest('.table-vac--study').clone([true]).appendTo(".form__item__study");
If you always want the first element with the class:
$('.table-vac--study:first').clone([true]).appendTo(".form__item__study");

Angular2 Javascript Push - Add item to array

I'm building a form in Angular2 which contains a field that is an array of objects. I've so far built the table with a Delete Row button per row and an Add Row button. These use the JavaScript push() and slice() methods.
There is a big bug though:
When adding a new row, the content of the previous rows is deleted.
That is to say, the content of the row is deleted, not the row itself.
Any ideas why?
Component Code:
public addRow(): void {
this.table.push({});
}
public deleteRow(row: object): void {
this.table.splice(this.table.indexOf(row), 1);
}
HTML Template
<form #TimesheetForm="ngForm" (ngSubmit)="saveTimesheet()">
<div class="row">
<div class="col text-right">
<button type="button" class="btn" (click)="addRow()"><i class="fa fa-plus-square" aria-hidden="true"></i> Add Row</button>
</div>
</div>
<table class="table">
<thead>
<td class="table__header">Date</td>
<td class="table__header">Time</td>
<td class="table__header">Actions</td>
</thead>
<tbody>
<tr *ngFor="let row of table">
<td class="table__item">
<input class="input" [(ngModel)]="row.date" name="date">
</td>
<td class="table__item">
<input class="input" [(ngModel)]="row.time" name="time">
</td>
<td class="table__item">
<button type="button" class="btn btn--negative" (click)="deleteRow(row)"><i class="fa fa-times" aria-hidden="true"></i> Delete</button>
</td>
</tr>
<tr *ngIf="school.rows.length == 0">
<td colspan="3">No rows exist yet. Click Add Row to start logging your timesheet.</td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<div class="col">
<button class="btn btn--positive" type="submit"><i aria-hidden="true" class="fa fa-check"></i> Save</button>
</div>
<div class="col text-right">
<button class="btn btn--negative"><i aria-hidden="true" class="fa fa-times"></i> Cancel</button>
</div>
</div>
</form>
With template driven forms, we need to remember that the name attribute needs to be unique, otherwise the fields will be evaluated as the same field. So what your form does now, is not adding new form controls when you add new rows, instead it manipulates the one and same form field. If you were to put something like <pre>{{TimesheetForm.value | json}}</pre> in your template, you can see, that despite pushing new rows, there is only one form control name date and one form control named time.
So what we need to do is to provide an unique name, we can do that by using the index of the items in your table array. So do the following:
<tr *ngFor="let row of table; let i = index">
<td>
<input [(ngModel)]="row.date" name="date{{i}}">
</td>
<td>
<input [(ngModel)]="row.time" name="time{{i}}">
</td>
<!-- more code here -->
</tr>

Angularjs popover nglick does not trigger at second time

My problem is I create a popover for controlling the element's width and offset.
Here is the screenshot for better understanding.
However, the problem is when first click the element (for example: Description1 ), the popover pops up and the ng-click of the four arrows work. But second time click the element, the popover still comes, but the ng-click of the four arrows does not works anymore!
Here is part of the html code:
<div id="sortable" ng-repeat="object in arrayForShow">
<div ng-show="checkType(object)">
<div ng-switch on="getKeyValue(object)">
<div ng-switch-when="default">
<div ng-class="classGenerate(object)" class="well nomargin" id="resizable" pop-over-width-offset argument='object' addwidth='addWidth(object)' decreasewidth='decreaseWidth(object)' addoffset='addOffset(object)' decreaseoffset='decreaseOffset(object)'>
{{object.default}}
</div>
pop-over-width-offset is an directive, and pass object into it and bind four method: addWidth, addOffset, decreaseOffset, which are in the controller.
The directive part code:
app.directive "popOverWidthOffset", ($templateCache, $compile)->
restrict: 'A',
controller: 'CustomiseFormCtrl'
scope: {
argument: '='
addwidth: '&'
decreasewidth: '&'
addoffset: '&'
decreaseoffset: '&'
}
link: (scope, element, attrs)->
content = $templateCache.get('angular/templates/popOverCustomisationChangeWidthOffset.html')
scope.$watch 'content', ()->
popOverContent = $compile(content)(scope)
options = {
content: popOverContent,
placement: "top",
html: true,
trigger: "click"
}
$(element).popover(options)
, true
And the template url code is as follows:
<table>
<tbody>
<tr>
<td>
<a class="btn btn-link" ng-click="addwidth(argument)">
<span class="glyphicon glyphicon-chevron-up">
</a>
</td>
<td> </td>
<td>
<a class="btn btn-link">
<span class="glyphicon glyphicon-chevron-up" ng-click="addoffset(argument)">
</a>
</td>
</tr>
<tr>
<td class="form-group" width="40px;">
<input class="form-control" ng-model="argument.position[1]" style="text-align: center;">
</td>
<td> </td>
<td class="form-group" width="40px;">
<input class="form-control" ng-model="argument.position[2]" style="text-align: center;">
</td>
</tr>
<tr>
<td>
<a class="btn btn-link" ng-click="decreasewidth(argument)">
<span class="glyphicon glyphicon-chevron-down">
</a>
</td>
<td> </td>
<td>
<a class="btn btn-link">
<span class="glyphicon glyphicon-chevron-down" ng-click="decreaseoffset(argument)">
</a>
</td>
</tr>
</tbody>
</table>
Replace this:
popOverContent = $compile(content)(scope)
with this:
popOverContent = function() {
return $compile(content)(scope);
};
;)

Categories

Resources