0

I'm setting a small window for set and update parameters of different modules in a web app, for this, I'm using a jQueryUI dialog that loads the settings from each module at the time. My problem is that if you hit the button cancel it will reset all the configuration to the initial state even if I have made changes before and saved them before opening the dialog again and cancel.
Also, I would like the Close 'X' button to have the same behavior as the Cancel button.

    var appDiv = $(Container).find(".divAppAdmin")[0];
var backupDiv = appDiv.innerHTML;

var closedFunction = function() {
    $(appDiv).dialog( "destroy" );
};
var closeFunction = function() {
    $(appDiv).dialog( "close" );
    $(Container).append(appDiv);
};
var cancelFunction = function() {
    $(appDiv).dialog( "close" );
    appDiv.innerHTML = backupDiv;
    $(Container).append(appDiv);
}
$(appDiv).dialog({
    "modal": true,
    "title": "Edit",
    "close": closedFunction,
    "buttons": {
        "Save": closeFunction,
        "Cancel": cancelFunction
    },
    "minWidth": 600
});

Step by step:
  1. Open the dialog and introduce some changes,
  2. Save the changes,
  3. Open the dialog again without making any changes,
  4. Hit button Cancel.
At this point, I lose the changes I've made before and saved on step 2 and the module goes back to the state it was before step 1.

I know that using

    appDiv.innerHTML = backupDiv;

is causing the loss of the changes in this specific situation but it works fine if I actually want to undo any modifications.

EDIT:
I kept digging and so far I found a solution for copying the Cancel behavior to the Close 'X' button (How to find out if jquery dialog was closed on escape and execute some code):

 var closedFunction = function (event, ui) {
    if (event.originalEvent) {
        cancelFunction();
    }
    $(appDiv).dialog("destroy");
};

By adding this if clause in the closedFunction() allows me to capture when the dialog is being closed by hitting the 'X' button or pressing the ESCAPE key, then I can call the cancelFunction() inside the if and now is the same as if hitting the Cancel button.

2
  • Welcome to StackOverflow. Please provide a Minimal, Complete, and Verifiable example: stackoverflow.com/help/mcve
    – Twisty
    Commented May 8, 2019 at 16:22
  • thnx, I'll try my best to follow this in the future
    – jpotterh
    Commented May 16 at 17:09

1 Answer 1

1

Consider this semi-basic example.

$(function() {
  var appDiv = $("#appDialog");

  function editSetting(s) {
    $(".setting-id", appDiv).val(s.id);
    $(".setting-name", appDiv).html(s.label);
    $(".setting-value", appDiv).val(s.value);
    appDiv.dialog("open");
  }

  function saveSetting() {
    var sid = $(".setting-id", appDiv).val();
    var v = $(".setting-value", appDiv).val();
    $("#" + sid).data("value", v);
  }

  function resetDialog() {
    $(".setting-id", appDiv).val("");
    $(".setting-name", appDiv).html("");
    $(".setting-value", appDiv).val("");
  }

  appDiv.dialog({
    autoOpen: false,
    modal: true,
    minWidth: 300,
    buttons: [{
      text: "Save",
      icon: "ui-icon-check",
      class: "ui-priority-primary",
      click: function() {
        saveSetting();
        appDiv.dialog("close");
      }
    }, {
      text: "Cancel",
      icon: "ui-icon-close",
      click: function() {
        appDiv.dialog("close");
      }
    }],
    close: function(e, ui) {
      resetDialog();
    }
  });

  $(".app .edit-setting").button().click(function(e) {
    var that = $(this).parent();
    var setting = {
      id: that.attr("id"),
      label: $("label", that).text(),
      value: that.data("value")
    };
    editSetting(setting);
  });

  $("form", appDiv).submit(function(e) {
    e.preventDefault();
    saveSetting();
    appDiv.dialog("close");
  });

  $(".app > .save").button().click(function() {
    var settings = {};
    $(".app li").each(function(ind, el) {
      var k = $(el).attr("id");
      var v = $(el).data("value");
      settings[k] = v;
    });
    //Save Settings to Storage
    console.log(settings);
  });
});
.app ul {
  margin: 10px;
  padding: 0;
  list-style: none;
  width: 300px;
}

.app ul li {
  border: 1px solid #CCC;
  padding: .5em;
  margin-bottom: -1px;
}

.app ul li:first-child {
  border-radius: 3px 3px 0 0;
}

.app ul li:last-child {
  border-radius: 0 0 3px 3px;
}

.app ul li label {
  display: inline-block;
  width: 200px;
}

.app .save {
  margin-left: 10px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="app ui-widget">
  <ul>
    <li id="set-1" data-value="A"><label>Setting 1</label><button class="edit-setting">Edit</button></li>
    <li id="set-2" data-value="B"><label>Setting 2</label><button class="edit-setting">Edit</button></li>
    <li id="set-3" data-value="C"><label>Setting 3</label><button class="edit-setting">Edit</button></li>
  </ul>
  <div id="appDialog" class="appDiv" title="Edit Setting">
    <form>
      <input type="hidden" class="setting-id" />
      <label class="setting-name"></label>: <input type="text" class="setting-value" />
    </form>
  </div>
  <button class="save">Save Settings</button>
</div>

If we treat the dialog like a container or template, we can populate the single dialog with various bits of data. Then it's a matter of opening and closing it.

When a 'Edit' button is clicked, the current setting and value are loaded to the dialog before it is opened. Hitting the 'X' or pressing 'Cancel' closes the dialog without saving. Wrapping our entry with <form> allows us to use Enter to submit the form or clicking 'Save'. Both are configured to save the value before closing the dialog.

I added a reset function to the close callback, so anytime the dialog is closed, it clears any older data out. This is not exactly needed since when we open the dialog, it populates the data into the fields.

We have to store the values someplace. For this example, I am use the data attribute. It can be added as part of the HTML and read by jQuery. It is not sustaining. You can see a final save button and this could read the new values in and push them to localStorage or a database.

Hope this helps.

4
  • Try with local storage maybe ? or you just want to add some html elements ? Commented May 8, 2019 at 23:10
  • @stanchacon it's not clear what OP's intentions are and he did not state them. They may push the data to a session, database, localStorage, or a cookie. That's really up to OP to decide.
    – Twisty
    Commented May 8, 2019 at 23:11
  • I mean that local Storage is a great option to save the data Commented May 8, 2019 at 23:11
  • Thanks @Twisty, your solution really helped me a lot.
    – jpotterh
    Commented May 9, 2019 at 19:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.