jquery.AreYouSure icon indicating copy to clipboard operation
jquery.AreYouSure copied to clipboard

CKeditor support

Open ghost opened this issue 10 years ago • 10 comments

Hi,

You can add CKeditor support. Just simply add following code into your solution.

checkForm()

(...) // ckeditor if (typeof (evt.editor) !== 'undefined') { if (CKEDITOR.instances[evt.editor.name].checkDirty()) { setDirtyStatus($("#" + evt.editor.name).parents('form'), true); return; } }

(...)

initForm()

(...) //ckeditor if (typeof(CKEDITOR) !== 'undefined') { CKEDITOR.on('instanceReady', function () { for (var instanceName in CKEDITOR.instances) { CKEDITOR.instances[instanceName].removeListener("change", checkForm); CKEDITOR.instances[instanceName].on("change", checkForm); CKEDITOR.instances[instanceName].removeListener("keyup", checkForm); CKEDITOR.instances[instanceName].document.on("keyup", checkForm); } }); } (...)

ghost avatar Sep 17 '14 07:09 ghost

+1, that would be awesome! :+1:

paulofreitas avatar Oct 21 '14 17:10 paulofreitas

You should make a pull request.

lagseeing avatar Oct 22 '14 16:10 lagseeing

That's good information. Would you be willing to submit a demo page to the repo? I'm thinking an example HTML file located at:

~demo/integration/ckeditor-ays-example.html

Just a simple page that demonstrates this integration I'm sure would be a great help to others.

codedance avatar Oct 23 '14 23:10 codedance

I tried this and it doesn't work for changes made to the text, only changes made via the toolbar.

I've narrowed down the problem to a race condition. The event for the form fires, and sets dirty to false. And then the event for CKEditor fires and sets dirty to true. If it happens the other way round then it works (such as while debugging), but without a breakpoint set, I found it was setting dirty and then immediately unsetting it.

robme avatar Oct 22 '15 16:10 robme

I got it working. I was using tyama's commit above, which didn't work. You need to put the initForm code at the end, not above, and tweak it slightly. Here is my initForm:

var initForm = function($form) {
  var fields = $form.find(settings.fieldSelector);
  $(fields).each(function() { storeOrigValue($(this)); });
  $(fields).unbind(settings.fieldEvents, checkForm);
  $(fields).bind(settings.fieldEvents, checkForm);
  $form.data("ays-orig-field-count", $(fields).length);
  setDirtyStatus($form, false);

  //CKEditor
  if (typeof(CKEDITOR) !== 'undefined') {
    CKEDITOR.on('instanceReady', function () {
      for (var instanceName in CKEDITOR.instances) {
        $('#' + instanceName).unbind(settings.fieldEvents, checkForm);
        CKEDITOR.instances[instanceName].on("change", checkForm);
        CKEDITOR.instances[instanceName].document.on("keyup", checkForm);
      }
    });
  }
};

Explanation: The CKEditor part has to come afterwards because we want to unbind the events added. And in order to unbind them, I just use the instanceName as a selector and call it in the same way they were bound above. This means the change/keyup events are not firing on the hidden textarea (the contents of which does not change), and instead, CKEditor's events will fire.

robme avatar Oct 22 '15 16:10 robme

This worked for me :

  function beforeUnload(evt) {
    for (var name in CKEDITOR.instances) {
      if (CKEDITOR.instances[name].checkDirty())
        return evt.returnValue = "messageUnsaved";
    }
  }

  if (window.addEventListener)
    window.addEventListener('beforeunload', beforeUnload, false);
  else
    window.attachEvent('onbeforeunload', beforeUnload);

jfcartier avatar Jul 05 '16 18:07 jfcartier

I'm using v4 of CKEditor so ymmv... but this is how I do it without modifying jquery.are-you-sure.js:

$('#my_happy_little_form')
.areYouSure({'message': "Your changes haven't been saved."} )
.on('dirty.areYouSure', function() {
	$(this).find('input[type="reset"], input[type="submit"]').prop('disabled', false);
})
.on('clean.areYouSure', function() {
	$(this).find('input[type="reset"], input[type="submit"]').prop('disabled', true);
});

CKEDITOR.on('instanceCreated', function(e) {
	e.editor.on('change', function(event) {
		var textarea = event.editor.element.$;
		$(textarea).val(event.editor.getData().trim());
		$(textarea.form).trigger('checkform.areYouSure');
	});
})
CKEDITOR.replace('body_xhtml', { 
	// place options here
});

cmanley avatar Dec 31 '16 03:12 cmanley

@cmanley Thanks for getting me started on this. I'm wondering why not just this:

        CKEDITOR.on("instanceReady", function (event) {
                $('form').areYouSure();
                event.editor.on('change', function(event) {
                    $('form').trigger('checkform.areYouSure');
                });
            });

bryanjamesmiller avatar Jun 09 '17 20:06 bryanjamesmiller

@bryanjamesmiller It won't work like that because you need to copy the CKEDITOR data into the textarea element before triggering checkform.areYouSure. However, you can use either instanceCreated or instanceReady as both seem to work, and you can initialize areYouSure either inside the instanceCreated or instanceReady or outside as I did. The latter makes more sense to me as areYouSure depends on the textarea existing and not a CKEditor instance.

cmanley avatar Sep 03 '17 21:09 cmanley

Just wanted to pop along to say thank you @cmanley

Slotting in:

CKEDITOR.on('instanceCreated', function(e) {
	e.editor.on('change', function(event) {
		var textarea = event.editor.element.$;
		$(textarea).val(event.editor.getData().trim());
		$(textarea.form).trigger('checkform.areYouSure');
	});
})

Makes it work perfectly as far as I can tell :+1:

LiamDawe avatar Sep 20 '17 22:09 LiamDawe