Table body disappears when clicking first time on checkbox input - html

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.

Related

Why are the form inputs in my html table unclickable?

I am trying to render a table in html that is the representation of a reactive form array.
I loop over the complex object (FormGroup > FormArray > FormGroup > FormArray) With the final array being the data that we want to represent to the UI in its transformed format. (Happens in the function groupFormGroup())
Everything works fine, the data is correctly transformed and displayed.
However, now I am trying to add inputs (NOT formControlName inputs) to the table and when they load, they load without me being able to click into, or change their value. They are not disabled, just unclickable. No errors come up in the console.
What I have tried:
Modifying the class names so it is no longer class='form-control'
Increasing the z-index of inputs to be on the forefront
Making the inputs position relative
Here is the code:
<div class="row" [formGroup]="address">
<div class="col-12">
<table class="w-100">
<thead>
<th></th>
<th>Order ID</th>
<th>GP Code</th>
<th>Product</th>
<th>Quantity</th>
<th>Preset Suite Number</th>
<th></th>
</thead>
<tbody>
<ng-template formArrayName="addressOrders" ngFor let-addressOrder [ngForOf]="address.get('addressOrders').controls" let-ao="index">
<ng-container [formGroup]="addressOrder">
<ng-template ngFor let-fulfillment [ngForOf]="groupFormGroup(addressOrder.get('fulfillments').getRawValue(),'orderDetailId')" let-f="index">
<tr>
<td class='table-input'>
<input type="checkbox"
(change)="updateFulfillmentFormControl(fulfillment,addressOrder,'selected',$event)"/>
</td>
<td>{{addressOrder.get('orderId').value}}</td>
<td>{{fulfillment['gpItemNumber']}}</td>
<td>{{fulfillment['name']}}</td>
<td>{{fulfillment['quantity']}}</td>
<td>
<ng-container *ngIf="fulfillment['isSuite']">
<!-- <input class="form-control" (keydown)="updateFulfillmentFormControl(fulfillment,addressOrder,'suiteNumber',$event)" /> -->
<input type="text" class="form-control" />
</ng-container>
</td>
<td>Edit Detail</td>
</tr>
</ng-template>
</ng-container>
</ng-template>
</tbody>
</table>
</div>
</div>
And the code generating the Form Group:
draw() {
this.formGroup = this.initFormGroup(this.ordersToDisplay)
}
initFormGroup(ordersToDisplay: Array<BulkFulfillCustomer>):FormGroup {
var queueList = this.queues.map(q => q['queue_id']);
return this.fb.group({
customers: this.fb.array(
ordersToDisplay.map(otd => {
return this.fb.group({
gpCustomerNumber:[otd.gpCustomerNumber],
customerName:[otd.customerName],
customerAddresses: this.initAddressForm(otd.addressOrders, queueList)
})
})
)
})
}
initAddressForm(addressOrders: Array<BulkFulfillAddress>, queues:Array<string>):FormArray {
return this.fb.array(
addressOrders.map(ao => {
return this.fb.group({
addressLine:[ao.addressLine],
bundleShipment:[true],
addressOrders: this.initAddressOrdersForm(ao.orders,queues)
})
})
)
}
initAddressOrdersForm(orders: Array<BulkFulfillOrder>, queues:Array<string>):FormArray {
return this.fb.array(
orders.map(o => {
return this.fb.group({
orderId: [o.order.id],
fulfillments: this.initFulfillmentsForm(o.orderDetailFulfillments,queues)
})
})
)
}
initFulfillmentsForm(fulfillments: Array<FulfillmentLine>, queues:Array<string>) {
return this.fb.array(
fulfillments.map(f => {
return this.fb.group({
selected:[true],
expandDetail:[false],
isSuite:[f.inventory.isSuite],
suitePrefix:[f.inventory.suitePrefix],
gpItemNumber:[f.inventory.gpItemNumber],
name:[f.inventory.name],
queueId:[{value:f.inventory.pulseQueueId,disabled:(!this.isPulseFulfill && f.inventory.fulfillmentMethod != INVENTORY_FULFILLMENT_PULSE)}, Validators.compose([Validators.required, ContainsListValidator(queues,'Queue ID')])],
orderDetailId:[f.orderDetailFulfillment.orderDetailId],
pulseOrderId:[f.orderDetailFulfillment.pulseOrderId],
suiteNumber:[{value:f.orderDetailFulfillment.suiteNumber,disabled:!this.isPulseFulfill || !f.inventory.isSuite}, Validators.required],
quantity:[{value:f.orderDetailFulfillment.quantity,disabled:f.orderDetailFulfillment.fulfillmentMethod != 1},Validators.compose([Validators.required, Validators.min(1),Validators.max(f.orderDetailFulfillment.quantity)])]
})
})
)
}

Bootstrap tooltip is switching width on hover

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>

e-form add row presents at top of table

I have an angularjs application and am using e-form to view/add/edit rows in a table. When I choose add, I would like the new row to present at the top of the list rather than the bottom of the list. Once the row is added, it should sort according to the sort order I have designed. But for usability, it's friendlier for the user if the new row is at the top of the page. Any ideas, suggestions, etc. greatly appreciated.
HTML:
<md-button type="button" class="md-accent md-raised" ng-click="searchText=undefined; addContributor()">+ Add Contributor</md-button>
</div>
</md-card-header-text><label>Search: <input ng-model="searchText"></label><button-xs ng-click="searchText=undefined">Clear</button-xs>
</md-card-header>
<md-card-content class="px-helper-pt-0">
<md-table-container>
<table md-table md-progress="vm.contributors">
<colgroup><col></colgroup>
<colgroup><col></colgroup>
<colgroup><col></colgroup>
<colgroup><col></colgroup>
<thead md-head md-order="vm.query.order">
<tr md-row>
<th ng-show=false md-column md-order-by="id" class="md-body-2"><span class="md-body-2">Id</span></th>
<th md-column md-order-by="name" class="md-body-2"><span class="md-body-2">Name</span></th>
<th md-column md-order-by="role" class="md-body-2"><span class="md-body-2">Role</span></th>
<th md-column class="md-body-2"><span class="md-body-2">Edit</span></th>
<th md-column class="md-body-2"><span class="md-body-2"></span></th>
</tr>
</thead>
<tr dir-paginate="item in vm.contributors | filter:{searchField:searchText} | itemsPerPage: 25 | orderBy: vm.query.order">
<td ng-show=false md-cell><span editable-text="item.id" e-disabled e-name="id" e-form="rowform">{{item.id}}</span></a></td>
<td md-cell><span editable-text="item.name" e-name="name" e-form="rowform">{{item.name}}</span></a></td>
<td md-cell><span editable-text="item.role" e-name="role" e-form="rowform">{{item.role}}</span></a></td>
<td style="white-space: nowrap">
<form editable-form name="rowform" onbeforesave="saveContributor($data, item.id)" ng-show="rowform.$visible" class="form-buttons form-inline" shown="inserted == item">
<md-button type="submit" ng-disabled="rowform.$waiting" class="md-accent md-raised">save</md-button>
<md-button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()" class="btn btn-default">Cancel</md-button>
</form>
<div class="buttons" ng-show="!rowform.$visible">
<md-button type="button" class="md-primary md-raised" ng-click="rowform.$show()">edit</md-button>
<md-button class="md-warn md-raised" ng-confirm-message="Are you sure you want to delete?" ng-confirm-click="deleteContributor(item.id)">Delete</md-button>
</div>
</td>
</tr>
</table>
</md-table-container>
controller:
activate();
function activate() {
vm.promises = [getContributors()];
return $q.all(vm.promises).then(function() {
logger.info('Activation', 'Contributors Controller', 'Template Rendered');
});
}
vm.query = {
order: 'name'
};
$scope.deleteContributor = function(contributorId) {
contributorsFactory.deleteContributor(contributorId).then(function(status) {
console.log(status);
if (status !== 409) {
$mdToast.show($mdToast.simple().textContent('Deleted Contributor' + contributorId).theme('success').position('left top'));
contributorsFactory.deleteItemFromArrayById(contributorId, vm.contributors);
}
window.setTimeout(function() {window.location.reload();}, 1000);
});
};
$scope.saveContributor = function(data, id) {
contributorsFactory.updateContributor(JSON.stringify(data), id).then(function(res) {console.log(res);});
$mdToast.show($mdToast.simple().textContent('Form Saved').theme('success').position('left top'));
window.setTimeout(function() {window.location.reload();}, 1000);
};
$scope.addContributor = function() {
$scope.inserted = {
value: ''
};
vm.contributors.push($scope.inserted);
};
function getContributors() {
var item;
return dojo.contribCollection()
.then(function(data) {
vm.contributors = data;
angular.forEach(vm.contributors, function(e) {
e.searchField = e.id + ' ' + e.name + ' ' + e.role + ' ';
If you want new item display in the first . You can try use splice
vm.contributors.splice(0,0,itemyouwanpush)
And why you mixing $scope with controllerAs? Just use one . In html you change ng-click to
vm.addContributor()
And in controller
vm.addContributor()=function(){
vm.contributors.splice(0,0,itemyouwanpush)
}
And dont forget
var vm = this; in controller
This is the code that resolved the issue:
controller.js
vm.contributors.splice(0, 0, $scope.inserted = {name: '', role: ''});

Show text beside checkbox depending on whether it is checked or unchecked

Currently, I have a angularjs table that looks like this.
Here is the code;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="CheckCtrl">
<table class="table table-hover data-table sort display" style="width:100%">
<thead>
<tr>
<th class="Serial_">
Serial
</th>
<th class="Name_">
Name
</th>
<th class="ID_">
ID
</th>
<th class="On_off_">
On/off
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in check_items">
<td>{{item.SERIAL}}</td>
<td>{{item.NAME}}</td>
<td>{{item.ID}}</td>
<td> <input type="checkbox" ng-checked="item.ON_OFF == '1'" ng-click="rowSelected(item)"></td>
</tbody>
</table>
</div>
<script>
var app = angular.module('app',[]);
app.controller('CheckCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.check_items =
[
{
SERIAL:'Test Serial',
NAME:'Test Name',
ID : 10,
ON_OFF : '1'
}
];
$scope.rowSelected = function(row)
{
console.log(row);
};
}]);
</script>
I would like the text "On" to appear beside each checkbox in each row whenever it is checked. The text "Off" will appear beside each checkbox in each row whenever it is unchecked.
I am using angularjs v1.
<td> <input type="checkbox" ng-checked="item.ON_OFF == '1'" ng-click="rowSelected(item)">{{item.ON_OFF == 1 ? 'On' : 'Off'}}</td>
You can do this if you have AngularJS 1.1.5 or more

Send row info to angularjs controller when checkbox in row is clicked

I have some html code which uses angularjs to show a table. On this table, there is a checkbox on each row.
The table looks like this;
Here is the html code.
<div ng-app ng-controller="CheckCtrl">
<table class="table table-hover data-table sort display" style="width:100%">
<thead>
<tr>
<th class="Serial_">
Serial
</th>
<th class="Name_">
Name
</th>
<th class="ID_">
ID
</th>
<th class="On_off_">
On/off
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in check_items">
<td>{{item.SERIAL}}</td>
<td>{{item.NAME}}</td>
<td>{{item.ID}}</td>
<td> <input type="checkbox" ng-checked="item.ON_OFF == '1'"></td>
</tbody>
</table>
</div>
Here is my angularjs controller code.
controller('CheckCtrl', ['$scope', '$http', 'configuration',
function ($scope, $http, $configuration) {
var url_api = $configuration.host + "cloe/webroot/cloe-cloud/app/API.json";
$http.get(url_api).success(function(data)
{
$scope.check_items = data;
});
This is what I want. When a user clicks on a checkbox, information regarding all the items on that particular row belonging to the clicked checkbox is sent to a angualrjs controller function for processing. This information should include the Serial, Name, ID and new state of On/Off after clicking on the checkbox.
I am using angularjs v1 and twitter bootstrap.
EDIT: Edited the original question details to indicate that the row information should be sent whenever the checkbox is clicked and not only when the checkbox is enabled.
We can use ng-change to send row data to controller as object.
After that, you can retrieve row data as following:
var serial = row.SERIAL;
var name = row.NAME;
var id = row.ID;
var onOff = row.ON_OFF;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="CheckCtrl">
<table class="table table-hover data-table sort display" style="width:100%">
<thead>
<tr>
<th class="Serial_">
Serial
</th>
<th class="Name_">
Name
</th>
<th class="ID_">
ID
</th>
<th class="On_off_">
On/off
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in check_items">
<td>{{item.SERIAL}}</td>
<td>{{item.NAME}}</td>
<td>{{item.ID}}</td>
<td> <input type="checkbox" ng-checked="item.ON_OFF == '1'" ng-click="rowSelected(item)"></td>
</tbody>
</table>
</div>
<script>
var app = angular.module('app',[]);
app.controller('CheckCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.check_items =
[
{
SERIAL:'Test Serial',
NAME:'Test Name',
ID : 10,
ON_OFF : '1'
}
];
$scope.rowSelected = function(row)
{
console.log(row);
};
}]);
</script>
You can maybe use something like this,
HTML:
<input type="checkbox" ng-checked="item.ON_OFF == '1'" ng-change="checkSubmit(item.serial,item.name,item.id,item.on_off)">
JS:
function checkSubmit(serial,name,id,on_off){
...
/*Processing can happen now with the parameters obtained*/
...}
NOTE: The case of the variables may be wrong
Some modification to the answer provided by Natiq.
Modify this line
<td> <input type="checkbox" ng-checked="item.ON_OFF == '1'" ng-model="item.selected" ng-change="rowSelected(item)"></td>
to
<td> <input type="checkbox" ng-checked="item.ON_OFF == '1'" ng-model="item.selected" ng-click="rowSelected(item)"></td>
The modification is from ng-change to ng-click. This will solve your problem where the first click does not work but only subsequent clicks work based on the comments posted. Using ng-click ensures that every click will be detected.