Delay model change when editing cells in Angular ui-grid - angularjs

When editing a cell in a ui-grid, the underlying model changes immediately (before committing the change by pressing Enter). Pressing escape undoes the change (by setting the model to the original value).
I have a $watch set on the model, it fires with every keystroke, including the cancel event. I would like the model to only change when the change is committed in the grid.
My work-around is to not have a watch, and use a combination of gridApi.edit.on.afterCellEdit and firing events when action buttons (custom templates in cells) are pressed - but that is not a very graceful solution.
Is there any way to coerce ui-grid to delay updating the model until after the cell changes are committed?

There isn't a way built in, currently, as the Grid uses Angular's two-way binding. I would personally try binding the model to a "temporary" local variable using editModelField or a custom row template. Then have your afterCellEdit handler overwrite the "real" model when the change is committed.
You could package this functionality up in a plugin. There's a Yeoman generator for UI-Grid plugins: https://github.com/c0bra/generator-ui-grid-plugin . And this post has a how-to on using it: http://brianhann.com/write-your-own-ui-grid-plugin/

Related

ExtJS Grid roweditor still dirty after grid save and store reload

I'm using ExtJS 5.1.3, I have a grid which is loaded from a store which has a model. The grid is set to use plugin roweditor, so I edit a cell and give it a new value, at this point the red tick is shown that the cell has been changed.
I have a Save button which when clicked gets the store.getModifiedRecords() and passes these off to a ajax request, upon success of this request a few things happen and the last action I do is to load the grid store again which then populates the grid again with the latest version of the data, this is fine and seems to be working as expected.
As this is a multi page application I also have a check when a user navigates away from this page, this is to catch any unsaved grid changes, so basically I get any form from the page and verify the isDirty() value, this is where I am finding my issue, the roweditor is being returned as dirty, this is because some columns have an editor and ExtJS uses form validation on these fields,
I can't understand why the store loading again has not cleared any dirty fields associated with the grid columns? I've tried a number of things such as clearing the store prior to ajax request along with refreshing the grid view, I've tried committing the store changes prior to doing the ajax request but each time I try navigate away from the page after a grid save I pick up the roweditor as having dirty fields :( any help is greatly appreciated.
EDIT: managed to replicate on a simple fiddle
https://fiddle.sencha.com/#view/editor&fiddle/1rmf
The fiddle is basic, to replicate follow these steps;
edit first row age, change age to 13
click Save (i'm forcing the store to load data which has the change we've made)
click 'Check roweditor is Dirty() value' button to see the value of the roweditor isDirty() function, this will return true
if you look at the button handler, you can drill into forms[0].items.items[2] and see that this field has dirty: true which is why isDirty() is returning true.
SOLUTION
As explained in accepted answer, the roweditor is not affected by the store edit/cancel or load in my case. What I did when clicking on 'Save' was to get the grid, then the editor and it's form and called reset() on this so effectively sync everything again.
grid.editingPlugin.getEditor().form.reset();
you can also get access to plugins via grid.getPlugins() which returns an arrary
updated fiddle to show it working
https://fiddle.sencha.com/#view/editor&fiddle/1rmr
During the editing process grid will eventually call loadRecord on the editor's form. However the editor's form is not cleared upon editing success or canceling. That is why your check for dirtyness returns false.
Grid reloading the data is not destroying the editors. It is an optimisation. Editors are created only once and they are destroyed along with the grid.
I'll try to answer regarding to an experience of mine with an all ExtJS desktop application.
By the way looking quickly over your description, you may have to call the Store.sync() method that refreshes your store.
Looking more deeply, there are many way to make CRUD using ExtJs.
I've been made using the "instance" of store but at certain point I had to change it to static calls like MyApp.store.Model.save() etc. That makes you have only one instance of the store avoiding dirty data.
Here's my project folder if you need
https://github.com/guilhermeribeirodev/grizzlyboilerplate/tree/master/src/main/webapp/js/MyApp

Disabling user input within a Marionette collection view - that is being updated by other parts of the application

Need to disable input buttons for items within a Marionette collection view.
Normally I'd just do:
TheView.$el.find('input').prop('disabled', true);
That should disabled all input elements within the view.
The problem I am having is that other parts of the application are updating that view, as a result anything new that comes into the view is not disabled.
What is a good pattern for dealing with this situation?
INHO its not very good to work with ItemView elements from collection view - its better to use custom event or move disable logick to item view.
In case you have other modules updating the view - if i were you i would move disable term in ItemView template - in this case any update will check this term and render input correctlly.

Angular UI-slider, update model when user drops mouse key

Is there anyway to configure angular-ui slider so the model is updated only when user drops mouse key? Instead of changing the value in realtime?
Reason is performance. I make heavy calculations when everytime my moodel changes.
https://github.com/angular-ui/ui-slider
Instead of ng-click or ng-change, try ng-mouseup. It'll do the trick.
There's not a way to configure it, however it seems feasible that you could fork this and convert the elm.bind('slide') call to elm.bind('slidestop'), which would only trigger after the user is done sliding the handle.
EDIT: You could also listen for both, and publish an event from the directive via $rootScope.$broadcast when the user stops sliding the handle, and do your calculations when the subscriber receives that event.

How to display model value in angular view without binding? Eliminate Angular binding?

I have a usual angular model in $rootScope. Data is displayed in angular Views using {{$rootScope.client.name}}
There is a form where the user can change his name. When it's updating the form with the new name, the existing one changes in the template (which is normal because of the binding).
How can I stop this binding and make the change available on the next refresh or manually after save? Thank you!
Don't bind original object to a form but do a copy (angular.copy) of it before editing and bind a copy in a form. Then after "Save" copy back object bound to a form back to the original object.

Ext: bind formpanel after datastores for combo's have loaded

In an Ext Js-application I am working on I have a formpanel that contains (among other controls) three comboboxes, each with a different datastore. I need to load the form with existing data and display that in the form. This works for all simpel controls (textboxes, checkboxes) but there is a problem with the comboboxes.
The comboboxes each use a datastore but I can see that there is only one store loaded before the form loads its own data, causing that one combobox to display the correct text and the other two the value. If I click and close the combobox without making a selection the correct text appears.
Is there a way to either delay the loading of the form or the binding of the form until all datastores have loaded? The datastores are local stores with autoload and the formpanel calls its own load in the afterlayout-event.
The problem is that the setValue executed by loading your form is executed before the stores of the combo boxes are actually loaded.
You could try to implement the fix condor and animal of ExtJS have propsed in this forum thread on sencha.com: http://www.sencha.com/forum/showthread.php?75751-OPEN-42-ComboBox-s-setValue-call-with-a-remotely-loaded-Store
It basically just delays the setValue call on any combobox until the store of the combobox is fully loaded.
Load the form panel after the rendering is complete. Is there any specific reason you are loading the form in afterlayout event?
Load the form in afterrender event rather than afterlayout. the afterrender event happens when all form is completely rendered.

Resources