kendo UI grid master/detail using angular - javascript

I'm trying to implement a Kendo UI master/detail grid using the kendo angular directives:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<kendo-grid options="gridOptions">
<div k-detail-template>
???
</div>
</kendo-grid>
</div>
</div>
In the controller, I've configured gridOptions on $scope to retrieve data from a rest service. This works fine. The grid displays this data. Now upon expanding a row, in detailInit function (defined on $scope.gridOptions) I make a second rest request to retrieve the child data associated with the expanded record. I want to display this data in the detail template.
My question is, how do I bind the HTML in the k-detail-template to the data returned from the second request? I tried assigning this data to $scope but then if I expand one row and then another row, both rows render the same detail. This is understandable as both detail rows will be bound to same scope.
In the following example on the Telerik website they bind to the dataItem.FieldName, but I don't think this is appropriate for me as I am not displaying a grid in the detail template.
http://demos.telerik.com/kendo-ui/grid/angular
I'm a newbie to Angular so apologies if I'm missing something obvious. Please let me know if you have any suggestions.
Thank you.

Related

How can I pass in an <input> element to ng-for, which is bound to some ng-model?

Background
I am designing a reusable table component. The component was originally designed to merely display data in a table structure.
e.g you pass in a data array and a columnInfo array and the component renders an HTML table
There has been a change in requirements however, and now the table needs to support input fields.
Textfield 1 Textfield 2 Textfield 3 Input 1 Input 2
testestestestestsetestsetestestsetestestsetsetsett *dropdownhere* *textbox here*
The Problem
First and fore-most , simply displaying an "extra textbox column" on every row has proven difficult.
I've used a simple ng-content with single-selector
Table Component. html
<tr *ngFor="let row of rows" (click)="onCellClick(row)">
<td *ngFor="let column of _columns">
{{ getData(row,column) }}
</td>
<td><ng-content select="[test]"></ng-content></td>
</tr>
Parent Component
<table-component [columns] = "tableHeaders"
[data]="_allTasksArray"
(cellEvent)="getActionUrl($event)"
[filterAllColumns]="true"
>
<div test >
<h1>TEST</h1>
</div>
</table-component>
However this does not work as expected, the h1 TEST is only rendered in ONE row. And after some digging around, I discovered that the template passed in from ng-content can only ever be displayed once.
Not very useful for my requirements.
The Question
So if there exists a way to pass in an HTML element to a component for use with ngFor, how then can I associate these inputs with a value?
for example If I wanted to pass in a drop down pre-populated with values specific to each row in the table.
This is how it should work
<table-component>
<template-for-content>
<input [(ngModel)]="This would be linked row[column.name] in the table">
</template-for-content>
</table-component>
Table
<td><ng-content someWayOfPassingDataBackToTemplate></ng-content></td>
You should take a look at the reactive forms module for angular 2, I think this would be a good use case for it. There is a good walkthrough of it in the Angular 2 docs. Reactive forms let you define forms 'programmatically' using objects. The walkthrough shows you have to set it up so you can pass in an array of configuration objects (each object representing a single input) into a reactive-form directive and it will iterate over the array and render an input based off each configuration object. It also shows how to get the data out of a reactive form.

Dragula Angular2 update values using observable

I am writing a tree control using Angular2 and ng2-dragula (based on dragula). I am currently using something very similar to the example nested repeat example here. I have no problem loading in my list and getting drag and drop to work as expected. What I need to do is click a button, go back to the http service get fresh data, then update data on page. I know that I can use javascript to find the id and update that way but it doesn't seem like the correcy way to handle it.
Here is my component code - All this does is just over write the view data and completey undo any drags changed etc (im sure that is by design). I have tried a bunch of different different ways to use dragulaModel, but no matter what the whole component is re-rendered no matter what happens. I need to be able just to update the child text
I'm new to angular and want to make sure i follow the correct patterns
item.component.ts
loadItems(){
this._itemsService.getIems();
}
reloadIems(){
this._itemsService.getItems();
}
item.component.html
<div *ngIf="items">
<div class="holder">
<div *ngFor="let item of items | async">
<div (click)="checkCollapsed(item.text)" >
<div *ngIf='item.children' [dragula]='"first-bag"'>
<div *ngFor='let child of item.children' class="item">
<span class="handle">+</span><span id='{{child.id}}' [innerHtml]="child.text"> </span>
</div>
</div>
</div>
</div>
</div>
</div>
Edit
If I add a .subscribe to loadItems() then update this.items manually like this.items[0].children[0].text = "1000" in reloadItems() it works as i would like. Should I be manually updating the whole object this way? Seems like a hack
**Edit 2 **
I managed to get it to work by subscribing in the loadItems() then comparing the 2 objects in reloadItems, then making any necessary changes there. I think due to the subscribe it is autoupdating. Can anyone confirm if im doing it wrong/right (working plnkr here, leaving out the angular dependencies)

How to hide ag-grid if rowData is null?

I have a use case where the ag-grid (Angular Grid) I am using must not appear at all if the rowData is null that is returned from the Model code.
As of now I am unable to find a way to do it at the grid level.
What would be the right way to implement this? If hiding the div element is the way to do it, how does one doit in aright way from JavaScript?
If you want to hide the grid if no rows, then use an ng-if or an ng-show, pointing to the gridOptions.data.
<div ng-grid="gridOptions" ng-show="gridOptions.rowData.length>0"/>
or
<div ng-grid="gridOptions" ng-if="gridOptions.rowData.length>0"/>
If you use show, then the grid will stay there, but Angular will apply css to hide the element.
If you use if, then the grid directive will not be initialised by AngularJS until you have data present in rowData.

Angularjs Make drop down disabled when pressing checkbox inside ng-repeat

I'm trying to display on screen html controls using Meta-Data stored in json file.
Also I'm trying to create a state where pressing check box that will make a drop down disabled.
I was managed to achieve this for a select box with static options and a select box with dynamic options (using ng-options).
I could not achieve this when wrapping it with ng-repeat.
I have spent a lot of time making this work but in vane.
I would appreciate if someone could pin point me to the right direction.
I have created a sample code which can be found in Plunker here
From ngRepeat doc:
The ngRepeat directive instantiates a template once per item from a
collection. Each template instance gets its own scope
The trick is to add controlChecked to form and remove the ng-init. So they will be in the same scope.
<div ng-show="control.type == 'Checkbox'">
<input type="checkbox" ng-model="form.controlChecked" name="{{control.id}}"/>
</div>
<div ng-show="control.type == 'DropdownList'">
<select ng-model="control.id"
ng-disabled="!form.controlChecked"
ng-options="value.code as value.name for value in control.items"
name="{{control.id}}"
>
</select>
Demo
from http://docs.angularjs.org/api/ng.directive:ngRepeat:
The ngRepeat directive instantiates a template once per item from a collection. Each template instance gets its own scope.
so it looks like you should use the $parent scope: $parent.controlChecked.

Kendo UI: Dynamically change dataSource of grid on button click event

I am having 2 Json files i.e. Products.json and Promotions.json. Both are having the same structure i.e. fields are same just the values are different.
When the page gets loaded the grid is bound with the data in Products.json as follows:
<!--dataSource gets the Products.json data -->
<div data-role="grid" data-columns="[{field:'code',title:'Code'} .... data-bind="source: dataSource"></div>
after which on button click I want to clear the current records of grid and add data of Promotions.json
<div data-role="grid" data-columns="[{field:'code',title:'Code'} .... data-bind="source: applyPromotionsDataSource"></div>
I am able to read both the dataSources successfully, also I am successfully able to get the "click" event as well..
Questions
How shall I clear the existing dataSource of the grid?
How shall I bind the new dataSource to the grid? (using what method?)
the method setDataSource() works well, but if datasource is different also in columns it goes on error cause it can't find the column "xxxNewDataSourceColumn"... There is a method to refresh also the columns?
I got the solution for the above issue.
I went through the documentation of grid and came across the setDataSource() method and added it on the button click event.
That worked well.
Those looking into this issue, Thanks!! :)
-Hardik

Categories

Resources