I have the following vue template
<div v-for="(v, k, i) in subs" :key="index">
<table>
<thead>
<tr>
<th>Barang</th>
<th>Satuan</th>
<th>Jumlah</th>
</tr>
</thead>
<tbody>
<tr v-for="j in ranges[k]">
<td><Select2 :options="goods" #change="fill_units(i)" /></td>
<td><Select2 ref="units" :options="[]" /> </td>
<td></td>
</tr>
</tbody>
</table>
<button #click="ranges[k]++">Add row</button>
</div>
and the data
data(){
return {
ranges: {
makanan: 1,
minuman: 1,
dll: 1
}
subs: {
makanan: 'Makanan',
minuman: 'Minuman',
dll: 'Dan lain-lain'
}
}
}
what I want is, when first Select2 element change its value, this will trigger the next Select2 element to fill its options based on it's ref. the problem is, i is not the correct index for the next Select2, since there might be more row added by the user. I think temporary variable that can hold the total rows on each table can solve the problem, but I don't know how to make that variable inside the template.
equivalent in vanilaJS loop, look like this
let total_rows = 0;
for(let i = 0; i < 3; i++){
for(let j = 0; j < 5; j++){
total_rows++; // i need this variable
fill_units(total_rows);
}
}
I am so sorry if my question isn't clear enough
edit: add select2 code
fill_units(value, i){
const types = this.goods.filter(type => type.id == value);
if(types.length > 0){
const units = types[0].units;
// delete all previous selections
this.$refs.units[i].select2.empty();
// append new selections
this.$refs.units[i].select2.append(`<option value="">Pilih Unit</option>`);
units.forEach(unit => {
this.$refs.units[i].select2.append(`<option value="${unit.id}">${unit.name}</option>`);
})
// this.$refs.units[i].select2.trigger('change');
}
}
Related
Good afternoon, below is the code in it I am getting fields from my table. The 0 field contains a checkbox, how can I find out if it is checked or not(true or false)? You need to change this line: console.log (td.item (f));
var table = document.getElementsByClassName("table-sm");
for (var i = 0; i < table.length; i++) {
var tr = table.item(i).getElementsByTagName("tr");
for (var j = 0; j < tr.length; j++) {
var trr = tr.item(j);
var td = tr.item(j).getElementsByTagName("td");
for (var f = 0; f < td.length; f++) {
if (f === 0) console.log(td.item(f));
console.log(td.item(f).innerText);
}
}
}
Firstly, please learn about JavaScript Table API is much better than just making complex for-loops.
Next time please add full code (HTML/JavaScript) so people can help you.
Now let's fix your code.
Suppose we have this table
<table class="table-sm" id="myTable">
<thead>
<tr>
<th>Checkbox</th>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" name="selected[]" checked /></td>
<td>1</td>
<td>Mohammed</td>
</tr>
<tr>
<td><input type="checkbox" name="selected[]" /></td>
<td>2</td>
<td>Ali</td>
</tr>
</tbody>
</table>
and we want to get the first item of each rows, and check whether the checkbox is checked or not.
We can do it easly using JS Table APIs.
Get the table by it's ID.
var table = document.getElementById("myTable");
Get the table rows
I use Array.from() to convert HTMLCollection to normal array, so I can use Array APIs (Like .forEach).
var rows = Array.from(table.rows);
Loop into table rows, and get cells of each row.
rows.map((row) => {
var cells = Array.from(row.cells);
// TODO add logic here.
});
Get the firstChild of first cell.
rows.map((row) => {
var cells = Array.from(row.cells);
if (Array.isArray(cells) && cells.length > 0) {
var firstChild = cells[0].firstChild;
console.log(firstChild.checked);
}
});
Live Example
I have a table rendered dynamically. There's one <tr class="dolly"> somewhere inside its <tbody> that serves as a reference row - it gets cloned and filled with data later. I need to delete all rows except that one.
What I tried:
for loop: uses an increment which quickly gets invalid as the rows are deleted
while loop: continues until all rows are deleted, which never happens because of the condition
Please let me know if you have any ideas. Please no jQuery.
use document.querySelectorAll('tr:not(.dolly)') to select all tr's except with class .dolly and then iterate over it to remove the filtered tr's.
document.querySelectorAll('table tr:not(.dolly)').forEach((tr) => {
tr.remove();
});
<table>
<tr class="dolly">
<td>One</td>
</tr>
<tr>
<td>Two</td>
</tr>
<tr>
<td>Three</td>
</tr>
</table>
I am gonna share my solution here.
function deleteAllOtherRowExceptOne(exceptionIndex) {
const tableBody = document.querySelector('#my-table-tbody')
const tableBodyRowLength = tableBody.rows.length
let deleteIndex = 0
for (let i = 0; i < tableBodyRowLength; i++) {
if(i == exceptionIndex){
deleteIndex++
} else {
tableBody.deleteRow(deleteIndex)
}
}
}
Here is my solution for this question.
// Fetch all rows
const rows = document.querySelectorAll('tr');
// Iterate through the rows and remove those that do not have the desired
class
const className = 'class-name';
rows.forEach(row => {
if (!row.classList.contains(className)) {
row.remove();
}
});
I took refernce from here - https://bbbootstrap.com/code/delete-all-table-rows-except-one-given-class-javascript-61232938
Fiddle Example
I've a table in which each row has checkbox and another checkbox in to check-all rows (checkboxes) and send ID of selected/all row(s) as JSON object.
I've an object array from (GET) response (server-side pagination is enabled) and stored it in itemsList $scope variable.
Following is my code.
View
<table class="table">
<thead>
<tr>
<th><input type="checkbox" ng-model="allItemsSelected ng-change="selectAll()"></th>
<th>Date</th>
<th>ID</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in itemsList track by $index" ng-class="{selected: item.isChecked}">
<td>
<input type="checkbox" ng-model="item.isChecked" ng-change="selectItem(item)">
</td>
<td>{{item.date | date:'dd-MM-yyyy'}}</td>
<td>{{item.id}}</td>
</tr>
</tbody>
</table>
Controller
$scope.itemsList = [
{
id : 1,
date : '2019-04-04T07:50:56'
},
{
id : 2,
date : '2019-04-04T07:50:56'
},
{
id : 3,
date : '2019-04-04T07:50:56'
}
];
$scope.allItemsSelected = false;
$scope.selectedItems = [];
// This executes when entity in table is checked
$scope.selectItem = function (item) {
// If any entity is not checked, then uncheck the "allItemsSelected" checkbox
for (var i = 0; i < $scope.itemsList.length; i++) {
if (!this.isChecked) {
$scope.allItemsSelected = false;
// $scope.selectedItems.push($scope.itemsList[i].id);
$scope.selectedItems.push(item.id);
return
}
}
//If not the check the "allItemsSelected" checkbox
$scope.allItemsSelected = true;
};
// This executes when checkbox in table header is checked
$scope.selectAll = function() {
// Loop through all the entities and set their isChecked property
for (var i = 0; i < $scope.itemsList.length; i++) {
$scope.itemsList[i].isChecked = $scope.allItemsSelected;
$scope.selectedItems.push($scope.itemsList[i].id);
}
};
Below are the issues I'm facing...
If you check fiddle example than you can see that on checkAll() the array is updated with all available list. But if click again on checkAll() instead of remove list from array it again add another row on same object array.
Also i want to do same (add/remove from array) if click on any row's checkbox
If i manually check all checkboxes than the thead checkbox should also be checked.
I think that you are on the right path. I don't think is a good idea to have an array only for the selected items, instead you could use the isSelected property of the items. Here is a working fiddle: http://jsfiddle.net/MSclavi/95zvm8yc/2/.
If you have to send the selected items to the backend, you can filter the items if they are checked with
var selectedItems = $scope.itemsList.filter(function (item) {
return !item.isChecked;
});
Hope it helps
This will help you for one of the two doubts:
$scope.selectAll = function() {
if($scope.allItemsSelected){
for (var i = 0; i < $scope.itemsList.length; i++) {
$scope.itemsList[i].isChecked = $scope.allItemsSelected;
$scope.selectedItems.push($scope.itemsList[i].id);
}
}else{
for (var i = 0; i < $scope.itemsList.length; i++) {
scope.itemsList[i].isChecked = $scope.allItemsSelected;
}
$scope.selectedItems = [];
}
};
I'm looking for something to achieve solution to point 2.
ng-checked can be used but it is not good to use ng-checked with ng-model.
I am trying to delete multiple columns from html table using javascript.
The logic it is using is that it searches in top row for tag "" and then deletes that column.
The problem is if only one cell in top row is having '', then it deletes that columns fine, but if there are multiple columns it throws error.
Here is my code
<!DOCTYPE html>
<html>
<body>
<table style="width:100%" border='1' id='Just_for_california'>
<tr>
<td><span></span></td>
<td>S</td>
<td><span></span></td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</body>
<script>
var dataTable_length = document.getElementById('Just_for_california').rows[0].cells.length;
var count_rows = document.getElementById('Just_for_california').rows.length;
var column_array = [];
for(var i=0; i<dataTable_length; i++)
{
var str = document.getElementById("Just_for_california").rows[0].cells[i].innerHTML;
if(str.search("<span></span>") != -1)
{
column_array.push(i);
}
}
var len = column_array.length;
for(var i=count_rows-1 ; i>=0;i--)
{
rows_number = document.getElementById('Just_for_california').rows[i];
console.log("row_number:"+i);
for(var j=0; j<len;j++)
{
rows_number.deleteCell(column_array[j]);
}
}
</script>
</html>
It happens because you calculate indexes incorrectly when you delete cells. I refactored you code (making it clearer) and it seems to work now:
var table = document.getElementById('Just_for_california'),
rows = table.rows;
for (var i = 0; i < rows[0].cells.length; i++) {
var str = rows[0].cells[i].innerHTML;
if (str.search("<span></span>") != -1) {
for (var j = 0; j < rows.length; j++) {
rows[j].deleteCell(i);
}
}
}
The problem is that you are trying to remove cells "horizontally" in the row. So say you want to delete cells at indexes 1 and 3 and there are 4 columns in the table. When you delete the first cell 1 it works fine. However then you move to the right and try to remove cell at index 3. This fails because since you have already removed cell 1, there is no cell with index 3 anymore. The maximum index now is 2. Hence the error.
In my improved code I'm removing columns "vertically", so such an issue can't happen.
Demo: http://jsfiddle.net/t2q60aag/
I am trying to get to the logic of the Tic Tac Toe game which I almost have made a logic, but I am stuck while pushing the Data to the array. Here is a fiddle that I have created.
http://jsfiddle.net/afzaal_ahmad_zeeshan/6bgjp/1/
Let me explain the whole thing to you!
I am trying to use the 9 td of the table as the 8 rows of the possible win. For that I have given some of the tds a className depending on their location in the table.
The HTML is simple
<div class="vicvacvoe">
<table>
<tr>
<td class="line1 line4 line7"></td>
<td class="line1 line5"></td>
<td class="line1 line6 line8"></td>
</tr>
<tr>
<td class="line2 line4"></td>
<td class="line2 line5 line7 line8"></td>
<td class="line2 line6"></td>
</tr>
<tr>
<td class="line3 line4 line8"></td>
<td class="line3 line5"></td>
<td class="line3 line6 line7"></td>
</tr>
</table>
</div>
Just a simple table with 9 tds, the CSS is not relative to this so leave it I guess.
jQuery for this also simple one. But I am not able to push the data to the Array.
var vic = $('.vicvacvoe table tr td');
var player = 1;
var tick = '✓';
var cross = 'X';
var user1 = [];
var user2 = [];
vic.click(function () {
var className = $(this).attr('class');
if (className != 'dead') {
// A new board place to write on...
// Now do the processes here...
if (player == 1) {
// First player!
var cArray = className.split(' ');
for (i = 0; i < cArray.length; i++) {
for (j = 0; j < user1.length; j++) {
// check for each class
if (user1[j] != cArray[i]) {
user1.push(cArray[i]);
}
}
}
} else {
/* code for second player, the same */
}
$(this).text('Works!');
$(this).attr('class', 'dead');
}
});
This is the entire jQuery script. Actually when I run the code, it really does go to the end of the stack (to the class attribute change script) and it locks the td for further process and it write Works! in the td too. But I am not able to get the classNames inside the Array for that user. I want to save the line number for each user and then check whether he has 3 spots filled or not. I need help with the Array part.
Thanks!
I prefer simplicity so you could use indexOf to check whether the class is already in the users' array like so:
if (player == 1) {
// First player!
var cArray = className.split(' ');
for (i = 0; i < cArray.length; i++) {
if(user1.indexOf(cArray[i]) == -1) {
user1.push(cArray[i]);
} else {
// css class is already in the array
}
}
}
Your issue is here:
for (j = 0; j < user1.length; j++) {
The only place you add to the user1 array is within this loop. Now the array is initially empty, so clearly this loop will never iterate as user1.length is always 0.
I think your intent with this bit of code was to check if the value was already in the array in which case I suggest using $.inArray.