HTML
<div data-bind="dxList: { dataSource: dataSource }">
<div data-options="dxTemplate : { name: 'item' } " >
<div class="list-item" data-bind="text: name"></div>
<div data-bind="dxCheckBox: {value: check }"></div>
</div>
</div>
<div data-bind="text: 'Save', click: save"></div>
Javascript
var dataSource = ko.observableArray([]);
dataSource.push({ name: "name1", check: true });
dataSource.push({ name: "name2", check: false });
save: function () {
}
How to get 'name' and 'check' values inside save function,Devextreme mobile?
You just can use the dataSource array.
var save = function () {
var items = dataSource();
console.log(items[0].name + " - " + items[0].check());
console.log(items[1].name + " - " + items[1].check());
};
If you want to get only checked items, you can use the jQuery.grep function to filter data.
var items = $.grep(dataSource(), function(item){
return item.check() === true;
});
Also, I suggest you use the ko.observable() to define the check field of items. It allows you to track changes of the check field.
http://jsfiddle.net/d4t1pqby/3/
Related
I have created a toggle view to select available items in Ionic, and if anyone of the item were selected, I want to uncheck all the other items. I also have a scan function which allows me to dynamically update the items list
I'm fairly new to ionic, so I just have the following code in my settings.html
<ion-toggle ng-repeat="item in itemsList"
ng-model="item.checked">
{{ item.text }}
</ion-toggle>
and then I have created a simple settings.js:
(function () {
'use strict';
angular.module('i18n.setting').controller('Settings', Settings);
SettingController.$inject = ['$scope'];
function Settings($scope){
$scope.settingsList = [
{text: "item1", checked: true},
{text: "item2", checked: false}
];
}
})();
I know ng-model="item.checked" will do the job of changing the attribute $scope.settingsList.checked for me. But what I want to know this how to use it to check one items and uncheck all the other ones?
loop through all the items, set the checked state of all the values to false and then your html code must be:
<ion-toggle ng-repeat="item in settingsList"
ng-model="item.checked"
ng-checked="item.checked" style="border:1px solid #28a54c" ng-change="toggleChange(item)">
{{ item.text }}
</ion-toggle>
Your Controller code
$scope.toggleChange = function(item) {
if (item.checked == true) {
for(var index = 0; index < $scope.settingsList.length; ++index)
$scope.settingsList[index].checked = false;
item.checked = true;
} else {
item.checked = false
}
};
And it's better to use forEach in async environment.
Angular 2+ Version, Ionic 4
HTML
<div class="toogle" *ngFor="let item of toogleConfig">
<div class="toogle__title">{{item.title}}</div>
<ion-toggle [(ngModel)]="item.checked" (ngModelChange)="ToogleChange(item.id)" color="success"></ion-toggle>
</div>
</div>
TS
public toogleConfig = [
{id:0, title:'Recurrent', checked: false},
{id:1, title:'One time', checked: false},
]
public ToogleChange(index:number) {
this.toogleConfig.forEach(toogle => { toogle.checked = false; });
this.toogleConfig[index].checked = true;
}
I would like to use a check list and show the user the boxes she has checked.
I am using this framework: http://vitalets.github.io/angular-xeditable/#checklist . See his example 'Checklist' versus his example 'Select multiple'. However, I do not want to display a link with a comma separated string, i.e., join(', '). I would like each selection to appear beneath the previous, in an ordered list or similar.
Pretty much copied from his examples, here are the guts of my controller:
$scope.userFeeds = {
feeds: {}
};
$scope.feedSource = [
{ id: 1, value: 'All MD' },
{ id: 2, value: 'All DE' },
{ id: 3, value: 'All DC' }
];
$scope.updateFeed = function (feedSource, option) {
$scope.userFeeds.feeds = [];
angular.forEach(option, function (v) {
var feedObj = $filter('filter')($scope.feedSource, { id: v });
$scope.userFeeds.feeds.push(feedObj[0]);
});
return $scope.userFeeds.feeds.length ? '' : 'Not set';
};
And here is my html:
<div ng-show="eventsForm.$visible"><h4>Select one or more feeds</h4>
<span editable-select="feedSource"
e-multiple
e-ng-options="feed.id as feed.value for feed in feedSource"
onbeforesave="updateFeed(feedSource, $data)">
</span>
</div>
<div ng-show="!eventsForm.$visible"><h4>Selected Source Feed(s)</h4>
<ul>
<li ng-repeat="feed in userFeeds.feeds">
{{ feed.value || 'empty' }}
</li>
<div ng-hide="userFeeds.feeds.length">No items found</div>
</ul>
</div>
My problem is - display works with editable-select and e-multiple, but not with editable-checklist. Swap it out and nothing is returned.
To workaround, I have tried dynamic html as in here With ng-bind-html-unsafe removed, how do I inject HTML? but I have considerable difficulties getting the page to react to a changed scope.
My goal is to allow a user to select from a checklist and then to display the checked items.
Try this fiddle: http://jsfiddle.net/mr0rotnv/15/
Your onbeforesave will need to return false, instead of empty string, to stop conflict with the model update from xEditable. (Example has onbeforesave and model binding working on the same variable)
return $scope.userFeeds.feeds.length ? false : 'Not set';
If you require to start in edit mode add the attribute shown="true" to the surrounding form element.
Code for completeness:
Controller:
$scope.userFeeds = {
feeds: []
};
$scope.feedSource = [
{ id: 1, value: 'All MD' },
{ id: 2, value: 'All DE' },
{ id: 3, value: 'All DC' }
];
$scope.updateFeed = function (feedSource, option) {
$scope.userFeeds.feeds = [];
angular.forEach(option, function (v) {
var feedObj = $filter('filter')($scope.feedSource, { id: v });
if (feedObj.length) { // stop nulls being added.
$scope.userFeeds.feeds.push(feedObj[0]);
}
});
return $scope.userFeeds.feeds.length ? false : 'Not set';
};
Html:
<div ng-show="editableForm.$visible">
<h4>Select one or more feeds</h4>
<span editable-checklist="feedSource"
e-ng-options="feed.id as feed.value for feed in feedSource"
onbeforesave="updateFeed(feedSource, $data)">
</span>
</div>
<div ng-show="!editableForm.$visible">
<h4>Selected Source Feed(s)</h4>
<ul>
<li ng-repeat="feed in userFeeds.feeds">{{ feed.value || 'empty' }}</li>
<div ng-hide="userFeeds.feeds.length">No items found</div>
</ul>
</div>
Css:
(Used to give the "edit view" a list appearance)
.editable-input label {display:block;}
Also there is the option of using a filter if you do not need to do any validation or start in edit mode.
Controller:
$scope.user = { status: [2, 3] };
$scope.statuses = [
{ value: 1, text: 'status1' },
{ value: 2, text: 'status2' },
{ value: 3, text: 'status3' }
];
$scope.filterStatus = function (obj) {
return $scope.user.status.indexOf(obj.value) > -1;
};
HTML:
<a href="#" editable-checklist="user.status" e-ng-options="s.value as s.text for s in statuses">
<ol>
<li ng-repeat="s in statuses | filter: filterStatus">{{ s.text }}</li>
</ol>
</a>
I have a select2 drop down with the following markup:
<select id="selectByName" ui-select2="select2Options" ng-model="selectId" data-placeholder="Select item by name" style="width:250px">
<option></option>
<option ng-repeat='item in items' data-show="{{item.show}}" value="{{item.id}}">
{{item.name}}
</option>
</select>
And the js contains the following:
$scope.items (an array that has a id, a boolean show property and a name property)
and the select 2 options:
select2Options : {
allowClear: true,
placeholder:"select a value",
formatResult: function(state) {
var $elem = angular.element(state.element),
isVisible = $elem.data('show');
return isVisible ? '<span style="color:red">'+state.text+'</span>':
<span style="color:blue">'+state.text+'</span>';
}
},
Well, the ng-repeat updates correctly the html markup and sets data-show attribute to either true or false, but the formatResult function does not update this value.
In the html source the data-show="true" and in the formatResult function $elem.data('show') = false;, why doesn't it update while the function is called every time the select2 is opened?
Here is made a plunker that illustrates my question: plnkr.co/edit/d0LxuhzdQh7hMdzOoxpr?p=preview .It looks the formatResult updates the results correctly only once before opening the select2 for the first time.
Edit
http://plnkr.co/edit/6Vma1WTQWQw0HAIQUVxE?p=preview
$scope.select2options = {
allowClear: true,
placeholder: "select a value",
formatResult: function(state, container) {
var $elem = angular.element(state.element);
var scope = $elem.data('$scope');
if (scope !== undefined) {
isVisible = scope.$eval($elem.data('show'));
$scope.dataShow[$elem.attr('value')] = isVisible;
$scope.updated++;
return isVisible ? '<span style="color:red">' + state.text + '</span>' :
' <span style="color:blue">' + state.text + '</span>'
}
}
}
The key part is grabbing the $scope data from the jqLite element and then calling $eval, which evaluates an unparsed string expression in the context of the scope. If we had used $scope.$eval, it would have used the controller $scope, which wouldn't have the ng-repeat on it. By grabbing it from the element we have a scope that has access to the item property for the ng-repeat.
Having said that I don't recommend using this code (sometimes jQuery widgets force you into unpleasant corners when working with angular). Again if you find yourself manipulating angular.element or using $element in a controller you probably should use a directive instead. Then again we programmers have to deal with non-ideal constraints (time, money, etc.) that prevent us from working "ideally" so given your context this may be a decent solution.
Let me know if any of my explanation doesn't make sense.
Original
http://plnkr.co/edit/vYTdxPwgwqZSgK5m9yk9?p=preview
Is this what you want?
JavaScript
$scope.items = [{
id: 1,
show: false,
name: 'test1'
}, {
id: 2,
show: true,
name: 'test2'
}, {
id: 3,
show: true,
name: 'test3'
}];
$scope.selections = [1, 2];
$scope.getStyleForIndex = function (index) {
var item;
for (var i = 0; i < $scope.items.length; i++) {
if (i === index) {
item = $scope.items[i];
break;
}
}
return item.show ? { color: "red" } : { color: "blue" };
}
$scope.select2options = {
allowClear: true,
formatResult: function(item, container) {
var color = $scope.getStyleForIndex(parseInt(item.id, 10)).color;
container.html('<span style="color:' + color + '">RESULT ' + item.text + '</span>');
},
formatSelection: function(item, container) {
container.append($compile('<span ng-style="getStyleForIndex(' + item.id + ')">SELECTION ' + item.text + '</span>')($scope));
}
}
HTML
<div ng-repeat="item in items">
{{ item.name }}
<input type="checkbox" ng-model="item.show" />
</div>
<select ui-select2="select2options" ng-model="selections" style="width:200px" multiple="true" ng-options="i.id as i.name for i in items"></select>
{{selections}}
Not sure what wrong I am doing, but I have followed the apparoch explained. I think, I am also getting the objects added into store object. but the same is not getting reflected on UI. the drop down is still blank. can sombody please help.
My Select box code:
<div class="ecmSearchFormInputArea">
<table class="ecmSearchFormInputArea">
<tr>
<td class="propertyRowLabel">
<label><span class="mandatory_red"></span>Cost Center :</label>
<select data-dojo-attach-point="costCenter" id="costCenter"
data-dojo-type="dijit/form/FilteringSelect" style="width: 18em;"
data-dojo-attach-event="onChange:loadDocStacks">
</select>
</td>
</tr>
</table>
</div>
My JS
postCreate: function() {
this.logEntry("postCreate");
//Trying to populate Combobox
var storeData = {
identifier: 'costCenter',
items: []
}
var jsonObj = [{
costCenter: 'sc1'
},
{
costCenter: 'sc2'
}]
dojo.addOnLoad(function () {
var costCenterStore = new dojo.data.ItemFileWriteStore({ data: storeData });
for (var i = 0; i < jsonObj.length; i++) {
alert ("value of i = " + jsonObj[i].costCenter);
costCenterStore.newItem(jsonObj[i]);
}
var serviceFilterSelect = dijit.byId('costCenter');
alert ("serviceFilterSelect " + serviceFilterSelect);
alert ("costCenterStore " + costCenterStore);
serviceFilterSelect.attr('store', costCenterStore);
});
//Trying to populate Combobox
this.logExit("postCreate");
},
Alerts in the FOR loop shows correct data. Am I missing anything?
add label attribute along with the identifier. Because that is what will be used as label to populate.
var jsonObj = [{
costCenter: 'sc1', name: 'label1'
},
{
costCenter: 'sc2', name: 'label2'
}];
var storeData = {
identifier: 'costCenter', label: 'name',
items: []
};
I have a AngularJS directive that allows users to select a values from a list to filter on. Pretty simple concept which is represented here:
Problem is when I click one of the checkboxes they all select unintended. My directive is pretty simple so I'm not sure why this is happening. The code around the selection and checkboxes is as follows:
$scope.tempFilter = {
id: ObjectId(),
fieldId: $scope.available[0].id,
filterType: 'contains'
};
$scope.toggleCheck = function (id) {
var values = $scope.tempFilter.value;
if (!values || !values.length) {
values = $scope.tempFilter.value = [];
}
var idx = values.indexOf(id);
if (idx === -1) {
values.push(id);
} else {
values.splice(idx, 1);
}
};
$scope.valuesListValues = function (id) {
return $scope.available.find(function (f) {
return f.id === id;
}).values;
};
and the data resembles:
$scope.available = [{
id: 23,
name: 'Store'
values: [
{ id: 124, name: "Kansas" },
{ id: 122, name: "Florida" }, ... ]
}, ... ]
the view logic is as follows:
<ul class="list-box">
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
<div class="checkbox">
<label ng-click="toggleCheck(val.id)">
<input ng-checked="tempFilter.value.indexOf(val.id) === -1"
type="checkbox"> {{val.name}}
</label>
</div>
</li>
</ul>
First off, it toggleCheck fires twice but populates the correct data ( second time given my code it removes it though ).
After the second fire, it checks all boxes... Any ideas?
Perhaps its that the local variable doesn't get reassigned to the property of the scope property used in the view. Since your values are then non-existent and not found, the box is checked.
$scope.tempFilter.value = values
I took the interface concept you were after and created a simpler solution. It uses a checked property, found in each item of available[0].values, as the checkbox model. At the top of the list is a button that clears the selected items.
JavaScript:
function DataMock($scope) {
$scope.available = [{
id: 23,
name: 'Store',
values: [{
id: 124,
name: "Kansas"
}, {
id: 122,
name: "Florida"
}]
}];
$scope.clearSelection = function() {
var values = $scope.available[0].values;
for (var i = 0; i < values.length; i++) {
values[i].checked = false;
}
};
}
HTML:
<body ng-controller="DataMock">
<ul class="list-box">
<li>
<button ng-click="clearSelection()">Clear Selection</button>
</li>
<li ng-repeat="val in available[0].values">
<div class="checkbox">
<label>
<input ng-model="val.checked"
type="checkbox" /> {{val.name}}
</label>
</div>
</li>
</ul>
</body>
Demo on Plunker
The repeat that I used to grab the values based on the id, was the problem area.
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
removing that and simple listening and setting a static variable resolved the problem.
$scope.$watch('tempFilter.fieldId', function () {
var fId = $scope.tempFilter.fieldId;
if ($scope.isFieldType(fId, 'valuesList')) {
$scope.valuesListValues = $scope.valuesListValues(fId);
}
}, true);
});
and then in the view:
ng-repeat="value in valuesListValues"