I have a table where I want the last row to to display a button, but only on the last row. The code below works on showing and hiding the button, but it appears on every row.
How would I go about only displaying it on the last row?
Viewmodel:
var loadCustomFileName = function () {
for (i = 0; i < self.GetCanSeam().length; i++) {
var obj = {
appendFileName: parseFileName(i),
displayFileName: parseDisplayName(i)
if (i == self.GetCanSeam().length - 1) {
self.isMax(true);
}
};
self.GetCustomFile.push(obj);
}
};
View:
<div class="csFormField" data-bind="visible: GetCustomFile().length > 0">
<table style="width: 100%;">
<thead>
<tr>
<th>File Name Template</th>
<th>File Name Append</th>
</tr>
</thead>
<tbody data-bind='foreach: GetCustomFile()'>
<tr>
<td><p class="cs-label"><label data-bind="text: displayFileName" /></p></td>
<td><p><input class="cs-input" data-bind="textInput: appendFileName" />
<button class="addFormat" data-bind="visible: isMax">+</button></p></td>
</tr>
</tbody>
</table>
</div>
I think your isMax is initialized on parent context. Maybe try this
var obj = {
appendFileName: parseFileName(i),
displayFileName: parseDisplayName(i)
};
obj.isMax = ko.observable(i==(self.GetCanSeam().length - 1));
self.GetCustomFile.push(obj);
You can compare the index of your forloop. If it gets to the last element then visible the button.
Example :https://jsfiddle.net/kyr6w2x3/12/
self.ArrayLength = ko.observable()
self.ArrayLength(self.GetCustomFile().length);
HTML :
<button class="addFormat" data-bind="visible: $index() == $parent.ArrayLength() -1">+</button></p></td>
Related
I need to get the table row value from onclick event. Below the table, I am using
Group name|Manage group
Test 1 | Button
Test 2 | Button
If I click 'Button' from the table row, I need to get the respective group name value from the table row.
Below the script, I am trying. But it is printing only the first group name value "Test 1" for both buttons.
var table = document.getElementById("user_table");
var rows = table.rows;
for (var i = 1; i < rows.length; i++) {
rows[i].onclick = (function (e) {
var rowid = (this.cells[0].innerHTML);
var j = 0;
var td = e.target;
while( (td = td.previousElementSibling) != null )
j++;
alert(rows[1].cells[j].innerHTML);
});
}
alert(rows[1].cells[j].innerHTML) printing group name value Test 1 and if I click second row button it is showing Test 1 only.But I need to get Test 2 if I click second row button.
Html file
<table id="user_table" style='overflow-x:scroll;overflow-y:scroll;width:100%;height:auto' class="table table-bordered" >
<thead>
<tr class="info">
<th>Group Name</th>
<th>User Group</th>
</tr>
</thead>
<tbody id="table_body">
<br>
<% #array.each do |user| %>
<tr>
<td >
<%=user['group_name']%>
</td>
<td>
<button id='manageusrbtn' name="button" type="button" class="editbtn" onclick="manageUserGroups()" style="background-color: #008CBA; color: white; border-radius: 6px;" >Manage User Groups</button>
</td>
<% end %>
</tr>
</tbody>
</table>
I would suggest to attach the click event handler to the button and not to each cell.
For this you can use:
querySelectorAll
forEach
addEventListener
closest
The snippet:
var table = document.querySelectorAll('#user_table tr button');
table.forEach(function(ele) {
ele.addEventListener('click', function (e) {
var rowid = (this.closest('td').previousElementSibling.innerHTML);
console.log(rowid);
})
});
<table id="user_table">
<tr>
<th>Group name</th>
<th>Manage group</th>
</tr>
<tbody>
<tr>
<td>Test 1</td>
<td><button>Button</button></td>
</tr> <tr>
<td>Test 2</td>
<td><button>Button</button></td>
</tr>
</tbody>
</table>
I have a table which contains some data about car makes.
It looks like this:
Now in the table appears data for all makes, but I need to show data only for the make that I've clicked. For example if I click on Audi to show data only for this make.
This is my view where I have populated the table:
<div class="row">
#{var testList = Model.ProductMatchingVehicles.GroupBy(p => p.Make.Name).ToList(); foreach (var item in testList) {
<div class="btn btn-danger btnMake" data-id="#item.Key" id=btnMake onclick="myFunction()">#item.Key</div>
} }
</div>
<div class="row">
<div class="col-xs-12">
<table class="table table-condensed table-striped table-bordered">
<thead>
<tr>
<th>Make</th>
<th>Model</th>
<th>Engine</th>
<th>Data</th>
<th></th>
</tr>
</thead>
<tbody>
#if (Model.ProductMatchingVehicles != null) { foreach (var item in Model.ProductMatchingVehicles) {
<tr>
<td>#item.Make.Name</td>
<td>#item.Model.Name</td>
<td>#item.Engine.Name</td>
</tr>
} }
</tbody>
</table>
</div>
</div>
Can you please advise me how to achieve this in javascript or jquery? Thanks!
You can try with following code:
1) Modify <tbody> as follows:
<tbody>
#if (Model.ProductMatchingVehicles != null) { foreach (var item in Model.ProductMatchingVehicles) {
<tr class="vehicle_rows" data-refId="#item.Key">
<td>#item.Make.Name</td>
<td>#item.Model.Name</td>
<td>#item.Engine.Name</td>
</tr>
} }
</tbody>
Here we have added the class and data-refId attribute to each <tr>
2) Modify the button click function a bit:
<div class="btn btn-danger btnMake" data-id="#item.Key" id=btnMake onclick="myFunction(this)">#item.Key</div>
Here passing this reference to function
3) The function myFunction will have logic something like this:
function myFunction(obj){
var $button = $(obj);
var car_make = $button.data("id"); //reading the data-id of clicked button
//hide all rows first
$(".vehicle_rows").hide();
//show only currenly clicked buttons associated rows
$(".vehicle_rows[data-refId="+car_make+"]").show();
}
I've got two tables. Left side containing all items, right side showing the ordered items. (See picture)
What I want to do:
If an item from the left table is already added on the right table, instead of adding it again, just increase the quantity by one instead. If that's not the case, just add it..
Code:
HTML
<form id="OrderedItemsWithoutBatch" class="orderedDataWithoutBatch">
<table class="orderFormArticlesTable" style="width: 47%;float: right; font-size: 9pt;">
<thead>
<tr>
<th>SKU</th>
<th>Product</th>
<th style="width: 15%">Qty</th>
<th></th>
</tr>
</thead>
<tbody id="orderedItemsVM" data-bind="foreach: orderedItems">
<tr class="clickable" data-bind="css: { alternate: $index()%2 }">
<td data-bind="text: MateriaalSku"> </td>
<td data-bind="text: MateriaalDescription"> </td>
#*<td class="onelineData"><input style="width:2em" type="text" /> [pieces] </td>*#
<td><input class="orderedQty" style="max-width: 15%" data-bind="value: materiaalAantal"/>[pieces]</td>
<td data-bind="click: function() { $parent.orderedItems.remove($data); }">Remove</td>
</tr>
</tbody>
</table>
JS
$(document).ready(function () {
var dataTableForm = $("form.dataWithoutBatch");
var orderedItemsTable = $("form.orderedDataWithoutBatch");
var dataReloading = false;
var currentPage = 0;
//viewModel
var viewModel = {
orderedItems: ko.observableArray(),
items: ko.observableArray(),
sortColumn: ko.observable(),
total: ko.observable()
}
var request = $.post(url, postData);
request.fail(function () {
alert('Failed!');
});
request.always(function () {
listItemsParameterInputs.prop('disabled', false);
$(document.body).removeClass("loading");
dataReloading = false;
if (callback) {
callback();
}
});
request.done(function (data) {
viewModel.total(data.Total);
viewModel.items.removeAll();
for (var index = 0; index < data.Items.length; index++) {
var item = data.Items[index];
if (item.hasOwnProperty("qty")) {
item.qty = ko.observable(item.qty);
}
else {
item.qty = ko.observable("");
}
item.addItem = function () {
//Check if item is already in the table on the right
if(viewModel.orderedItems.indexOf(this) < 0){
viewModel.orderedItems.push(this);
}
else{
// Increase quantity by one.
}
}
viewModel.items.push(item);
}
Instead of using two arrays and removing elements from the second, why don't you use the same array, just add qty variable and show lines only if they satisfy qty()>0
That way, you could just increment the value of qty by one in the first table with this.qty(this.qty()+1); and set the value to 0 in the second when clicking on remove.
Code for your second table should look something like this:
<tbody id="orderedItemsVM" data-bind="foreach: items">
<!-- ko if: qty()>0 -->
<tr class="clickable" >
<td data-bind="text: MateriaalSku"> </td>
<td data-bind="text: MateriaalDescription"> </td>
<td>
<input style="width:2em" type="text" data-bind="value:qty"/>
[pieces]
</td>
<td><a data-bind="click: function() { qty(""); }">Remove</a></td>
</tr>
<!-- /ko -->
</tbody>
more on the if binding at http://knockoutjs.com/documentation/if-binding.html
Cant you just increment the quantity of your observable as follows:
...
else {
// Increase quantity by one.
this.qty(this.qty() += 1)
}
I was working on a university project. They told us to make 2 arrays. The first will have 3 cells with 3 images, and the second will be empty with 1 row.
I need to remove the image from the cell clicked each time in the first table and copy it to the second table!
My problem is that deleteCell() function will only delete the first element each time. I don't know how to delete the CLICKED cells from my table row!
My JS:
var table1 = document.getElementById("myTable");
var table2 = document.getElementById("myTable2");
function DL1() {
var row = document.getElementById("myRow1");
row.deleteCell();
}
function CR2() {
var row = document.getElementById("myRow2");
}
My HTML:
<table id="myTable" class="auto-style1">
<tr id="myRow1">
<td onclick="DL1()"><img src="../../2.jpg" /></td>
<td onclick="DL1()"><img src="../../1.gif" /></td>
<td onclick="DL1()"><img src="../../3.png" /></td>
</tr>
</table>
<table id="my2Table">
<tr id="myRow2"></tr>
</table>
var table1=document.getElementById("myTable");
var table2=document.getElementById("myTable2");
function DL1(elem){
var row = document.getElementById("myRow1");
for(i=0;i<row.children.length;i++) {
if(row.children[i]==elem) {
row.deleteCell(i);
row2=document.getElementById("myRow2");
row2.appendChild(elem);
}
}
}
<td onclick="DL1(this)"><img src="http://placehold.it/100x100"/></td>
<td onclick="DL1(this)"><img src="http://placehold.it/150x100"/></td>
<td onclick="DL1(this)"><img src="http://placehold.it/200x100"/></td>
Demo: https://jsfiddle.net/Lt2cyw0g/2/
So, you need to get index of clicked element (pass it to the function, and check index, and use it in deleteCell() function), then add element to the second table row...
Just pass clicked element to the function:
var table1 = document.getElementById("myTable");
var table2 = document.getElementById("myTable2");
function DL1(td) {
td.parentNode.removeChild(td);
}
function CR2() {
var row = document.getElementById("myRow2");
}
<table id="myTable" class="auto-style1">
<tr id="myRow1">
<td onclick="DL1(this)">
<img src="../../2.jpg" />
</td>
<td onclick="DL1(this)">
<img src="../../1.gif" />
</td>
<td onclick="DL1(this)">
<img src="../../3.png" />
</td>
</tr>
</table>
<table id="my2Table">
<tr id="myRow2"></tr>
</table>
Hope it helps, no need ID:
var a = document.querySelectorAll("table tr");
for(var b in a){
var c = a[b];
if(typeof c == "object"){
c.onclick = function (){
this.offsetParent.deleteRow(this.rowIndex);
}
}
}
<table >
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>1a</td><td>2a</td><td>3a</td></tr>
<tr><td>1b</td><td>2b</td><td>b</td></tr>
</table>
<table>
<tr><td>a</td><td>aa</td><td>aa</td></tr>
<tr><td>b</td><td>bb</td><td>bb</td></tr>
<tr><td>c</td><td>cc</td><td>cc</td></tr>
</table>
I have been working on a sample Knockout.js application where there is a list of offices and each office is associated with 1 or more sets of opening hours.
When I click on select in the table the opening hours are shown underneath for the first set of opening hours.
I want to be able to cycle through the array by clicking on the button to show the opening hours for Rota A, then B, then C and back to Rota A again.
With my current solution, if I press on the >> button currently the index is incremented but the opening hours table is not updated until I re-press the select button.
The jsfiddle is here https://jsfiddle.net/58p57dv3/
How, do I make the opening hours in the table update automatically when I press the >>> button
HTML
<div id="container">
<div id="officeInfo">
<table>
<thead>
<tr>
<th>Office ID</th>
<th>Office Name</th>
</tr>
</thead>
<tbody data-bind="foreach: offices">
<tr>
<td data-bind="text: OfficeID"></td>
<td data-bind="text: OfficeName"></td>
<td>Select</td>
</tr>
</tbody>
</table>
</div>
<div id="openingHours" data-bind="with: selectedOffice">
<input type="button" value=">>>" data-bind="click: $parent.nextOpeningHourType">
<table>
<thead>
<tr>
<th>Day</th>
<th>Opening Time</th>
<th>Closing Time</th>
</tr>
</thead>
<tbody data-bind="with: OpeningHours()[$parent.index]">
<tr><td>Monday</td><td data-bind="text: MondayStartTime"></td><td data-bind="text: MondayEndTime"></tr>
<tr><td>Tueday</td><td data-bind="text: TuesdayStartTime"></td><td data-bind="text: TuesdayEndTime"></tr>
<tr><td>Wednesday</td><td data-bind="text: WednesdayStartTime"></td><td data-bind="text: WednesdayEndTime"></tr>
<tr><td>Thursday</td><td data-bind="text: ThursdayStartTime"></td><td data-bind="text: ThursdayEndTime"></tr>
<tr><td>Friday</td><td data-bind="text: FridayStartTime"></td><td data-bind="text: FridayEndTime"></tr>
<tr><td>Saturday</td><td data-bind="text: SaturdayStartTime"></td><td data-bind="text: SaturdayEndTime"></tr>
<tr><td>Sunday</td><td data-bind="text: SundayStartTime"></td><td data-bind="text: SundayEndTime"></tr>
</tbody>
</table>
</div>
</div>
JS
var OfficeViewModel = function() {
var self = this;
self.offices = officeList;
self.selectedOffice = ko.observable();
self.index = ko.observable();
self.index = 0;
self.nextOpeningHourType = function() {
if (self.index < 2) {
self.index++;
} else {
self.index = 0;
}
}
self.selectOffice = function (office) {
self.selectedOffice(office);
}
}
I guess it will work fine if you just make index an observable
self.index = ko.observable(0);
self.nextOpeningHourType = function() {
if (self.index() < 2) {
self.index(self.index()+1);
} else {
self.index(0);
}
}
self.selectOffice = function (office) {
self.index(0);
self.selectedOffice(office);
}
and change your markup as
<tbody data-bind="with: OpeningHours()[$parent.index()]">
JsFiddle: https://jsfiddle.net/newuserjs/58p57dv3/2/