Vue - Recursively inserting <div> - html

I'm trying to recursively insert a div element that contains a button as follows:
<div v-for="column in 25" :key="column.id" class="columna">
<div v-for="row in 10" :key="row.id" class="recuadro">
{{ row == 1 ? 'PAXXX' : `<div class="selector"><button onclick="colorCell()" /></div>` }}
</div>
</div>
Basically it inserts row element name first and then fulfills the row with a selectable div that has an invisible button.
I'm getting syntax error in <div class="selector"><button onclick="colorCell()" /></div>:
Missing ` (placed right under <div...)
Any suggest will be appreciated

This code from the question above:
{{ row == 1
? 'PAXXX'
: `<div class="selector"><button onclick="colorCell()" /></div>`
}}
Is not valid, as you can place only text (not HTML) inside double mustaches.
Using v-if and v-else works as intended and avoids the syntax error:
<div v-for="column in 25" :key="column.id" class="columna">
<div v-for="row in 10" :key="row.id" class="recuadro">
<span v-if="row == 1">PAXXX</span>
<div v-else class="selector"><button onclick="colorCell()" /></div>
</div>
</div>
Or you can use the v-html attribute to tell vue to treat the contents as raw HTML.
<div v-for="column in 25" :key="column.id" class="columna">
<div v-for="row in 10" :key="row.id" class="recuadro"
v-html="row == 1 ? 'PAXXX' : `<div class='selector'><button onclick='colorCell()' /></div>`"
>
</div>

Related

Property 'x' does not exist on type 'y' in Angular ngIf

I am creating an Angular page to display the results of football matches and would like a warning message to be displayed when there are no matches. I used an ngIf to check if the array containing all matches is different from 0 but specifying in the else the ng-template to refer to gives me an error "Property 'noMatch' does not exist on type 'MainPageComponent'".
This is the piece of html code in which the matches are displayed, and if there are none, I would like the message contained in the ng-template to be displayed.
<div *ngIf="live.length > 0">
<h1 style="color: red;">Live ScoreBoard</h1>
<div *ngFor="let data of live">
<div class="title-box">
<p id="elapsed">{{ data.fixture.status.elapsed }}'</p>
</div>
<div class="title-box">
<div class="team">
<img id="homeLogo" src="{{ data.teams.home.logo }}">
<p id="homeName">{{ data.teams.home.name }}</p>
</div>
<p id="goals">{{ data.goals.home }} - {{data.goals.away}}</p>
<div class="team">
<img id="awayLogo" src="{{ data.teams.away.logo }}">
<p id="homeName">{{ data.teams.away.name }}</p>
</div>
</div>
<hr>
</div>
<ng-template #noPartite>
<p>No matches are scheduled today, however you can check the results of past matches <a routerLink="/matchday">here</a>and the standings here.</p>
</ng-template>
</div>
This is what the terminal returns
Error: src/app/Components/main-page/main-page.component.html:3:43 - error TS2339: Property 'noPartite' does not exist on type 'MainPageComponent'.
3 <div *ngIf="live.length > 0; else noPartite">
~~~~~~~~~
src/app/Components/main-page/main-page.component.ts:7:16
7 templateUrl: './main-page.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component MainPageComponent.
The position of noPartite template is important. You have to move out from <div> element with *ngIf as below:
<div *ngIf="live.length > 0; else noPartite">
...
</div>
<ng-template #noPartite>
...
</ng-template>
Demo # StackBlitz

Restructure the display of instantiated elements in *ngFor

I am currently just adding randomized numbers to an array and displaying them to the user.
<div *ngFor="let temp of randomIntArray; let i = index">
<div *ngIf="i == randomIntArray.length - 1">
This is the real random number {{ temp }}
<div>
<button (click)="addRandomValueIntoRandomIntArray()">
add random number
</button>
</div>
</div>
<div *ngIf="i != randomIntArray.length - 1">
{{ temp }}
</div>
</div>
I think I understand what's happening here as I am creating a new element on the DOM each time the user clicks : addRandomValueIntoRandomIntArray() as its increasing the length of the randomIntArray.
Due to the: *ngIf="i == randomIntArray.length - 1 this will always be the last element and will be always be displayed at the bottom. Is there any feasible way for me to to swap them around and have all the new elements created at the bottom going downwards instead? Below is an image of how it currently looks.
You can reverse the order of ngFor items using randomIntArray.slice().reverse()
and you need to change ngIf condition to i==0.
app.component.html
<div *ngFor="let temp of randomIntArray.slice().reverse(); let i = index">
<div *ngIf="i ==0">
This is the real random number {{ temp }}
<div>
<button (click)="addRandomValueIntoRandomIntArray()">
add random number
</button>
</div>
</div>
<div *ngIf="i != randomIntArray.length - 1">
{{ temp }}
</div>
</div>

highlight word by start and end matches using angular 7

I have a collection of array which is having datas like
[0]: username {kavya} secret {password}
[1]: lorem ipsem text data value
[2]: lorem {{lrm}} datas {{pp}}
I am using foreach to show this data in frontend with
<div *ngFor="let data of output;let i=index">
<div *ngIf="data.includes('{') || data.includes('{{');else isNotEdited;" >
<div class="variable-textarea" contenteditable="false" >
<span>
{{data | slice:' ' }}
</span>
</div>
</div>
<ng-template #isNotEdited>
<ngx-md>{{data}}</ngx-md>
</ng-template>
</div>
Here I achieved like 0,2 row of div will be editable and in case of 1st array is non-editable.
But I want to do like specific matches which word starts with { or {{ and that particular word needs to be highlight and editable.
Is there any option to do in this way
Thanks in advance.
You could split the data into words:
<div *ngFor="let data of arr">
<span *ngFor="let word of data.split(' ')">
<span *ngIf="word.indexOf('{') > -1;else isNotEdited;">
<span class="variable-textarea-2" contenteditable="true">
{{word | slice:' ' }}
</span>
</span>
<ng-template #isNotEdited>
<span class="variable-text-2" contenteditable="false">
{{word}}
</span>
</ng-template>
</span>
</div>
Check this Stackblitz example I made based on your code: https://stackblitz.com/edit/angular-pkg6i9
this is a performance nightmare, you don't want to be running this many functions in template, and your format isn't helping you. map your data ahead of time into a friendlier view model:
this.mappedOutput = this.output.map(data => {
const editable = data.includes('{'); // checking for doubles is redundant
return {
editable,
data: !editable
? data
: data.split(' ')
.map(word => ({
word,
editable: word.trim().startsWith('{') && word.trim().endsWith('}')
}))
};
})
run this whenever your output changes, then use it in template:
<div *ngFor="let data of mappedOutput;let i=index">
<div *ngIf="data.editable;else isNotEdited;" >
<div class="variable-text">
<ng-container *ngFor="let word of data.data">
<div *ngIf="word.editable; else wordTmp" class="variable-textarea inline" contenteditable="true" >
<span>{{word.word}}</span>
</div>
<ng-template #wordTmp>
{{word.word}}
</ng-template>
</ng-container>
</div>
</div>
<ng-template #isNotEdited>
<ngx-md>{{data.data}}</ngx-md>
</ng-template>
</div>
and adjust the styles by adding this to your css:
.variable-textarea.inline {
display: inline-block;
width: fit-content;
margin: 0;
}
here's an edited blitz: https://stackblitz.com/edit/angular-arayve?file=src/app/app.component.html

Use local variable in template html without component Angular2+

I want to use a local variable into my html template to use it in css classes but without linking it with the component. I want to do that :
[local_html_variable = 1]
<div class="css-{{ local_html_variable }}">
Div #1
</div>
[local_html_variable + 1]
<div class="css-{{ local_html_variable }}">
Div #2
</div>
[local_html_variable + 1]
<div class="css-{{ local_html_variable }}">
Div #3
</div>
...
to get
<div class="css-1">
Div #1
</div>
<div class="css-2">
Div #2
</div>
<div class="css-3">
Div #3
</div>
...
Important : the number of div is dynamic.
But I don't achieve it. I tried with <ng-template let-localHtmlVariable> but didn't work.. Any idea ?
You can use *ngFor structural directive
<div *ngFor="let value of [1,2,3]" class="css-{{value}}">
DIV #{{value}}
</div>
Here is a very situational answer that takes advantages of truhy/falsy values :
<ng-container *ngIf="1 as i">
Number is {{ i }}
</ng-container>
Use it in your classes in the container itself :
<div class="css-{{ i }}">With interpolation</div>
<div [class]="'css-' + i">With input</div>
Here is the stackblitz : https://stackblitz.com/edit/angular-3wm4en?file=src%2Fapp%2Fapp.component.html
EDIT explanation :
In javascript, every value can be transalted to boolean : they are truthy or falsy values.
The quick boolean parse operator is the !! double negation.
Let's try :
console.log(!!'');
console.log(!!0);
console.log(!!5);
When we use this notation, the evaluation use the same principle : it tests if the given value is truthy or falsy. In numbers, 1 being truthy, the test checks out, and the as i notation simply creates a template variable.
For information, falsy values are 0, '', null, undefined, infinity, NaN.

ng-if and col col-50 don't seem to go together?

I am trying to generate a table using angular code in HTML. Now I seem to have how I want the table to look which is how I have set up this code:
<div class="row">
<div class="col col-25">Date</div>
<div class="col col-50">Name of Customer</div>
<div class="col col-25">Hours Used</div>
</div>
What I have done is generated a list in angular code (which is done correctly) and I have ordered them in a certain way with Date being the first entry and Hours Used being the last. To generate the table in HTML, I use this code:
<div class="row">
<div ng-repeat="B in ConvertToTableRow(T) track by $index">
<div class="col col-25" ng-if="$index == 0">
{{ B }} &nbsp
</div>
<div class="col col-50" ng-if="$index == 1">
{{ B }} &nbsp
</div>
<div class="col col-25" ng-if="$index == 2">
{{ B }} &nbsp
</div>
</div>
</div>
Everything in the first row works well and styled to what I need it to be but the second entry (when the index is 1) will never style its table to a col-50 but instead will stick with a col-25. Now I have tested to see the if the values are equal to 1 or 2 but it seems that is working correctly and the infomation is also coming out correctly but its just not styling correctly.
Is it possible to style a table this way using Angular and HTML?
Would it not be better to use ng-class? I think there's an even better way, but this is just off the top of my head. I hope this helps! :) Documentation for ng-class
<div class="row">
<div ng-repeat="B in ConvertToTableRow(T) track by $index">
<div class="col" ng-class="{'col-25': $index % 3 !== 1, 'col-50': $index % 3 === 1}">
{{ B }} &nbsp
</div>
</div>
</div>