Bootstrap tooltip is switching width on hover - html

I have a specific problem with my angular web-application. I'm viewing a matrix in my application with data in it. When I hover over my data in this matrix it will show some basic information about the object. anyway: everytime when I hover over it with my cursor, it changes the width from right to left.
my HTML:
<table class="table table-bordered" style="margin-top: 22px">
<colgroup *ngFor="let y of yArray">
<col style="width: 5%" *ngFor="let x of xArray"/>
</colgroup>
<tr *ngFor="let y of yArray">
<td *ngFor="let x of xArray" [style.background]="getBackground(y+1,x+1)"
[tooltip]="getTooltipContent(y+1,x+1)" placement="bottom">
{{ setBerechnung(y+1, x+1).messwert}}
</td>
</tr>
</table>
my GetTooltipContent-Function (TS/Angular):
public getTooltipContent(yKoordinate: number, xKoordinate: number)
{
const sensor = this.fullZoneResponse.sensorInSurface
.filter(x => x.xKoordinate == xKoordinate && x.yKoordinate == yKoordinate);
let zoneAssignment: IzoneAssignment[] = [];
this.fullZonenResponse.zoneInSurface.forEach((value) => {
zoneAssignment.push(...value.assignmentOfZone);
});
const sensorIsInSurface = zoneAssignment.filter(x => x.idSensor == sensor[0].id);
if (sensorIsInSurface.length > 0) {
this.zoneAssignment = this.fullZonenResponse.zoneInSurface.filter(x => x.id == sensorAssignment[0].idZone);
return this.tooltipContent = this.zoneAssignment[0].description;
}
else
{
return this.tooltipContent = "";
}
}
here is a screenshot of it's normal behaviour:
and another one of it's bad behaviour:
I would be very very thankful if you could help me out!

I fixed it by my own!
The problem was that my ngx-bootstrap tooltip got added to my DOM on runtime. I just added the "container='body'"-attribute, so the tooltip get's added on the right element.
my HTML now:
<tr *ngFor="let y of yArray">
<td *ngFor="let x of xArray" container="body" [style.background]="getBackground(y+1,x+1)" [tooltip]="getTooltipContent(y+1,x+1)" placement="bottom">
{{ setBerechnung(y+1, x+1).messwert}}
</td>
</tr>

Related

Table body disappears when clicking first time on checkbox input

noticed a very strange behaviour from table body - it disappears on the first time when I click on checkboxes. As you will see in the gif, data is fetched successfully without any issues. I'm manipulating it whenever user tries to filter it. Couldn't find anywhere related issues to checkboxes and tables. Thanks for any ideas/advices! Want to mark that there are no errors in console, everything is clean, just inside the tbody gets empty
gif
<aside class="last-updates">
<div>
<span>Last 10 minutes update</span>
<div class="checkboxes">
<input type="checkbox" id="available" value="Available" v-model="needToFilter" #click="filterRoutes = true" />
<label for="available">Available</label>
<input type="checkbox" id="in-progress" value="In progress" v-model="needToFilter" #click="filterRoutes = true" />
<label for="in-progress">In progress</label>
<input type="checkbox" id="completed" value="Completed" v-model="needToFilter" #click="filterRoutes = true" />
<label for="completed">Completed</label>
</div>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">Driver ID</th>
<th scope="col">Route</th>
<th scope="col">Latitude</th>
<th scope="col">Longitude</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody v-if="routes">
<tr v-for="route in filteredRoutes" :key="route">
<th>
{{ route.driver_id }}
</th>
<th>
{{ route.route_name ? route.route_name : 'No data' }}
</th>
<th>
{{ route.route_latitude }}
</th>
<th>
{{ route.route_longitude }}
</th>
<th
:class="
route.route_status === 'Available'
? 'not-driving'
: route.route_status === 'In progress'
? 'in-progress'
: 'completed'
"
>
{{ route.route_status }}
</th>
</tr>
</tbody>
<tbody v-else>
<p>Fetching data from database...</p>
</tbody>
</table>
</aside>
<script>
import { ref, computed } from 'vue';
import getAllRoutes from '../../composables/routes/getAllRoutes';
export default {
async setup() {
let routes = ref([]);
let needToFilter = ref([]);
let filterRoutes = ref(false);
routes = await getAllRoutes();
const filteredRoutes = computed(() => {
console.log(routes);
if (filterRoutes.value) {
if (needToFilter.value.length === 1) {
return routes.filter(route => route.route_status.startsWith(needToFilter.value[0]));
} else if (needToFilter.value.length > 1) {
for (let i = 0; i < needToFilter.value.length; i++) {
// todo
}
}
} else {
// Default sorting, displayed when page is loaded
const sortingDefaultPriority = ['Available', 'In progress', 'Completed'];
return routes.sort((a, b) => sortingDefaultPriority.indexOf(a.route_status) - sortingDefaultPriority.indexOf(b.route_status));
}
});
return { routes, needToFilter, filteredRoutes, filterRoutes };
}
};
</script>
The issue was with #click. For some reasons whenever I click the checkbox it removes the content from tbody tag. Removing the #click helped me out, found another way to watch the click.

angular fake API using jasonplaceholder, getting details after clicking button

I am working on a dummy API with jsonplaceholder, I am getting all posts after clicking button, but i wanna get userid and title on load,and after clicking title need to get that particular body of that id How can i achieve this.
in jasonplaceholder there are 100 posts with id,title,body. on clicking getdata i need only id and title after when I click on title I need to get body as either in paragraph or popup or something.
html
<button (click)="get()">Get Data</button>
<div class="col-md mt-4 mb-4">
<table class="table table-bordered">
<thead>
<tr>
<th>id</th>
<th>title</th>
<th>body</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let d of data">
<td><span>{{d.id}}</span></td>
<td><span>{{d.title}}</span></td>
<td><span>{{d.body}}</span></td>
</tr>
</tbody>
</table>
</div>
ts
get(){
this.userservice.getData().subscribe((data) =>{
console.log(data)
this.data = data
})
}
service
getData():Observable<any>{
const url = "https://jsonplaceholder.typicode.com/posts";
return this.http.get(url)
}
A simple solution would be to use *ngIf and a variable, eg. selectedId
<td (click)="showBody(d.id)"><span>{{d.title}}</span></td>
<td *ngIf="selectedId === d.id"><span>{{d.body}}</span></td>
Then in your component, initiate it:
selectedId: any = null;
and
showBody(id: number){
this.selectedId ? this.selectedId = null : this.selectedId = id;
}
so that it would hide the body if you click on the title again.
As I understand, you need to get the id of the element you clicked on it to show the element's body.
so to achive this, you can write something like this:
component.html
<tr *ngFor="let d of data" (click)="setBody(d)">
<td><span>{{d.id}}</span></td>
<td><span>{{d.title}}</span></td>
</tr>
<!-- Show selected item body here -->
<h1>Selected item body</h1>
<p>{{selectedItemBody}}</p>
component.ts file
[Optional]: you can define the POST interface top of your ts file to have more clean code:
interface POST {
id: number;
title: string;
body: string;
}
setBody(post: POST) {
this.selectedItemBody = post.body;
alert(this.selectedItemBody); // you can remove this alert
}
I provided you this sample working code here in stackblits

Need to get specific html element row index from *ngFor to activate boolean function

I'm trying to build a dynamic table in Angular with add, edit, delete functionality. Both my edit/delete buttons exist as their own column on every single one of the table rows. The edit button (onclick) is designed to make each of the 3 text data fields (in the same row as the edit button itself) turn into input fields whose user-entered text can then be saved.
<table id="thetable" align="center">
<tr>
<th>Application ID</th>
<th>Description</th>
<th>API Key</th>
<th>EDIT/DELETE</th>
</tr>
<tr id="newtablerow" ng-app="tblRowApp" *ngFor="let prov of providers; let i = index">
<td id="tablevalues" *ngFor="let col of columns">
<span id="columnText" ng-init="getRowIndex(i)" *ngIf="!editing">{{prov[col]}}</span>
<span class="editfield" *ngIf="editing">
<input id="changeText" ng-init="getChangeTextCol(col)" type="text" style="margin-right: 10px" placeholder="{{prov[col]}}">
<button ngOnload="getChangeTextCol(col)" (click)="save(changeText.value); !editing">Save</button>
</span>
</td>
<td id="editdelete">
<button class="edit" name="editButton" (click)="editToggle(i)">/</button>
<button class="delete" (click)="deleteRow(i)">x</button>
</td>
</tr>
public editing: boolean = false;
editToggle(event) {
var table = (<HTMLTableElement>document.getElementById("thetable"));
var getTextFields = table.getElementsByClassName("columnText");
for (var i = 0; i < getTextFields.length; i++) {
if (getTextFields[i].getRowIndex(event) == event) {
getTextFields[i].editing = !getTextFields[i].editing;
}
}
}
getRowIndex(event) {
console.log("row index = " + event);
return event;
}
getChangeTextCol(event) {
return event;
}
deleteRow(event) {
this.providers.splice(event, 1);
}
editToggle() is activated on edit button click and finds the current row index of itself by variable i specified by *ngFor. However, I also need to tell angular the row index of the span element containing the html input field to be shown, but I get an error saying property 'getRowIndex' does not exist on type 'Element'. This works for other functions in HTML elements like deleteRow(i), for instance.

How to add html in a location above Razor code ASP.NET MVC

I am using ASP.NET MVC4. I am curious, is there a way to conditionally add/change html code that is higher up in the file than where the conditional statement is?
I am using a partial, and I want to add a button at the top of page to hide and unhide a row that contains M. only if this certain condition code exists in the table. I tried using RendorSection but apparently that doesn't work in a partial.
Currently, I hide the button based on the model being empty or null. The model is just a list. But I want to take it further and hide the button conditionally on if the value M exists but, the conditional statement will be further down the page, than where the button needs to be in the markup.
This is my code:
<div class="container TransactionTableResult" style="padding-top:3px">
#if (Model != null && Model.Count > 0)
{
<button type="button" id="MoveToggle" class="btn btn-info" data-toggle="button" title="Click to toggle display of move transactions.">Moves</button>
}
#if (Model != null && Model.Count > 0)
{
<table id="LogTable" class="table table-striped table-condensed">
<thead>
<tr>
#foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(Model[0]))
{
<th>#descriptor.Name</th>
}
</tr>
</thead>
<tbody>
#foreach (Dashboard.Areas.Transact_Part.BusinessLayer.Models.Transaction trans in Model)
{
string hide = trans.TRANS.Equals("M") ? "display:none" : "";
<tr style="white-space:nowrap; #hide">
#foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(trans))
{
<td>
#descriptor.GetValue(trans)
</td>
}
</tr>
}
</tbody>
</table>

Angular 2: if attr.title in html == array in component

<div class="kalender">
<table *ngIf="datoer">
<tr>
<td *ngFor="let cell of ukeEn()"
[attr.title]="cell.id">{{cell.text}}</td>
</div>
</tr>
</table>
</div>
I would like to check if attr.title (or cell.id) == any of the element's .dato attribute (an element is a type element called Cell, with the attribute dato) in an array called datoer, which is defined in my component. So I need to check the attr.title up against every value in the datoer array. Then I want to add an element (for ex. div or p) in the td if this condition is true.
Is this possible?
If you need more code samle to understand my problem, just ask.
<div class="kalender">
<table *ngIf="datoer">
<tr>
<td *ngFor="let cell of ukeEn()" [attr.title]="cell.id">
<div *ngIf="datoerContains(cell)">{{cell.text}}</div>
</td>
</tr>
</table>
</div>
In your component put this:
datoerContains(cell:any):boolean {
for(let i = 0; i < this.datoer.length; i++) {
if (this.datoer[i].dato == cell.dato) {
return true;
}
}
return false;
}