Angular JS Smart Table Filtered collection - angularjs

Where is the filtered collection after filtered value in smart table.
the table is bound with rowCollection.
<table st-safe-src="rowCollection" st-table="displayed" class="table table-bordered">
and i have used a search filter:
<input type="text" id="regionFilter" st-search="region" />
after the result are filtered i still see all records in rowCollection

You can create a directive to access the get the filtered Collection. For example:
HTML:
<table
st-table="displayedCollection"
st-safe-src="rowCollection"
on-filter="onFilter">
Javascript:
//
// Create a directive
//
angular.module("smart-table").directive('onFilter', function () {
return {
require: '^stTable',
scope: {
onFilter: '='
},
link: function (scope, element, attr, ctrl) {
scope.$watch(function () {
return ctrl.tableState().search;
}, function (newValue, oldValue) {
scope.onFilter(ctrl);
}, true);
}
};
});
//
// In your controller
//
$scope.onFilter = function (stCtrl) {
var filtered = stCtrl.getFilteredCollection();
}

Related

How to get instances of ckeditor with ng-repeat?

I am trying to use ckeditor with angularjs I have added a directive for the same. It is working fine. The problem is when I try to get the instances list of the ckeditor.
// directive
app.directive('ckeditor', function () {
return {
require: '?ngModel',
link: function (scope, element, attr, ngModel) {
var ck = CKEDITOR.replace(element[0]);
if(!ngModel)return;
ck.on('pasteState', function () {
scope.$apply(function () {
ngModel.$setViewValue(ck.getData());
});
});
ngModel.$render = function (value) {
ck.setData(ngModel.$viewValue);
};
}
};
});
// ng-repeat
<div ng-repeat="key in []| range:0:(vm.listCount-1)">
<textarea ckeditor id="content_{{key + 1}}"
ng-model="vm.contentList[key].content">
</textarea>
</div>
In controller I am trying to get instances list. There instead of
content_0,content_1 etc. I am getting content_{{key + 1}} only one instance
console.log(CKEDITOR.instances);
I want to get the proper instance of the ckeditor but I am getting only one value that is content_{{key + 1}} Please someone suggest.
My guess is that the directive needs to set the id attribute before invoking CKEDITOR.replace:
app.directive('ckeditor', function () {
return {
require: '?ngModel',
link: function (scope, element, attr, ngModel) {
//COMPUTE id attribute
if (attr.key) {
var keyValue = scope.$eval(attr.key);
element[0].id += "_"+keyValue;
};
var ck = CKEDITOR.replace(element[0]);
if(!ngModel)return;
ck.on('pasteState', function () {
scope.$apply(function () {
ngModel.$setViewValue(ck.getData());
});
});
ngModel.$render = function (value) {
ck.setData(ngModel.$viewValue);
};
}
};
});
Usage:
<div ng-repeat="key in [0,1]">
<textarea ckeditor key="$index+1" id="content"
ng-model="vm.contentList[key].content">
</textarea>
</div>
The CKEDITOR is likely instantiating the editor before the AngularJS framework computes id="content_{{key + 1}}".

Having multiple suffix for same directive (angularjs)

Let say we have the following directive:
app.directive('testList', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
//do stuff
}
}
});
I would like to call this directive from multiple element in html
<button test-list-add></button>
<table test-list="listObject">
<tr ng-repeat="list in testList">
<td test-list-click>list.item</td>
</tr>
</table>
is it possible to get into the link function for each attribute starting with test-list (test-list-add, test-list, test-list-click)?
Thank you
You want to pass attributes to your directive and doing some action, depending on the attribute:
app.directive('testList', function () {
return {
restrict: 'A',
scope: {
'add': '#', // Text
'click': '&' // function
},
link: function (scope, element, attrs) {
// scope.add - your Text you passed
// scope.click(); - calls your function you passed
}
}
});
<button test-list add="test"></button>
<table test-list="listObject">
<tr ng-repeat="list in testList">
<td test-list click="myFunc()">list.item</td>
</tr>
</table>
You can't repeat a directive (what you obvis trying to do).
If you want to make multiple suffix for a directive, you have to declare them one by one:
app.directive('testListAdd', function () {...});
app.directive('testListclick', function () {...});
<test-list-add></test-list-add>
<test-listclick></test-listclick>

possible for directive to run each time when scope changes?

I want to write a directive to for a table TBODY to show some text when it is empty. I want to achieve this by writing a directive that detects if the table's TBODY has any child TR, if not then show some text.
I do not wish to use ng-if="model.entries.length == 0" because I might have a TR in there for creating new entry that won't belong to entries.
The directive I wrote currently only works one time because it only runs once. When entries changes the directive won't run again and therefore the empty text is still showing
baseModule.directive('emptyTbody', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
if (element.find('tr').length == 0) {
element.addClass('empty');
} else {
element.removeClass('empty');
}
}
}
});
Is it possible to write a directive that runs when scope changes like regular angular behavior? Or if this cannot be achieved through a directive, is there any other ways to achieve this?
Here is the Html
<tbody empty-tbody>
<tr ng-if="isCreating()">
<td>
<input ng-model="creatingItem.Name"/>
</td>
</tr>
<tr ng-repeat="item in model.entries" >
<td>
<input ng-model="item.Name"/>
</td>
</tr>
</tbody>
Create a isolate scope and put watch there
Like this
baseModule.directive('emptyTbody', function() {
return {
restrict: 'A',
scope: {
source: '='
},
link: function(scope, element, attrs) {
scope.$watch("source", function(nv) {
if (nv) {
if (nv.length == 0)
element.addClass('empty');
else
element.removeClass('empty');
} else
element.addClass('empty');
});
}
}
});
HTML
<tbody empty-tbody source="model.leps">
EDIT
If you wanna to use only from element .
You can use anonymous function to watch.
Try like this
baseModule.directive('emptyTbody', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(function() {
return element.find('tr').length;
}, function(nv) {
if(nv){
console.log("Table has data")
}
else
console.log("Table has no data");
});
}
}
});
JSFIDDLE

onFinishRender not being fired

Plunker
I'm loading data into a table using ng-repeat.
There is an onFinishRender, which emits ngRepeatFinished. However it's not being fired.
Any ideas why it's not working?
logsmgr.directive('onFinishRender', function ($timeout) {
showLog("onFinishRender");
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit('ngRepeatFinished');
});
}
}
}
});
You need to add the directive to one of your repeat elements. For example, from your Plunker add on-finish-render.
<tr ng-repeat="data in model.DataList" on-finish-render>

Access parent data model in directive

I wrote a directive to check for double values in a data column:
The markup
<table>
<tr data-ng-repeat-start="rowItem in vm.model.data" ...>
<td>
<input type="text" data-ng-model="rowItem.ID" data-unique-column="vm.model.data" />
</td>
...
</tr>
</table>
and the directive
(function () {
'use strict';
angular.module('app').directive('uniqueColumn', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
element.on('keyup blur', function () {
scope.$eval(attrs.uniqueColumn).forEach(function (item) {
// validation logic
});
});
}
};
});
})();
Everything works fine but I asked myself if there was a solution to access the data of my repeater, i.e. vm.model.data, without passing an argument to the directive?
Because you didn't isolate the scope, you can read javascript's prototypal inheritance. You can perhaps access a method from the child that will then lookup to the parent's. And perhaps use the $index as the parameter.
Why not use another directive to define the unique-column's model and add it as a dependency on the unique-column directive, like this:
unique-column-model directive:
app.directive('uniqueColumnModel', function() {
return {
restrict: 'A',
controller: function($scope) {
// add more logic here if necessary
},
link: function (scope, element, attrs, ngModel) {
// save the value of the uniqueColumnModel as a private var in the scope
scope.$uniqueColumnModel = scope.$eval(attrs.uniqueColumnModel);
}
};
});
unique-column directive:
app.directive('uniqueColumn', function() {
return {
restrict: 'A',
// set the uniqueColumnModel directive as a dependency (^ is to search on parents)
require: ['ngModel', '^uniqueColumnModel'],
link: function (scope, element, attrs, ngModel) {
element.on('keyup blur', function () {
// use the private $uniqueColumnModel var that was
// previously saved on the scope
angular.forEach(scope.$uniqueColumnModel, function(item) {
// validation logic
});
});
}
};
});
And on the HTML:
<tr ng-repeat="item in model.items" unique-column-model="model.items">
<td>
<input type="text" ng-model="item.id" unique-column />
</td>
</tr>
Check this plunker.
There's still room for improvement but the idea is there...

Resources