Cancel context model when popup(dialog) is closed with close ( 'X' ) button

  • 1
  • Question
  • Updated 4 years ago
  • Answered
  • (Edited)
I want to cancel the context model when popup is closed with 'X'. This is because, when you change something on a popup and close it by clicking 'X' it does not cancel the changes unless you hit cancel button; which is confusing. I tried following code to cancel the model but it cancels all the models which have unsaved changes.

       $(window).on('dialogclose', function(ctxt) {       
            $.each(skuid.model.list(), function(i,m){
                if(!($.isEmptyObject(m.changes))){
                    m.cancel();
                }
                
            });
            
        });


How could  I just cancel the models which are in current popup's context.  Any Idea?

Thanks!
Photo of Gyan

Gyan

  • 1,400 Points 1k badge 2x thumb

Posted 4 years ago

  • 1
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
I as well think that there needs to be something we can do for action wise when clicking the x. It wouldn't be too hard to implement either as far as adding this functionality to the popup component.

Either an action framework or choose a button in the popup to trigger. The latter would be harder to do, but better for page management.
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Until then, I'm not at all sure how, but I'm sure something can be done in javascript. The term listener comes to mind. Beyond that though, I'm not the person to do this. At least not yet. ;) Irvin, Moshe, Barry, and Menachem all are better equipped than I. Of course the Skuid folks too.
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,006 Points 20k badge 2x thumb
We want to implement "on Close Actions"  on popups that would be triggered with any mode of closing the popup - including the X.   We just haven't gotten there. 

What we reccomend is handling the "cancel model" action when you open the popup.  This is an action that can be managed with the current action framework.  So for a "New Contact" button we'd build out the following actions. 

1. Cancel NewContact model  (to get rid of any old rows where users had hit the red x)
2. Create New Row on NewContact model
3. Open Popup. 

This allows you to get the same effect,  without any javascript. 
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
On Close Actions. That works.

The recommendation covers most scenarios where issues might arise. I can't think of a specific scenario, but I'm sure it can cause problems that the model has changes to it.
Photo of Gyan

Gyan

  • 1,400 Points 1k badge 2x thumb
Thanks Gents for your replies. However, I think I did not make my scenario clear here. I would like to make it clear now.

I have a skuid table which is based on model 'OpenTasks'. The skuid table has a row action 'View/Edit Details' of type 'Pop Up'  which has field editor (based on the same model 'OpenTasks' of course) . When I click View/Edit Details in the UI I get nice pop up which is cool. But if I change something on the popup and close with 'x' without saving/canceling it, the model ('OpenTasks') will have unsaved changes. Which is rather confusing. I would like to get the 'OpentTasks' model ( by using javascript or any other way eg. Action framework ) so that I can cancel 'OpenTasks' model when I close the popup with 'x'.  As I already mentioned I could do it with the following

     $(window).on('dialogclose', function(ctxt) {       
            $.each(skuid.model.list(), function(i,m){
                if(!($.isEmptyObject(m.changes))){
                    m.cancel();
                }
                
            });
            
        });

But the problem is, it cancels all the models which have unsaved changes while the requrement is to Cancel ONLY the  model on which the popup's field editor is based ('OpenTasks' model in this case).
(Edited)
Photo of Greg Jarrett

Greg Jarrett

  • 3,496 Points 3k badge 2x thumb
would it be possible to simply hide the 'x', thus forcing the user to press a button to cancel the popup? (maybe a short term solution until the on-close actions are available)
Photo of Moshe Karmel

Moshe Karmel, Champion

  • 8,646 Points 5k badge 2x thumb

Try this, you should be able to get at the model manually (skuid.model.getModel()): https://community.skuidify.com/skuid/topics/add-a-beforeclose-event-handler-to-a-popup

Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Yup. The article Moshe points to is something I have yet to learn how to do, but I'd like to add to it.

There must be a way to determine which component and thus model is in the popup. If that is so, then the event listener could be dynamic. We could even add something that opens a new popup that confirms the user action. Not sure about being able to cancel the close popup though.

Would be slick for sure.
Photo of Gyan

Gyan

  • 1,400 Points 1k badge 2x thumb
@Greg I tried to hide the 'x' with css. But you can't get out of the popup unless you make some changes as save/cancel button is not active.

@Moshe I had a look in to the link you pointed to but it does not seem to work yet. I think this functionality is not implemented in skuid yet. Also, even if this functionality worked,  it would not give me which models were used in the current popup  to cancel these dynamically (which is my main concern).

@Pat Yes, there must be a way to determine which component and thus model is in the popup. I am expecting someone from skuid to provide clues.
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
Jnanendra, you're very close, if you inspect the event object passed on dialog close, you can get the Popup/Dialog's Contents, and then you can inspect the child DOM elements, find one corresponding to a Field Editor / Table, and then use .data('object').model on the element (only rely on .data('object') for Field Editor / Table) to get the Model, like this:

$(window).on('dialogclose', function(e) {	     
    // Get the contents of our Dialog/Popup
    var dialogContents = $(e.target);
    // Find the first Field Editor child (this might be different depending on your structure) 
    dialogContents.children('.nx-basicfieldeditor').each(function(){
       var el = $(this),
           dataObject = el.data('object');
       if (dataObject) {
           var model = dataObject.model;
           if (model) model.cancel();
       }
    });
});
Photo of mB Pat Vachon

mB Pat Vachon, Champion

  • 42,714 Points 20k badge 2x thumb
Can't wait til I can do code like that! Seems super simple.
Photo of Gyan

Gyan

  • 1,400 Points 1k badge 2x thumb
Thank you Zach!

The code you provided worked well ( with slight tweak: used find() method instead of children()). Also, it now cancels only the models which has unsaved changes.



$(window).on('dialogclose', function(e) {
    // Get the contents of our Dialog/Popup
    var dialogContents = $(e.target);
    
     // Find the first Field Editor child (this might be different depending on your structure)
     dialogContents.find('.nx-basicfieldeditor').each(function(){
        var el = $(this),
            dataObject = el.data('object');
        if (dataObject) {
            var model = dataObject.model;
            if (model && !($.isEmptyObject(model.changes))) model.cancel();
        }
     });
});