I have created table like below:
<table data-bind="with: choosenDateGoal">
<tbody data-bind="foreach: tblGoals">
<!-- ko if: status -->
<tr class="success">
<td>
<input type="checkbox" onclick="this.disabled = 'disabled';" data-bind="checked: status, disable: status, click: $root.UpdateStatus" />
</td>
<td>
<span style="width: 80%" data-bind="text: goals" />
</td>
<td>
<input type="text" style="width: 80%" data-bind="value: notes , event: { blur: $root.UpdateNote}" />
</td>
</tr>
<!-- /ko -->
</tbody>
</table>
I have an checkbox in every row and when i click on it it should change the row color.
But not working. here is my script for changing color:
self.UpdateColor = function ChangeBackgroundColor() {
debugger;
if ($("input[type='checkbox']:checked")) {
$(this).parent().addClass('success'); ;
}
};
Use knockout's css binding - see http://knockoutjs.com/documentation/css-binding.html
Try binding below and you don't call the ChangeBackgroundColor function
<tr data-bind="css: {success: status()}">
Zaik's answer will work, but if you do it the knockout way, you don't need to add any JavaScript eventing code. This is one of the real benefit's of knockout.
Related
I am trying to move checked checkboxes from one checklist, which is actually in a table, to another checklist in another table so the two are in sync. However, this code gives me the syntax error "Unexpected end of input" in Chrome and won't work:
var checkedBoxes = document.querySelectorAll('.contentChecks');
var chkArray = [];
chkArray = $.map(checkedBoxes, function(el) {
if(el.checked) { return el.id.substring(1, el.id.length) }
});
for (var i = 0; i < chkArray.length; i++)
{
var checkbox = document.getElementById("B" + chkArray[i]);
checkbox.checked = true;
var row = $("#B" + chkArray[i]).closest('tr'); // row with changed checkbox
row.insertBefore(row.parent().find('tr:first-child')); // move to top
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table1">
<thead>
<tr>
<th>Checkboxes</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" id="A127" class="contentChecks" checked />
<label for="A127" class="todo">
<i class="fa fa-check"></i>Sample Text 1
</label>
</td>
</tr>
<tr>
<td>
<input type="checkbox" id="A32" class="contentChecks" checked />
<label for="A32" class="todo">
<i class="fa fa-check"></i>Sample Text 2
</label>
</td>
</tr>
<tr>
<td>
<input type="checkbox" id="A1543" class="contentChecks" checked />
<label for="A1543" class="todo">
<i class="fa fa-check"></i>Sample Text 3
</label>
</td>
</tr>
</tbody>
</table>
<table id="table2">
<thead>
<tr>
<th>Checkboxes</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" id="B127" class="contentChecks2" />
<label for="B127" class="todo">
<i class="fa fa-check"></i>Sample Text 1
</label>
</td>
</tr>
<tr>
<td>
<input type="checkbox" id="B32" class="contentChecks2" />
<label for="B32" class="todo">
<i class="fa fa-check"></i>Sample Text 2
</label>
</td>
</tr>
<tr>
<td>
<input type="checkbox" id="B1543" class="contentChecks2" />
<label for="B1543" class="todo">
<i class="fa fa-check"></i>Sample Text 3
</label>
</td>
</tr>
</tbody>
</table>
I've tried debugging this a million ways to no avail, except I have concluded that something must be wrong with my for loop since commenting out the other code still gave the error. I've put this code in JavaScript validators and they all conclude the syntax is valid and the "end of the input" is just fine. Also it works just fine in my code snippet.
IMPORTANT: I am pulling this JavaScript code from an external file, so it is HTML along with this JS being returned from an AJAX call to the webpage the user is seeing, replacing the previous HTML.
I found the solution - it was a scope issue. Trying to pull HTML and JavaScript from an external file didn't work on the AJAX call, so I just put the same code under the complete section of the AJAX call of the same file/page and it worked :)
Using Knockout JS here.
I have a HTML table and the table has 4 columns. I have button to add a row to table and then remove button against each row to delete it. I also have a dropdown in the first column of this table. The dropdown is populated from the button click event outside the table. Below is my html:
<table class="table table-bordered">
<thead class="mbhead">
<tr class="mbrow">
<th>Input</th>
<th>First Name</th>
<th>Last Name</th>
<th>Address</th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td>
<select class="form-control" data-bind="options: $parent.ddl, optionsText: 'name', value: $parent.selectedColumnValue, optionsCaption: '--Select--', event: { change: $parent.ddlChanged }">
</select>
</td>
<td><span class="input-small" data-bind="value: firstName" /></td>
<td><span class="input-small" data-bind="value: lastName" /></td>
<td><span class="input-small" data-bind="value: address" /></td>
<td>
<input type="button" value="Remove Row" data-bind="click: $parent.removeRow" class="btn btn-danger" />
</td>
</tr>
</tbody>
</table>
<div class="col-xs-12 col-sm-6">
<input type="button" value="Add Row" class="btn btn-primary" data-bind="click: addRow" />
<input type="submit" value="Get Data" data-bind="click: GetData" class="btn btn-primary" />
</div>
My knockout code can be seen in the jsfiddle link as below.
What I am looking for is:
When the user selects the dropdown the selected dropdown text gets populated to that rows one column and the value gets populated to that rows other columns/cell.
My Issue:
1.) I am not able to get the selected text and selected value from the dropdown
When the dropdown selected index change event is fired the event param has the below value as seen in console:
firstName : ƒ c()
lastName: ƒ c()
address : ƒ c()
proto : Object
2.) Secondly I don't know how I could update other column values based on the dropdown selection.
The json that gets binded to dropdown is like below:
'[{"FirstName":"Alex","LastName":"Sanders","Address":123},{"FirstName":"Sam","LastName":"Billings","Address":"Mahony Street"}]';
Here is my fiddle:
https://jsfiddle.net/aman1981/njbyumrs/12/
Inputs are appreciated.
You've got some parent and level stuff mixed up, and your table was binding on value instead of text. I moved the drop down binding, selectedValue to Item since it's at the row level and not the parent level. I used the KO with binding to show the values inside selectedValue for that part of the HTML.
I also added a <pre> tag with the KO values so you can see what happens as you interact with it and the KO model data changes.
Side note: The three properties in Item don't need to be observable in this demo as the values do not change while on the screen.
var ViewModel = function() {
var self = this;
//Empty Row
self.items = ko.observableArray([new Item()]);
self.ddl = ko.observableArray();
self.addRow = function() {
self.items.push(new Item());
};
self.removeRow = function(data) {
self.items.remove(data);
};
self.GetData = function() {
if (self.ddl().length === 0) {
var item1 = new Item("Alex", "Sanders", "Maple Street");
self.ddl.push(item1);
var item2 = new Item("Sam", "Billings", "Mahony Street");
self.ddl.push(item2);
}
}
}
var Item = function(fname, lname, address) {
var self = this;
self.firstName = ko.observable(fname);
self.lastName = ko.observable(lname);
self.address = ko.observable(address);
self.selectedValue = ko.observable();
};
vm = new ViewModel()
vm.GetData();
ko.applyBindings(vm);
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table class="table table-bordered">
<thead class="mbhead">
<tr class="mbrow">
<th>Input</th>
<th>First Name</th>
<th>Last Name</th>
<th>Address</th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td><select class="form-control" data-bind="options: $parent.ddl, optionsText: 'firstName', value: selectedValue, optionsCaption: '--Select--'"> </select></td>
<td data-bind="with: selectedValue">
<span data-bind="text: firstName"></span>
</td>
<td data-bind="with: selectedValue">
<span data-bind="text: lastName"></span>
</td>
<td data-bind="with: selectedValue">
<span data-bind="text: address"></span>
</td>
<td>
<input type="button" value="Remove Row" data-bind="click: $parent.removeRow" class="btn btn-danger" />
</td>
</tr>
</tbody>
</table>
<div class="col-xs-12 col-sm-6">
<input type="button" value="Add Row" class="btn btn-primary" data-bind="click: addRow" />
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
I have this table:
my problem is that I want to if I check the checkbox of selected row it will enabled/desabled the "Montant" input,this is my try but it never works
I get all the rows activated!!
<table>
<thead>
<tr>
<th >
<input type="checkbox" />
</th>
<th>Montant</th>
</tr>
</thead>
<tbody ng-model="finalOperationsList">
<tr ng-repeat="item in finalOperationsList track by $index ">
<td class="TableHeaderalignment"><input type="checkbox"
ng-model="finalOperationsList[$index].checked" ng-change="changeMontantLBL($index)"/></td>
<td class="TableHeaderalignment">
<input type="text" class="form-control" value="{{item.montant}}" ng-disabled="montantBL" />
</td>
</tr>
</tbody>
</table>
and this is function in Controller:
$scope.changeMontantLBL =function($index){
if(true){
$scope.montantBL = false;
}
else{
$scope.montantBL = true;
}
}
so please how can I correct my code to make the input "Montant" enabled/desabled depending on the choice of selected row checkbox
thanks for help
You can directly consume the value of "finalOperationsList[$index].checked" in the ng-disabled of the input textbox, and remove the ng-change and scope.montantBL altogether.
<tr ng-repeat="item in finalOperationsList track by $index ">
<td class="TableHeaderalignment"><input type="checkbox"
ng-model="finalOperationsList[$index].checked"/></td>
<td class="TableHeaderalignment">
<input type="text" class="form-control" value="{{item.montant}}" ng-disabled="finalOperationsList[$index].checked" />
</td>
</tr>
It is also worth to note that you might have misused value="{{item.montant}}" and should use ng-model="item.montant" instead. You can also simplify your code for that row to:
<tr ng-repeat="item in finalOperationsList track by $index ">
<td class="TableHeaderalignment">
<input type="checkbox" ng-model="item.checked"/></td>
<td class="TableHeaderalignment">
<input type="text" class="form-control" ng-model="item.montant" ng-disabled="item.checked"/>
</td>
</tr>
You could just use the bound ng-model (answers[item.questID]) value itself in your ng-change method to detect if it has been checked or not.
Example:-
<input type="checkbox" ng-model="answers[item.questID]" ng-change="stateChanged(item.questID)" /> <!-- Pass the specific id -->
and
$scope.stateChanged = function (qId) {
if($scope.answers[qId]){ //If it is checked
alert('enable or disable input');
}
}
Sort of an odd question, but I'm having some trouble coming up with a good selector to do this. The jsfiddle is here: http://jsfiddle.net/NZf6r/1/
In short, I have a parent table which has a "select all" checkbox as a column in the thead. Every table row also has a checkbox. The intention is if they click the checkbox, I select (or deselect) all of the row checkboxes in the tbody. Simple, right?
However, there a rows in the table that function as child tables for each row. These child tables also have checkboxes and also have a need for the same "select all" scheme.
The tricky part is not getting the "select all" in the parent table to also select the children. My current event function looks like this (also on the jsfiddle):
$('th input').on('click', function(event) {
var isChecked = $(event.target).is(':checked');
$(event.target)
.parents('table')
.first()
.find('input[type="checkbox"]')
.each(function(i, checkbox) {
$(checkbox).prop('checked', isChecked);
});
});
I know I can use direct child selectors (>), but I'm not quite sure of the best way to incorporate that.
I also know I could add a class to the checkboxes for each table type (parent vs. child) and add that to the input selector, but I'm curious if there's a way I can avoid doing that. Some jQuery magic, if you will.
Here is the rough HTML of things (not the full table, obviously) in case you can't access the jsfiddle:
<table>
<thead>
<tr>
<th style="width:20px">
<div>
<input type="checkbox" />
</div>
</th>
<th>Bar</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<input type="checkbox" />
</div>
</td>
<td>Aaaaa</td>
</tr>
<tr>
<td colspan="2">
<div style="padding-left: 20px">
<table>
<thead>
<tr>
<th>
<div>
<input type="checkbox" />
</div>
</th>
<th>Bar</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<input type="checkbox" />
</div>
</td>
<td>Aaaaa</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
<tr>
<td>
<div>
<input type="checkbox" />
</div>
</td>
<td>Bbbbb</td>
</tr>
<tr>
<td colspan="2">
<div style="padding-left: 20px">
<table>
<thead>
<tr>
<th>
<div>
<input type="checkbox" />
</div>
</th>
<th>Bar</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<input type="checkbox" />
</div>
</td>
<td>Bbbbb</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
Use this script instead:
$('th input').on('click', function(event){
var parenttable = $(this).parents('table:first');
var isChecked = $(event.target).is(':checked');
parenttable.find(">tbody>tr>td>div>input").prop('checked', isChecked);
});
try this demo
$('th input').on('click', function (event) {
var isChecked = $(event.target).is(':checked');
$(event.target)
.closest("table")
.find('> tbody > tr:not(:has(table)) > td input[type="checkbox"]')
.each(function () {
$(this).prop('checked', isChecked);
});
});
I'm trying to make a "dynamic table" with knockout js and I'm having a bit of difficulty. I want to have a "Common Row Template" with a nested template for the variable columns. Something like this:
<script type="text/x-jquery-tmpl" id="CommonRow">
<td><input type="text" data-bind="value: Nome" /></td>
<td data-bind="template: { name: $item.LabelOne + 'Row' }"></td>
<td><button class="fancybox edit" data-bind="click: Edit">Modifica</button></td>
<td><button class="remove" data-bind="click: Remove">Rimuovi</button></td>
</script>
So the second <td> will render a template, which will look like this:
<script type="text/x-jquery-tmpl" id="ScalaRow">
<td><input type="text" data-bind="value: PianiFuoriTerra" /></td>
<td><input type="text" data-bind="value: Foo" /></td>
</script>
This "works" but it has a big problem: the desired <td> are nested in the outer <td> with the template binding, causing improper alignment with the header (which also is structured the same way).
I tried using the {{tmpl}} syntax to avoid the wrapping <td> and this gets me the right html, but all the databinding and observable don't work anymore in the dynamic part.
Is there a way to render a block of <td> preserving the knockout observable functionality and avoiding any wrapping tag? Thanks.
Your best option is to look at using KO 1.3 beta. Here is a sample of doing something like what you want: http://jsfiddle.net/rniemeyer/wmDfv/
<table data-bind="foreach: items">
<tr>
<td data-bind="text: name"></td>
<!-- ko template: type -->
<!-- /ko -->
</tr>
</table>
<script id="typeA" type="text/html">
<td>typeA template</td>
</script>
<script id="typeB" type="text/html">
<td>typeB template</td>
</script>