Setting scroll position on Kendo Angular Grid - kendo-ui-angular2

When a grid is in a component at one route and the user navigates away and then comes back, the current kendo grid loses its scroll position and starts at the top.
Anyone know a way to "remember" the scroll position so it can be set on the grid manually?

Not a great solution, but it works for the time being. Here it is.
Inside the component with the grid:
private _scrollPos: number;
#ViewChild("grid", { read: ElementRef }) gridEl: ElementRef;
constructor(private router: Router) { }
ngOnInit(): void {
this.router.events.subscribe(e => {
if (e instanceof NavigationStart) {
let gridContent = this.getGridContentElement();
if (gridContent.scrollTop > 0) {
this._scrollPos = gridContent.scrollTop;
}
}
else if (e instanceof NavigationEnd) {
if (this._scrollPos > 0) {
let gridContent = this.getGridContentElement();
gridContent.scrollTo({ top: this._scrollPos });
}
}
}
}
private getGridContentElement(): Element {
let el = this.gridEl.nativeElement as HTMLElement;
let gridContent = el.getElementsByClassName("k-grid-content").item(0);
return gridContent;
}

This is can done by remembering which row was selected, saving the id of the row, and then setting the grid property [selectedKeys]="id" when the user navigates back.
For example if the data for the grid was based on product data then save last viewed row id (ProductID). When the user navigates back to grid, you can push the ProductID you saved to an array that is bound on the grid. This will make the row selected, to scroll to the row you can use the class k-state-selected and scrollIntoView to scroll the row into view.
This is a basic implementation, but should give you a enough to go on. I created a Stackblitz example so you can see how to implement this. Make sure to configure the grid with kendoGridSelectBy and selectedKeys. The kendoGridSelectBy should match the id that you push to the array. In the example I created it was ProductID.

You can set the Grid skip to the same value it last was. You can check out the persist state examples. The Grids use regular paging, but the same principles apply.

Related

Change the Layout in Jetpack Compose

PROBLEM :::
I want to change the layout, more specifically hide or show the components in the layout based on the user click events.
I have attached a screen recording of the final result.
PLEASE VISIT THIS LINK FOR FINAL RESULT
THINGS WHICH I CAN TRY :::
Create same layout with components and load that layout when user clicks on button. But I know it's the very inefficient way.
you can create a isVisible value and add the layout between an if braces.
val isVisible = remember { mutableState(false) }
if (isVisible) {
content()
}
Button(onClick = { isVisible.value = true })

How to get position of clicked icon on cesium map

I am trying to draw circles around an icon that is selected via clicking. My current code is:
this.handler.setInputAction(function(click) {
var pickedObjects = viewer.scene.drillPick(click.Position);
if(Cesium.defined(pickedObjects)) {
if(pickedObjects.length >=1)
{
var cartesian = thisRef.viewer.camera.pickEllipsoid(click.position, thisRef.viewer.scene.globe.ellipsoid);
thisRef.drawCircle(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK;
};
If the user is zoomed out quite far, the position won't be accurate. It needs to be based on the selected object, not the users click. However I can't figure out how to do this. I have pickedObjects, but I can't figure out how to get their position from those objects. It doesn't seem to be an entity (even though I think the icon was an entity when it was being created) and so I can't use entity.position. Thank you for your help.
To be able to access the standard Cesium entity, it turns out, you must go in the drillPick objects id. So I modified my code to get the first object in the list of objects and get the id from that, and now I can call the member position of a standard entity.
this.handler.setInputAction(function(click) {
var pickedObjects = viewer.scene.drillPick(click.Position);
if(Cesium.defined(pickedObjects)) {
if(pickedObjects.length >=1)
{
var entity = pickedObjects[0].id;
thisRef.drawCircle(entity.position);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK;
};

SwiftUI ColorPicker "opened" and "closed" events?

I need to be able to undo / redo the colors that are picked with the new SwiftUI ColorPicker ( on the iPad : it's presented as a floating window )
The thing that makes it very difficult is that there is apparently no way to know that the user has indeed chosen a color ( and therefore closed the panel )
Instead, the behavior of ColorPicker is that it will keep updating the binded color as the user is manipulating the color controls. This is very helpful to show a live preview, but you don't want to register all these color variations for undo / redo purposes : you only want the color that was finally picked.
Therefore there is no logical distinction between the colors that the user tried, and the one that was selected
And I looked everywhere : there aren't any modifiers / notifications related to that.
I know SwiftUI hasn't been there for long, but this seems like a crucial functionality that's missing?
Has anyone found a workaround?
Undo is always tricky. One size does not fit all. In this case a good solution is to throttle the number of events that come into the UndoManager. You can do so by comparing the current time to the time you last commit.
Create a view model that represents your Source of Truth, and conform to ObservableObject to publish events. It will own the UndoManager. It will have a computed property that gets/sets to the internal data, and check the current time against the time of last commit.
class EditViewModel: ObservableObject {
var commitTime = Date.now
let undoManager = UndoManager()
private var _color: Color = .red {
didSet {
objectWillChange.send()
}
}
var color: Color {
get { _color }
set {
let oldValue = color
let now = Date.now
if now.timeIntervalSince(commitTime) > 1 {
undoManager.registerUndo(withTarget: self) {
$0.color = oldValue
}
}
self.commitTime = now
_color = newValue
}
}
}
Now all that's left to do is create your view and pass in the binding. The implementation details are opaque to the View since it is managed by the ViewModel.
struct EditView: View {
#StateObject var vm = EditViewModel()
var body: some View {
Form {
ColorPicker("Color", selection: $vm.color)
}
}
}
If you need even more control, you can additionally compare the last committed color to the new value and only commit if there is a significant change.
I will also agree that a data-driven approach like SwiftUI's can make undo more tricky. For example, when you need to coalesce multiple operations together into one undo group. By its very nature an undo group is procedural-- the user did one thing after the other, and finally terminates on some condition. But I'm sure there is some way to encapsulate this step-wise operation in a transaction object of some kind.
Undo is hard!

Material Angular md-autocomplete clear and blur after selection (multi select)

I am trying to use md-autocomplete in Angular Material as a multi selector. The idea is, that the selected element from the autocomplete will be added to an object array after selection and then the selection will be removed from the md-autocomplete. I was able to clear the md-autocomplete, but the focus stays on the md-autocomplete input and so the autocomplete suggestions are still visible.
Example:
http://cdpn.io/QjQGVQ
Code:
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
if(item)
{
//check if item is already selected
if($filter('filter')(vm.contactsSelected, function (d) {return d.id === item.id;})[0])
{
$log.info('Item already selected. Will not add it again.');
}
else
{
//add id to object
vm.contactsSelected.push(item);
}
// clear search field
vm.searchText = '';
vm.selectedItem = undefined;
//somehow blur the autocomplete focus
//$mdAutocompleteCtrl.blur();
}
}
PS: I am aware I could use the contact chips of Angular Material instead, but I was still wondering how the blur could be achieved.
If you set md-no-cache="true" property inside your the list will dissapear, but input field will not be cleared. I think is better solution than clearing input field but leaving the list visible, but is up to you.

Telerik MVC Grid submitChanges with no grid changes

I'm using Telerik's MVC grid, and I would like to submit batch edit mode changes with some out of grid values. According to this telerik forum I can call the grid's submitChanges function and supply non-grid values inside the OnSubmitChanges event. This function only gets called if the grid has changes. There can be a case when values are changed outside of the grid but grid values are not saved. Is it possible to force the submission so that non-grid values can be submitted?
Good thing Telerik MVC Extensions are open source. I figured out the answer the following way:
function SaveCriteriaChanges() {
var grid = $("#MyGridId").data("tGrid");
//don't submit if grid fails validation
if (!grid.validate())
return false;
if (grid.hasChanges()) {
grid.submitChanges();
} else { //no grid changes to process so force submission
var additionalValues = {};
if(!$.telerik.trigger(grid.element, 'submitChanges', { values: additionalValues })) {
grid.sendValues($.extend({}, additionalValues), 'updateUrl', 'submitChanges');
}
}
return true;
}

Resources