Right now I am using ng-grid and the grid option, showFilter: true
This places a triangle drop down in the top right corner of the grid, which when clicked pops up a search bar.
Is there a way with ng-grid to have the search bar directly visible in the grid without the need to click the triangle?
Sure, just make a input text wherever you want in your view with your ng-grid:
<input type="text" data-ng-model="outside_search_text" placeholder="Search"
class="form-control" data-ng-change="search()">
<div class="gridStyle" data-ng-grid="gridOptions">
</div>
and then in your controller:
$scope.sortOptions = {
fields : ['id'],
directions : ['DESC']
};
$scope.totalServerItems = 0;
$scope.gridOptions['sortInfo'] = $scope.sortOptions;
$scope.gridOptions['columnDefs'] = [
{field : 'name', displayName: 'Name'}
];
$scope.refresh = function() {
var p = {
searchText : {name: $scope.outside_search_text},
pageNumber : $scope.pagingOptions.currentPage,
pageSize : $scope.pagingOptions.pageSize,
sortField : $scope.sortOptions.fields,
sortDirection : $scope.sortOptions.directions
};
YourServices.getAll(p).then(function(response) {
var content = getResponseData(response);
$scope.totalServerItems = content.count;
$scope.myData = content.result_set;
if (content['result_set'].length > 0) {
//whatever
} else {
//whatever
}
});
};
Related
I'll try to simplify the problem as much as I can.
Let's say I have 2 scopes
$scope.section1 = [
{label: 'label1'},
{label: 'label2'}
];
$scope.section2 = [
{value: 'one'},
{value: 'two}
];
Those scopes are used to generate buttons with ng-repeat
<button ng-repeat="item in section1 type="button">{{item.label}}</button>
and
<button ng-repeat="item in section2 type="button">{{item.value}}</button>
Now what I would like to do it to create a third scope that would attach values to the combinations of objects from the two previous ones, say:
$scope.combo = [
{ section1.label:label1 + section2.value: one = 'result1' },
{ section1.label:label2 + section2.value: one = 'result2' },
{ section1.label:label1 + section2.value: two = 'result3' },
{ section1.label:label2 + section2.value: two = 'result4' }
];
Now here comes the tricky part. What I would need to do, is to add a function that would take the values of clicked ng-repeat buttons from each section and then display the results based on the third scope in an input field or something.
So, if you click the button with label:label1 and the one with value:two the input field would show result3.
I'm very green when it comes to Angular and I have no idea how to approach it, especially that all values are strings.
If I understand correctly you could setup your combo something like ...
$scope.combo = {
"label1": {
"one": "result1",
"two": "result2"
},
"label2": {
"one": "result3",
"two": "result4"
}
}
You can then reference the correct value as combo[valueFromButton1][valueFromButton2] where valueFromButton1 and valueFromButton2 point at a model that contains the result of the clicked buttons. Your controller function then just needs to tie everything together by updating the model when the buttons are clicked.
See this plunkr ... https://embed.plnkr.co/GgorcM/
Without changing much you can also try like below provided code snippet.Run it to check the demo.
var app = angular.module('app', []);
app.controller('Ctrl',['$scope' ,function($scope) {
var key1, key2;
$scope.click = function(type, item) {
if (type == 'label') {
key1 = item;
} else if (type == 'val') {
key2 = item;
}
$scope.key = key1 + '+' + key2;
angular.forEach($scope.combo, function(val, key) {
if(val[$scope.key]){
$scope.finalVal = val[$scope.key];
}
});
};
$scope.section1 = [{
label: 'label1'
}, {
label: 'label2'
}];
$scope.section2 = [{
value: 'one'
}, {
value: 'two'
}];
$scope.combo = [{
'label1+one': 'result1'
}, {
'label2+one': 'result2'
}, {
'label1+two': 'result3'
}, {
'label2+two': 'result4'
}];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='Ctrl'>
<button ng-repeat="item in section1" ng-click="click('label',item.label)" type="button">{{item.label}}</button>
<button ng-repeat="item in section2" ng-click="click('val',item.value)"type="button">{{item.value}}</button>
<input type="text" ng-model="finalVal"/>{{key}} {{finalVal}}
</div>
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/
So I have been struggling with this for like 2 days and still no clue on what to do...
First of all I'm very new to angular and javascript in general so everything I wrote can (and may) be extremely wrong.
sample data:
{
'title' : 'awesome title',
'date' : '19-05-2015',
'place' : 'nice place',
'person' : 'Juliet Peterson',
'status' : 'OK'
}
What I need is, in an existing ui-grid, add a column containing either
if myData.person contains only one persone, this person
if myData.person is empty the text 'No person'
if myData.person contains multiple persons the text 'Choose from' wich on click will popup a list for selection.
My problem is that I am curently unable to get that working. the 2 first cases work fine but i'm struggling for the last one.
We are using bootstrap so my heart goes for either a dropdown list or a popover button
here is my current code:
html:
<div id="grid_post_id" ui-grid="gridPostOpts" ui-grid-edit class="grid"></div>
js:
$scope.choosePerson = function(a) {
if (a.length == 0) {
return 'No person';
} else {
var split = a.split(',');
if (split.length > 1) {
var res = '<button type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="right" data-content="';
for (var i = 0; i < split.length; i++) {
res = res + split[i];
}
res = res + '">Choose from</button>'
return res;
} else {
return a;
}
}
}
$scope.gridPosteOpts = {
columnDefs : [
{
name : 'Title',
field : 'title',
enableCellEdit : false
},
[...]
{
name : 'Person',
cellTemplate : '<div class="ui-grid-cell-contents">{{grid.appScope.choosePerson(row.entity.person)}}</div>',
enableCellEdit : false
}
this code is almost working as i got the rigth data in my cell but it is displayed instead of being interpreted as html (ie my cell contains the string '<button type="bu...')
Use
cellTemplate : `
<div class="ui-grid-cell-contents">
<button type="button" class="btn btn-default" data-container="body"
data-toggle="popover" data-placement="right"
data-content="{{grid.appScope.choosePerson(row.entity.person)}}">
Choose from
</button>
</div>`
and have choosePerson() just return the data.
You can't inject elements into the DOM using angulars {{}}. It will always be text-only
Finnaly managed to do it by myself using a mix of differents approaches found on SO!
I used #j2L4e template for the case "button needed" and just the text for the othercases; i choose between the two with an ng-if
here is the "final" code:
$scope.containsComma = function(a) {return a.contains(',')};
$scope.choosePersonBis = function(a) {
if (a.length == 0) {
return 'No person';
} else {
var split = a.split(',');
if (split.length > 1) {
var res = '';
for (var i = 0; i < split.length; i++) {
res = res + split[i];
}
return res;
} else {
return a;
}
}
;
$scope.gridPosteOpts = {
columnDefs : [
{
name : 'Title',
field : 'title',
enableCellEdit : false
},
[...]
{
title : 'Person',
cellTemplate : `
<div ng-if="grid.appScope.containsComma(row.entity.person)"
class="ui-grid-cell-contents">
<button type="button" class="btn btn-default"
popover="{{grid.appScope.choosePersonBis(row.entity.person)}}"
popover-placement="right"
popover-trigger="focus">
Choose person
</button>
</div>
<div ng-if="grid.appScope.notContainsComma(row.entity.person)"
class="ui-grid-cell-contents">
{{grid.appScope.choosePersonBis(row.entity.person)}}
</div>`
}
};
try replace this code
<div class="ui-grid-cell-contents">{{grid.appScope.choosePerson(row.entity.person)}}</div>
with
<div class="ui-grid-cell-contents" ng-bind-html="grid.appScope.choosePerson(row.entity.person)"></div>
In this plunk I have an empty grid (without columns). When I click on "Build Grid" I need to add columns (taken from an array) and also add a row to the table.
The problem is that the columns are not added to the grid, any ideas? If I try to refresh the grid, I get an undefined error.
HTML:
<button ng-click="buildGrid()">Build Grid</button>
<div kendo-grid="grid" k-options="gridOptions" k-data-source="ds"></div>
Javascript:
var app = angular.module("app", [ "kendo.directives" ]);
function MyCtrl($scope) {
$scope.ds = []
$scope.colsList = [{ name: "col1" },
{ name: "col2" },
{ name: "col3" },
{ name: "col4" }];
var gridCols = [];
$scope.gridOptions = {
columns: gridCols
};
$scope.buildGrid = function() {
$scope.data = {};
for (var x=0;x<$scope.colsList.length;x++) {
var col = {};
col.field = $scope.colsList[x].name;
col.title = $scope.colsList[x].name;
$scope.data[col.field] = "" + (1111 * (x+1));
gridCols.push(col);
}
// add one row to the table
$scope.ds.push($scope.data);
//$scope.grid.refresh();
};
}
You need to use k-rebind so that the grid reinitializes (you can't set the columns dynamically on an existing grid):
<div kendo-grid="grid"
k-options="gridOptions"
k-data-source="ds"
k-rebind="gridOptions"></div>
(demo)
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}}