I have used custom formatter and editor in slickgrid, which is simply checkbox angular directive. I am using twice the directive, once for formatter, and once for editor. Formatter and Editors are served from angular service. Slickgrid itself is wrapped into an angular directive.
Editors are implemented according to slickgrid doc Writing custom editors
The slickgrid directive is used in several places. One scenario, which I am struggling with, is when there is a grid, and there are buttons outside of grid.
When one clicks one of this button, I have to get the values from cells/editors.
When grid is rendered, once sees checkbox. it is checked/unchecked based on current value of a cell where this formatter is used.
And when one clicked on a cell with checkbox, the checkbox changes from unchecked to checked or vice versa. And then one clickes somewhere else in the grid in the value of editor checkbox copied to cell, and then formatter shows checked/unchecked.
Back to my scenario: when one checkes/unchecks checkbox in editor mode, and directly clickes one of the buttons outside grid, the value of editor is not applied yet to cell, thus the wrong value is send. While we are still in editor mode, and value is not committed.
Now the question, how to commit changes to cell right after the value of checkbox is changed dynamically without waiting for slickgrid to change from editor mode to formatter mode?
Found this question relative, but my environment is not the same.
I found that editor takes args argument which has commitChanges() method, but how to use it?
Best
I have tried a lot of methods of slickgrid, but did not find a better solution but this.
Inside my custom Editor constructor, I have added a watcher that watches changes to checked attribute of Checkbox directive.
$timeout(function () {
controlScope.$watch('checked', function () {
$timeout(function() {
args.grid.getEditController().commitCurrentEdit();
args.grid.resetActiveCell();
});
});
});
The first timeout is not to break the running digest cycle, and just digest it on next run.
And the next timeout is needed to wait until angular is finished with changing scope, and only then commit changes. Otherwise the commitCurrentEdit() will kill the editor, and thus the scope of Checkbox directive.
I hope there will be a better solution.
1 EDIT: This solution brings weird behavior. The first click works good, but the next click on the same cell does not change the checkbox checked.
2 EDIT: I have added resetActiveCell() of grid to leave the focus of active cell, and now it works as I wanted.
3 EDIT: We could not find a better solution without changing the source code of Slickgrid, which is not wished. After searching alternatives and solution for the problem, we decided to use the ui.grid and it plays well with our environment , since we are using angular. And most of the problem we faced with slickgrid, is by default fixed just by using ui.grid without customization. Slickgrid is still of the best grids available for javascript developers, but it seems like it is slowing down from JavaScript progress.
Another solution to commit the change to the grid is call:
Slick.GlobalEditorLock.commitCurrentEdit();
Related
I'm trying to create (what I thought) was a basic Scheduler component for a current project.
EDIT: I have found my own solution, and the answer is provided below. Bonus for any help solving the select all features, which I have shelved for the moment :)
tldr;
Question: Why if I pass in a disabled row, enable it, and begin to edit, that row becomes disabled? If I enable all rows OnInit, everything works as expected.
Editor StackBlitz: Editor StackBlitz for Angular FormArray Table
App StackBlitz: App Stackblitz for Angular FormArray table
The goal is to allow a user to select and/or deselect specific days or time ranges within a form. If that column or row is selected, then their elements will toggle their 'active' state.
So, I toggle the Sunday column and Morning Row. Only the value pertaining to Sunday and Morning time ranges will be active.
I'm using *ngIf or hidden to hide elements from the user, so they cannot edit. If the form input is active, then they can view it an edit that field.
However, the issue comes when I initialize my form with rows that aren't active. So, I have the Morning Row active ngOnInit, and then the user can toggle rows once the state initializes.
When those disabled rows are enabled, and a user begins to edit, that row's active state disables. This is where I'm confused. I'm in the weeds and I can't seem to locate the issue.
After debugging, I have solved my issues. For anyone who runs into a similar use case, my solution involved how I handled setting the active states on toggling the FormControl's values.
Previously I was toggling active values through Angular's getter function:
[FormControl].value.[ActiveFormField] = !active_state
Which wasn't updating the form's proper values.
Instead, I needed to set the values as such:
[FormControl].value.[ActiveFormField].setValue(!active_state).
By setting the value, the form was then properly updated, and my toggle states performed as expected.
I also cleaned up the nested for-loops I referenced; however, I still need to tackle select all and deselect all states.
In in-cell edit mode, grid values do not update when clicking a different row. The update is only triggered when the user hits enter, when clicking outside of the grid, OR by tabbing/clicking to another cell in the same row. The other examples I've seen don't have this behavior so I'm wondering what I might be doing wrong. This has been an issue for sometime now and it has to be fixed before going live.
I have been able to duplicate the issue in an isolated state. Implementing drag and drop reordering (Kendo Sortable) seems to cause this behavior. Again, the behavior is when you are in an editor, change the value in the editor and click an editor in a different row - you will notice that the value doesn't update. Is this a documented bug? What is your suggested workaround?
Here is a jsfiddle demonstrating the issue:
https://jsfiddle.net/bhr7Lmpy/1/
<script async src="//jsfiddle.net/bhr7Lmpy/1/embed/"></script>
The Telerik Team responded here:
https://www.telerik.com/forums/in-in-cell-edit-mode-grid-values-do-not-update-when-i-click-a-different-row#aIdr3qwkX0aJnnNY9irSJg
You might be able to put a focusout event on the grid cell that programatically presses the enter key or clicks the save button.
I am using angular-ui-grid 3.1.1 with 25,50,75 records at a time.
Each cell is having different celltemplates e.g, onclick popovers, hover popovers, file download links, data with profile images, data in nested table etc.
Data is rendering fine in the grid, however for some seconds ui grid becomes unresponsive.
Also i have created an external column chooser. While choosing a column to show/hide, the grid becomes unresponsive for some seconds.(same unresponsive behavior seen with in-built column chooser provided by ui-grid)
Please suggest any fix for this.
sadly, we've had to abandon UI grid for these same sort of issues. The issue, however was not in UI-Grid but in angular lacking performance. In my case I built a grid with ReactJS that I created a angular JS directive wrapper to put over. Even by just putting angular HTML with lots of rows/columns it wasn't fast enough. The last thing you could try before swapping away from UI-Grid would be looking into row/column virtualization if you dont already have it enabled. Here is the option to test
columnVirtualizationThreshold
If you wont change the scope variables, try one-way-data-binding in your templates, it will give you some performance like:
<span>{{::variable}}</span>
IMPORTANT!: Be careful because it wont update data any more until you refresh the view.
Angular UI Grid currently allows for double-clicking on fields for editing, but you can only do this one at a time. Currently, I need a user to click on a button and then have all rows show the editable input fields. I was unable to find a solution online and am now posting a question here.
Anyone else have a current or easy hack for this before I have to start customizing the UI grid library (something I don't want to do yet)?
Thanks!
It is plausible to do this by providing a custom cellTemplate where that template is the editableTemplate, or quite a bit of the editable template. This would mean the edit widgets were shown at all times.
Having said this, the reason that ui-grid doesn't show all the widgets at once is performance. When you have a table you tend to render a lot of DOM elements, and slower devices cant' reasonably render and scroll that many DOM elements. You may also get issues with row virtualisation - you may end up with your editors pointing to the wrong elements in the data.
Is editOnFocus perhaps an option for you?
So what i did is, i used an ng-show directive on cell template to show and hide text box by setting an attribute on entity object of ngRow. By default edit will be false. when you press edit button its is made as true and the text box will appear.
Please find the following plunker for your requirement
http://embed.plnkr.co/tdtCbI8pw6mdSjG4SflP/preview
Hope this helps!!!!!!
I have an instance of CKEditor on a content-editing page. I'm looking to re-use or reset a CKEditor instance.
Use case
I have a table of which each cell is editable. When the user clicks a cell, I present them the CKEditor which provides editing functionality.
I'm setting data using CKEDITOR.instances.cellContent.setData( cellContent );
I'm getting data with var cellContent = CKEDITOR.instances.cellContent.getData();
This works well, except the CKEditor still thinks it has the old content after I call a setData()
user clicks cell #1
user edits cell #1, uses the color 'red' on a word
user saves cell #1
user clicks cell #2
now CKEditor shows the color 'red' as being active/used. But in fact it isn't because since that color has been used, other content has been loaded in the editor.
Does anyone know how to reset, reuse or (efficiently) re-instantiating a CKEditor instance?
(Google did not help me on this one)
Thanks for thinking along!
UPDATE 1
I'm using a single editor instance, which will be reused for editing of each table cell. (hidden when inactive, by setting display:none on containing element)
UPDATE 2
I'm using firefox 13.0.1 for Mac. Allthough this color problem does not occur on Chrome, the same issue does happen with the bold/italic buttons.
It's not possible to re-instantiate editor on new element. One instance is bound to one editable for its entire life.
You haven't mentioned how do you initialize editor. For each table cell, because you want to have editors in cells? Or you have one editor, outside the table and you just want to load content of clicked cell there and update it on blur/change/etc.
If you chose the first option, then you have to create editor instance for each table cell. You don't have to do this on page load - it'd be better to do this on cell click. When user leaves the cell you don't have to destroy (editor#destroy) editor - it's better to hide it and reuse for the same cell later.
If you chose the second option, then setData/getData should be enough to refresh editor's UI (buttons states). I checked now and this looks like a bug. Luckily it can be easily fixed by calling editor#focus after setting data - then UI is updated (at least in my quick test). If it won't work, delay focusing, because I was testing this manually from the console, so it was delayed by default.