Select an item in a list on click with knockout - javascript

I'm trying to chenge the css class of a li tag when I click on it.
I have this:
Model:
var businessUnitsModel = {
businessUnitsList: ko.observableArray([
{ siteID: "a", title: "business1" },
{ siteID: "b", title: "business2" },
{ siteID: "c", title: "business3" },
{ siteID: "d", title: "business4" }]),
currentSelected: ko.observable(),
selectItem: function (site) { this.currentSelected(site.siteID); }
}
//overall viewModel
var viewModel = {
businessUnits: businessUnitsModel,
};
HTML
<ul class="modal-list" data-bind="'foreach': businessUnits.businessUnitsList">
<li class="filterItem" data-bind="'text': title,
css: { 'filterItemSelect': siteID === $parent.currentSelected },
'click': $parent.selectItem">
</li>
</ul>
CSS
.filterItemSelect {
color:#0069ab;
}
and I can't understand why it is not working.

This is what you are looking for :
JS:
var businessUnitsModel = {
businessUnitsList: ko.observableArray([{
siteID: "a",
title: "business1"
}, {
siteID: "b",
title: "business2"
}, {
siteID: "c",
title: "business3"
}, {
siteID: "d",
title: "business4"
}]),
currentSelected: ko.observable(),
selectItem: function (that, site) {
that.currentSelected(site.siteID);
}
}
//overall viewModel
var viewModel = {
businessUnits: businessUnitsModel,
};
ko.applyBindings(viewModel);
View :
<div data-bind="with :businessUnits">
<ul class="modal-list" data-bind="'foreach': businessUnitsList">
<li class="filterItem" data-bind="'text': title,
css: { 'filterItemSelect': siteID === $parent.currentSelected() },
'click': function(){$parent.selectItem($parent, $data);}"></li>
</ul>
</div>
See fiddle
I hope it helps.

You should use currentSelected function value (i.e. add parentheses) when applying css:
<ul class="modal-list" data-bind="foreach: businessUnitsList">
<li class="filterItem" data-bind="text: title,
css: { 'filterItemSelect': siteID === $parent.currentSelected() },
click: $parent.selectItem">
</li>
</ul>
And script:
var businessUnitsModel = function() {
var self = this;
self.businessUnitsList = ko.observableArray([
{ siteID: "a", title: "business1" },
{ siteID: "b", title: "business2" },
{ siteID: "c", title: "business3" },
{ siteID: "d", title: "business4" }]);
self.currentSelected = ko.observable();
self.selectItem = function (site) {
self.currentSelected(site.siteID);
}
}
ko.applyBindings(new businessUnitsModel());
Fiddle
UPDATE here is update of your markup and view model. You should provide full path to currentSelected() property:
<ul class="modal-list" data-bind="'foreach': businessUnits.businessUnitsList">
<li class="filterItem" data-bind="'text': title,
css: { 'filterItemSelect':
siteID === $parent.businessUnits.currentSelected() },
'click': $parent.businessUnits.selectItem">
</li>
</ul>
And here is fixed problem with model - inside selectItem function this was equal to item which you clicked. Thus you don't want to use self alias to model, you need to specify its name:
var businessUnitsModel = {
businessUnitsList: ko.observableArray([
{ siteID: "a", title: "business1" },
{ siteID: "b", title: "business2" },
{ siteID: "c", title: "business3" },
{ siteID: "d", title: "business4" }]),
currentSelected: ko.observable(),
selectItem: function (site) {
businessUnitsModel.currentSelected(site.siteID);
}
}
//overall viewModel
var viewModel = {
businessUnits: businessUnitsModel,
};
ko.applyBindings(viewModel);
Fiddle

Related

How do i update observable array in knockout binding handler?

I want to update the observable array in knockout binding handler. But it is not updating. The following code i tried but nothing worked out.
this.DropdownValues = ko.observableArray([
{ id: 0, type: "Arc",Checked:false },
{ id: 1, type: "Eve",Checked:false },
{ id: 2, type: "Ca",Checked:false },
{ id: 3, type: "test",Checked:false },
]);
Code I have written inside binding handler.
var value = valueAccessor();
var valueUnwrapped = ko.unwrap(value);
console.log("true");
valueUnwrapped.map(function(item){
item[Checked]= true; return item;
});
ko.utils.unwrapObservable(value(valueUnwrapped));
But my view still not detecting the values. foreach not refeshing in view.
You were missing quotes around the word Checked. It should be item['Checked'] or item.Checked rather than item[Checked].
ko.bindingHandlers.updateArray = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var valueUnwrapped = ko.unwrap(value);
$("#before").text(JSON.stringify(valueUnwrapped));
console.log("true");
valueUnwrapped.map(function(item){
item['Checked']= true; return item;
});
ko.utils.unwrapObservable(value(valueUnwrapped));
}
}
var viewModel = function(){
var self = this;
self.DropdownValues = ko.observableArray([
{ id: 0, type: "Arc",Checked:false },
{ id: 1, type: "Eve",Checked:false },
{ id: 2, type: "Ca",Checked:false },
{ id: 3, type: "test",Checked:false },
]);
};
ko.applyBindings(new viewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Before:<br>
<span id="before"></span>
<div data-bind="updateArray: DropdownValues">
</div>
<br><br>
After:<br>
<span data-bind="text: ko.toJSON(DropdownValues)"></span>

ASP MVC Net using Check list kendo Grid

How to get data from kendogrid2 and set it to kendogrid1?
I have the 2 kendogrid using checklist grid.
This is the jquery code:
$("#btnAddPortfolio").click(function () {
var grid2 = $("#portfolioGrid2").data("kendoGrid");
var dt = grid2.dataItem
var ds = new kendo.data.DataSource({
data: [{ "Portfolio": "Data of checklist selected item"}]
});
$("#portfolioGrid1").data("kendoGrid").setDataSource(ds);
$('#grid2_modal').modal('toggle');
});
How to get the value of selected item on #portofolioGrid2?
A simple way to achieve it:
$("#grid1").kendoGrid({
dataSource: {
data: [{ Name: "John Doe" }, { Name: "Jane Doe" },
{ Name: "Doe John" }, { Name: "Doe Jane" }]
},
columns: [{
template: '<input type="checkbox" />',
width: 40
}, {
field: "Name"
}]
});
$("#grid2").kendoGrid({
columns: [{
field: "Name"
}]
});
$("#transfer-items").on("click", function() {
let grid1 = $("#grid1").data("kendoGrid"),
grid2 = $("#grid2").data("kendoGrid"),
$checkboxes = grid1.tbody.find('input:checked').toArray();
if ($checkboxes.length) {
$checkboxes.forEach($chk => {
let item = grid1.dataItem($chk.closest("tr"));
grid2.dataSource.add(item);
});
}
else {
window.alert("No item has been selected.");
}
});
Demo

My viewmodel does not reflect my selections

I'm using cascading dowpdowns in a list.
The user interface is working fine, but the underlying viewmodel is not up to date with the user selections.
I have the following html :
<ul data-bind="foreach: selectedExams">
<li>
<select data-bind="options: $parent.availableExams, optionsCaption: 'Choisir un type...', optionsText: 'examTypeName', value: examtype"></select>
<select data-bind="options: exams, optionsCaption: 'Choisir un examen...' , optionsText: 'examName',value: exam, enable:exams().length"></select>
Remove
</li>
</ul>
<button data-bind="click: add">Add</button>
<pre data-bind="text: ko.toJSON($root.selectedExams, null, 2)"></pre>
js file:
function AppViewModel() {
var self = this;
self.availableExams = [
{
examTypeId: "SCAN", examTypeName: "Scanner", exams: [
{ examId: "SCOEUR", examName: "SCOEUR" },
{ examId: "SANGIO", examName: "SANGIO abdominopelvien" },
{ examId: "SSINUS", examName: "SSINUS sans inj" }
]
},
{
examTypeId: "RX", examTypeName: "Radio", exams: [
{ examId: "RBRAS", examName: "RBRAS" },
{ examId: "RAVBRAS", examName: "RAVBRAS" },
{ examId: "RBASSIN", examName: "RBASSIN 1 inc + rx bilat COXO FEMO 1/2 inc" }
]
},
{
examTypeId: "IRM", examTypeName: "IRM", exams: [
{ examId: "ITETE", examTypeId: "IRM", examName: "ITETE angio IRM enceph" },
{ examId: "IRACHIS", examTypeId: "IRM", examName: "IRACHIS 1/2 segt avec INJ" },
{ examId: "ITHORAX", examTypeId: "IRM", examName: "ITHORAX sans inj" }
]
}
];
self.selectedExams = ko.observableArray([new selectedExam()]);
self.add = function () {
self.selectedExams.push(new selectedExam());
};
self.remove = function (exam) { self.selectedExams.remove(exam) }
}
var selectedExam = function () {
self.examtype = ko.observable(undefined);
self.exam = ko.observable(undefined);
self.exams = ko.computed(function () {
if (self.examtype() == undefined || self.examtype().exams == undefined)
return [];
return self.examtype().exams;
});
}
ko.applyBindings(new AppViewModel());
The result, for 3 lines of various selections is the following :
[
{},
{},
{}
]
I'm expecting to see this for instance :
[
{"SCAN","SCOEUR"},
{"RX", "RBRAS"},
{"IRM", "ITETE"}
]
This is probably a data binding issue, but I don't know where to start to debug this kind of problem.
Please note that I'm using this code in a bootstrap grid.
Any Help appreciated.
Thanks in advance.
The problem is that you're missing the definition of self in your selectedExam constructor function. Currently, your self is actually referencing window (the global context) hence you're ending-up with empty objects being returned.
Try this:
var selectedExam = function () {
var self = this; // <-- add this
self.examtype = ko.observable(undefined);
self.exam = ko.observable(undefined);
self.exams = ko.computed(function () {
if (self.examtype() == undefined || self.examtype().exams == undefined)
return [];
return self.examtype().exams;
});
}

selectable table modal popup in angular js

I am trying to open a modal popup with table. How can I do this? In my app.js, on the click event of row open a modal, I also want to update some field with the selected item value. But i can't update with selected value.
my app.js
var tableApp = angular.module('tableApp', ['ui.bootstrap']);
tableApp.controller('tableController', function ($scope,$rootScope, $filter, $modal) {
$scope.filteredPeople = [];
$scope.currentPage = 1;
$scope.pageSize = 10;
$scope.people = [{ id: "1", name: "joe",disable:true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe", disable: true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe", disable: true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe", disable: true },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true },
{ id: "1", name: "joe" },
{ id: "2", name: "bill", disable: true },
{ id: "3", name: "john", disable: true }];
$scope.getPage = function () {
var begin = (($scope.currentPage - 1) * $scope.pageSize);
var end = begin + $scope.pageSize;
$scope.filteredPeople = $filter('filter')($scope.people, {
id: $scope.idFilter,
name: $scope.nameFilter
});
$scope.totalItems = $scope.filteredPeople.length;
$scope.filteredPeople = $scope.filteredPeople.slice(begin, end);
};
$scope.getPage();
$scope.pageChanged = function () {
$scope.getPage();
};
$scope.open = function () {
$scope.id = generateUUID();
};
$scope.dblclick = function (index) {
for (var i = 0; i < $scope.filteredPeople.length; i++) {
$scope.filteredPeople[i].disable = true;
}
return index.disable = false;
}
$scope.rowSelect = function (rowdata) {
alert(rowdata.name);
}
});
tableApp.controller('DetailModalController', [
'$scope', '$modalInstance', 'item',
function ($scope, $modalInstance, item) {
$scope.item = item;
$scope.dismiss = function () {
$modalInstance.dismiss();
};
$scope.close = function () {
$modalInstance.close($scope.item);
};
}]);
tableApp.directive('myModal', function ($log, $compile) {
var parm = [];
return {
restrict: 'E',
templateUrl: 'modalBase.html',
scope: {
modal: '=',
idF:'='
},
link: function (scope, element, attrs) {
debugger;
parm.name = attrs.idf;
}
//controller: function ($scope) {
// debugger;
// console.log($scope);
// $scope.selected = {
// item: $scope.modal.items[0]
// };
// $scope.ok = function () {
// debugger;
// alert(parm.name);
// $scope.modal.instance.close($scope.selected);
// };
// $scope.cancel = function () {
// $scope.modal.instance.dismiss('cancel');
// };
// $scope.modal.instance.result.then(function (selectedItem) {
// $scope.selected = selectedItem;
// }, function () {
// $log.info('Modal dismissed at: ' + new Date());
// });
//}
};
});
As I understand, you use angular.ui. I would suggesst you to use $modal service instead of $modalInstance. Using that you can call your modal instance with $modal.open(). And also you don't need to close it in your controller - place appropriate methods on your modal template and it will work by its services
Template:
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
{{ item }}
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="$close()">OK</button>
<button class="btn btn-warning" type="button" ng-click="$dismiss('cancel')">Cancel</button>
</div>
</script>
Controlelr
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
You can find more info about it in angular.ui documentation for modals

Knockout - Unable to process binding, gridViewModel is not defined

I am new to knockout and I have no idea why I am getting this message.
Unable to process binding "simpleGrid: function (){return gridViewModel }"
Message: gridViewModel is not defined;
library_customization.js
define(['services/logger'], function (logger) {
var title = 'Library Customization';
var vm = {
activate: activate,
title: title
};
return vm;
var initialData = [
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
{ name: "Furious Lizard", sales: 152, price: 25.00 },
{ name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ name: "Brooding Dragon", sales: 0, price: 6350 },
{ name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ name: "Optimistic Snail", sales: 420, price: 1.50 }
];
var PagedGridModel = function (items) {
this.items = ko.observableArray(items);
this.addItem = function () {
this.items.push({ name: "New item", sales: 0, price: 100 });
};
this.sortByName = function () {
this.items.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
};
this.jumpToFirstPage = function () {
this.gridViewModel.currentPageIndex(0);
};
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
],
pageSize: 4
});
};
ko.applyBindings(new PagedGridModel(initialData));
function activate() {
logger.log(title + ' selected', null, title, true);
return true;
}
});
library_customization.html
<!DOCTYPE html>
<html id="libraryCust">
<head>
<title> Project</title>
<script type="text/javascript" src="../../Scripts/knockout-3.3.0.js
</script>
</head>
<body>
<section>
<h2 class="page-title" data-bind="text: title"></h2>
</section>
<div class='liveExample'>
<div data-bind='simpleGrid: gridViewModel'></div>
<!-- -->
<button data-bind='click: addItem'>
Add item
</button>
<button data-bind='click: sortByName'>
Sort by name
</button>
<button data-bind='click: jumpToFirstPage, enable: gridViewModel.currentPageIndex'>
Jump to first page
</button>
</div>
</body>
</html>
Check the fiddle: JS Fiddle
I think the main problem is that you exit your module earlier than planned in the code below:
var title = 'Library Customization';
var vm = {
activate: activate,
title: title
};
return vm;
/* your main code follows below but never executes */
So I moved these properties into the PagedGridModel constructor.

Categories

Resources