How to allow/stop an event based on a condition like YES or NO? - extjs

I need to allow or stop an event from happening, based on a given condition such as a pop up box with options YES, NO and CANCEL.
I need to notify the user saying that there are unsaved data and if the user wishes to SAVE it, IGNORE it or CANCEL his current action(event such as Selection-change or Click).
I tried to use createInterceptor() function. But could not achieve the functionality.
Can anybody give me some suggestions with example? Basically I want to know how to stop an event.
Thanks..
Edited
I like the idea of using beforeXXX events. But I am still facing problems. As I mentioned, I need to ask the user if he wishes to save the unsaved data, which is a popup message box (With options YES, NO and CANCEL) that runs asynchronously. So by the time I get a reply, the event will have happened.
For ex. lets imagine a situation where, there is a page that displays a list of records in a grid with a pagination toolbar attached to it on the bottom(with a page size of 10 and total number pages is 10. So totally 100 records) on the left hand side. If you select a record in the list, the details are shown in a detail view on the right hand side.
Now,
I select third record in the list and make some changes to it in the detail view(form).
Without saving the record, I click on next page button on the Pagination toolbar.
It will show a confirm box from the beforeXXX event of Pagination toolbar, but the event will have happened anyway.
Here if the user clicks on CANCEL, I will have to restore the previous state which is already gone. Somehow I will have to go back and select the third record in the list of previous page.
So in order to resolve this problem, if I return false from my beforeXXX event, the next XXX event will be not be triggered.
But if the user clicks on YES or NO options I will have to trigger the event XXX manually which I am unable to do it for a selection-change event as of now.
Like this there can be many operations like list-filtering, searching, Ordering(A-Z/ Z-A), logout etc. For each of this operation I will have to write customised code which totally spoils the readability of the code.
So I was thinking if there is way to, somehow manually trigger the event XXX by holding the event object in beforeXXX...or is there any other way to restore the previous state.
Please give me suggestions....Thanks...

Many events have their "before-" counterpart, for example "beforeactivate". If you return false from this kind of the processing stops.
If not, or if your event does not have it's before- part, then you can use event object passed to all event handlers and call:
ev.stopEvent();
ev.stopPropagation();
return false;
at the end of your handler.

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

How to refresh UI-Grid layout after reloading data

I have a problem with Angular UI-Grid (http://ui-grid.info/). Grid is implemented in modal window that appears after user clicks button.
Service works that way: User selects data set to prepare and clicks button. After clicking button website sends request to rest service to receive data. After receiving data modal with table is shown. Columns count depends on data requested by user.
The problem is that after user changes columns width and close modal with this table UI-Grid 'remembers' this column width that user left. If then user will select another set of data I am cleaning GridOptions object and fill it once again after data is received. The problem is that row width stays in previous state.
I tried so far:
using apis core.refresh() method - while debugging I can see that this
method fires some event but no effect on my grid,
remove whole DOM node and append it again before receiving response with new data
various different hacks trying to use many methods found inside grid api - no success at all.
I am sorry that I am unable to reproduce this in any fiddle but it would be really difficult I am afraid to match my case.
Any help would be very appreciated. Thanks
ps. it also applies to my another table where user can pin and hide columns. Pinned/hidden columns remains hidden/pinned after receiving brand new data. And it is not cool.
Once you set the data to the grid, you should be calling this -
gridApi.core.notifyDataChange( uiGridConstants.dataChange.ALL)
From the docs,
Notifies us that a data change has occurred, used in the public api
for users to tell us when they've changed data or some other event
that our watches cannot pick up
notifyDataChange tells the framework that one of the options or columnDefs has been changed.
Checkout this thread

BreezeJS Entity keeps getting refreshed?

I have a page with two panels. The first panel is where create and update happens, and the second panel is a list of stuff that I just added. Sort of like this (below). The second panel updates the list every X second.
Each list has an edit button that takes it back to the first panel. I pass the entity through the button's function and fill up the values in the edit panel. Here's the weird thing, when I try like say edit an entity in the list, an the interval happens to update the list, the entity gets refreshed and all my changes are never saved.
I tried just passing the id though the button then doing a get request for that particular entity and performing the edit, but the interval takes place and my changes are reverted.
I think my only option is to do angular.copy(myEntity) and do the edits from there, and then manually do the PUT request. Is there another way for the edited entity not to be affected by the interval aside from doing an angular.copy()? Pausing the interval while something is being edited is not an option, since client wants the list to update even when he's editing something.
If you need to keep your data up to date by refreshing every few seconds, i recommend implementing a bool HasChanges() function in your controller. This will return true if the data has changed, and false if not. That way you can decide if you want to pull and refresh new data, or deffer it until your editing is done without overwriting your unsaved changes.

Refresh Data in ComboBox List

I have a datatable (jobs) with a column in this table called StatusId. I have another datatable (jobStatus). The job table has 1 job record and the jobstatus table has all the job status.
On my winforms form I have the job record displayed and the job status is a combobox displaying the contents of the jobstatus table. The List portion (DisplayMember) is bound to the jobstatus table and the data portion is bound to the jobs table. (ValueMember) So all works well and when my jobs are selected and displayed the combobox selects the respective job status...All good.
Now I have another form (JobStatus) where I can added more job status records. So while I am entering / changing job records I discover I need another job status, so I jump over to my job status form and enter my new status. I then jump back to the job form and I now want to be able to select my new job status in the combobox.
My questions is what is the best practice for this senario where new records have been added or edited to a lookup style list which is used to populate a combobox on another form. I have tried putting code in the activate event of the form which works except the form flickers and it looks a ugly.
Any ideas???
I was virtually doing what your said, which made me look a bit closer at the code. The issue was the order I was processing the lines of code, and I found that when
old code
cboCustomer.DataSource = Business.Contact.GetContact( Enums.ContactType.Customer ).Tables[0];
sorted = ( ( DataTable ) cboCustomer.DataSource ).DefaultView;
sorted.Sort = "Name ASC";
new code here
DataView dv = Business.Contact.GetContact( Enums.ContactType.Customer ).Tables[0].DefaultView;
dv.Sort = "Name ASC";
DataTable dt = dv.ToTable();
cboCustomer.DataSource = dt;
works like a charm. Cheers for your help
You should be able to use the Activated event without a problem. That's even what the documentation says it is good for:
You can use this event for tasks such as updating the contents of the form based on changes made to the form's data when the form was not activated.
Of course, you'll get a few false positives when you subscribe to this event on the parent form. Consider the case where the user switches to the form without attempting to use the combo box control. It's not a huge deal, but in that case you will have updated the combo box for no reason. This is easily fixed by switching to handling the Enter event for the combo box control. This one only gets raised when that specific control receives the focus. The only limitation of the Enter event is that you can't change the focused control from inside of this event handler (but you don't want to do that anyway).
So now we need a fix for the flicker problem, which I think you'll find to be pleasantly simple. At the beginning of the event handler method (regardless of which one you use), before you start updating the combo box, call its BeginUpdate method. This prevents the control from flickering while it is being updated (by suppressing painting). At the end, you need to finish with a call to EndUpdate, which reenables painting and performs a single repaint to reflect your changes.
I just tested this myself, and I don't see any flicker. The most you'll get is a single flicker while the control gets repainted to reflect your changes. Obviously, you can't do any better than that.

Cannot tab out of databound Winforms dropdown list

This is a bit of a strange one, but I've been struggling for a few hours now and I can't understand what is happening.
I was wondering if anyone else has experienced this problem, and can perhaps explain it. I'm building a simple Winforms app and trying to use many of the built in controls.
Basically, I've got a form with a user control and some data capture fields. 3 of the fields are dropdown lists and on the user control I have a bindingSource control that binds directly to a Product class.
At run time I provide an instance of the Product class to the BindingSource and the class contains a property of ProductType. For simplicity I also added a List<ProductType> ProductTypes to the Product Class which loads itself when queried, which means I can just use the same bindingSource and choose the ProductTypes Data Member as the Datasource for the dropdownlist.
Upon running the form, the list binds perfectly and I can see all the product types listed, and I can select one and tab or click to the next field. But obviously the selected value won't bind because I've not chosen any bindings-SelectedValue for the dropdown, only a datasource. As soon as I make sure that the drop down modifies the instance of the Product by binding to the Bindings-SelectedValue, and then run the form, the list still gets populated perfectly and I can tab through the controls as long as I don't make a selection from the dropdown. If I make a selection from the dropdown then the dropdown holds focus. I cannot tab out for love or money and can't even click cancel button on the form, the close button top right is the only button I can click which works and I can't click any other field or dropdown. This affects all three dropdowns as soon as a selection is made.
Anyone have any ideas what I'm missing?
I have tried changing a few things and had some success by feeding the dropdown values a string[] instead of a member of an object. That seems to work, but defeats the object of using databinding doesn't it?
Any help appreciated!
Just guessing here, because I don't have time to set up a test and confirm right now, but are you doing any validating? I seem to remember that data-bound controls won't let you leave if the contents don't validate. Even if you aren't explicitly, try setting CausesValidation to False to see if there's any sort of validation going on behind the scenes, that might at least give you a hint.
Thanks for the input on this, helped me wrap my head around this.
In my case, it turns out that an exception was being thrown in one of the EventHadlers for my ComboBox.Validating event. It was hard to track down, because the IDE didn't show me that exception. I was able to modify the Exception behavior (in the debug menu) and have it show me any InvalidOperationException that was being thrown, and then I was able to track it down.
As Tom suggested, turning off CuasesValidation was the ticket to figuring it out.
For Infragisticst Dropdowns (may not be true for other winform dropdowns): If you have "LimitToList" set to true you can be stuck in a dropdown that you can't get out of without realizing it. Use the ItemNotInList even to trigger a warning message.

Resources