Apply rowTemplate on Kendo grid without overriding current - angularjs

I'm using Angular 1.4 typescript, with Kendo (using angular directives).
I'm trying to make a RowTemplate for each row, to change the color based on a property of the item.
I know there are some approaches with jQuery, but I find them very displeasing... If I'm using angular, I would like to reference items with angular.
This is my HTML:
<div id="resultSubTasksGrid"
kendo-grid="resultGrid"
k-options="vm.gridOptions"
k-columns="vm.columns">
</div>
This is my gridOptions:.
gridOptions: kendo.ui.GridOptions = {
rowTemplate : "<tr data- uid='#: uid #' ng-class='sent: item.IsSent'></tr>"
}
My problem comes here: I don't want to override the full row. This approach does so. I have lot of columns, and almost all of them have celltemplates I don't want to lose (but I don't want to have them all in the RowTemplate either).
I would like to know if is it possible to have something like:
rowTemplate : "<tr data- uid='#: uid #' ng-class='sent: item.IsSent'>{{RENDERCONTENT}}</tr>"

Well, it seems that by how Kendo it's developed, once you set up a row-template, you need to go all in. There is not such thing as partial template or wrapper.
More information here.

Related

Angular 1 ng-class doesn't work as expected

I have a simple ng-class that switches two classes based on the condition. When the class is switched, the order of the classes is messed up not sure why. Has anyone a solution for this?
<div class="ui" ng-class="{'two column grid' : submitNow, 'one column grid' : defaultState}"></div>
Rendered HTML when submitNow is true. This works as expected
<!-- submitNow is true -->
<div class="ui ng-scope two column grid"></div>
Rendered HTML when defaultState is true. This messes up the order of classes added by ng-class
<!-- defaultState is true -->
<div class="ui ng-scope column grid one"></div>
*** Edit ****
Quite strange because it works on jsfiddle. But here's the screenshot of my rendered html code
Here is a demo
https://codepen.io/vibwaj/pen/KKPBdNp
OK...looking at the style rules in elements inspector, semantic ui uses selectors like .ui[class*="two column"].grid > .row > .column
Not sure why they do it that way which is unusual and does make the order important.
Also not sure if it is angular or the browser that sorts the order of those classes. I suspect it is the browser, but that is a guess.
Rather than try to figure out what causes the sort you can add the following rule to fix layout for non specific class order.
.ui.two.column.grid > .row > .column,
.ui.two.column.grid > .column:not(.row){
width:50%!important;
}
Working codepen
Update:
I didn't notice the semantic UI framework that is using this approach.
If you still need the same approach, you can check the forked Codepen which I created a custom directive to be alternative than the original NgClass directive.
app.directive("myNgClass", function() {
return {
link: function(scope, element, attrs) {
scope.$watch(
function() {
return attrs.isExpand;
},
function(isExpand) {
element.removeAttr("class");
if (JSON.parse(isExpand)) {
element.addClass("two column grid");
} else {
element.addClass("one column grid");
}
}
);
}
};
});
Original Answer
So diving deep into the NgClass directive implementation in Angularjs source code and checking how they update the classes, there is a function called updateClasses.
In this function, it finds which classes should be removed and added.
Instead of replacing all the classes when the Boolean flag gets inverted, NgClass keeps the overlapping classes and checks which classes should be added / removed.
So in your case,one column grid (the default case) and two column grid have the column grid classes in common, so it will keep them, but remove the one from the start and add two at the end. So the result will be column grid one.
I really don't suggest to use the order of the classes as CSS selectors. This will make it more harder to select elements and make things more complex.
I also have a comment regarding the CSS selectors that you are using. I really suggest you to read Keep your CSS selectors short article so you can have a better practice of using shorter selector and why keeping the CSS selectors short can help with many things.
For example, If you don't need the one, column and grid classes seprately, you can just use .one-column-grid as a class name / CSS Selector instead of .one.column.grid.

Kendo UI grid with angular - curly brackets not binding value in column template

I just started using kendo-ui grid and have created my columns and everything works with data coming back. I tried adding in a template value to my column definitions and the kendo docs say that I should be able to use {{dataItem.something}} to access the value in a template. This does NOT work. However doing <span ng-bind='dataItem.something'></span> works fine. Why is this, and how can I get the curly braces binding working? Thanks.
Here is a snippet of pseudo code for what I'm doing:
in my html and controller ( I am omitting all the other options like datasources etc..):
this.gridOptions = {
columns: [
{
field: 'valueOne',
template: "<span ng-bind='dataItem.valueOne'></span>" // THIS WORKS
},
{
field: 'valueTwo',
template: "{{dataItem.valueTwo}}" // THIS DOES NOT WORKS
}
]
};
<div ng-controller="gridController as vm">
<div kendo-grid k-options="vm.gridOptions"></div>
</div>
What I'm attempting is right from the kendo documentation and demos:
http://docs.telerik.com/kendo-ui/AngularJS/the-grid-widget#template‌​s
http://dojo.telerik.com/ikEKIr
TL;DR;
By removing kendo-angular.js the binding is working as expected.
kendo-angular.js library was still being included in our build and was conflicting with kendo.all.js
More:
The kendo-angular.js library was deprecated and support was moved to kendo professional. The angular functionality was moved into kendo.all.js. The docs are very specific about including libraries in a specific order. The include order must be JQuery, Angular, then Kendo. I checked this and made sure to try the latest versions of all scripts, also tried using the specific versions used in the demos. However after digging a bit further into our scripts it turns out that our build scripts were still including kendo-angular.js farther down the list. Removing this fixed my issue.
You cannot use angular templates after app was initialized, when you inserting new HTML angular will ignore it.
Kendo have own templating tags for it:
There are three ways to use the hash syntax:
Render values as HTML: #= #.
Use HTML encoding to display values: #: #.
Execute arbitrary JavaScript code: # if (true) { # ... non-script content here ... # } #.
Also you can use functions as templates:
template:
function (e) {
if (e.type !== 1)
return "";
return '<input type="checkbox"' + (e.canExecute ? 'checked="checked"' : '') + 'disabled="disabled" />';
}
You also can check out docs for more info

angular formly - How to apply the custom css on dynamic label in angular formly?

How to apply the custom css on dynamic label in angular formly?
For one of our formly modal, I am creating dynamic label as below.
formlyConfig.templateOptions.wrapperLabel = 'Is '+ emailAddress + ' the best email?';
emailAddress - populated by service.
would like to display this on UI as - Is abc#abc.com the best email?
Looks like you will need to use the Template Manipulators in Formly to add markup to your label.
or you can just write it as an HTML template in formly---much easier, and what I usually do when I need something like that.
{
template: '<label>Is <strong>{{vm.email}}</strong> the best email?</label>'
}

ngtagsinput angularjs How to assign id to each tag

I'm using ngtagsinput (http://mbenford.github.io/ngTagsInput/) to add highlight functionality to my app. I can't figure out how dynamically add an id for each tag as its being created. I will be using this id to edit the styling of each tag item after it has been created. I saw the demo about custom templates, but this only works if you pre-define the array of tags. I'm a newb to Angular which is probably the issue... Any hints?
You can add the id using an on-tag-added handler. I made a very simple logic that appends the number of tags as id, but you can do whatever you want.
$scope.onTagAdded = function($tag) {
var index = $scope.tags.indexOf($tag);
$scope.tags[index].id = $scope.tags.length;
};
And in the HTML:
<tags-input ng-model="tags" on-tag-added="onTagAdded($tag)"></tags-input>
You can then use the appended id in your custom template if needed. See this Plunker.

Angular UI bootstrap: Type ahead select multiple

I am using angular UI bootstrap type-ahead directive for type-ahead in a form
http://angular-ui.github.io/bootstrap/
I am fetching the records from remote server via $http service. It is working fine.
However I can select only one element from list at a time.
I want to select multiple values from the list and show all currently selected element in input field with a remove button just like tags for SO. The selected tags are stored in angular array model.
How to achieve this ?
I have read documentation for Angular UI bootstrap but I am not able to find anything.
This guy made a directive for this. Should do exactly what you want and it's even using the ui-bootstraps typeahead.
https://github.com/mbenford/ngTagsInput
The best solution I have found so far is io.select
it does exactly what you require, multi-select typeahead.
and the markup is neat and clean too e.g:
<oi-select
oi-options="list.id as list.description for list in lists"
ng-model="tags"
multiple
placeholder="Select">
</oi-select>
This component is also compatible with bootstrap and the new bootstrap 4.
In js file :
To list all selected items, use $item with typeahead-on-select and push to an array for ex.evtMem. delete fn to delete selected item.
HTML :
Use table to list all array values using ng-repeat. Addition to that add remove glyphicon image and function to delete corresponding item.

Resources