Is there a way to restore the original content / undo all changes of an element that had become an Inline-CKEditor?
There does not seem to exist a build-in function for that, see for example this ticket.
Some propose workarounds like a button with onclick javascript event, which reloads a page. Or saving the initial data inside of the editor and use javascript to replace the content with that on an event again. (Here is a thread concerning your request with the mentioned tricks.)
My solution:
After instantiating CKEditor I save the initial content with CKEDITOR.editor1.getData() to a custom variable CKEDITOR.editor1.firstSnapshot. Later when I want to restore it I write it back with CKEDITOR.editor1.setData(CKEDITOR.editor1.firstSnapshot);
At first I wanted to use getSnapshot() but however it always returned true, so that didn't work for me.
I want to share a different approach to problem. I'm using inline CKEditor, and have on blur event (when user unfocus ckeditor) which prompt option for saving content or rollback changes.
For case of rollback - i just put checkDirty() - function which check if instance has changes - in while loop, so undo executes in each true until ckeditor will be restored to initial state.
Code will look like this:
CKEDITOR.instances["editor"].on('blur', function (evt) {
if (confirm("Do you wish to roll back changes ?")) {
while (CKEDITOR.instances["editor"].checkDirty()) {
CKEDITOR.instances["editor"].execCommand('undo');
}
} else {
// do nothing!
}
})
Related
How do I determine the state of a textarea element (:focus, :hover, etc.) in Chrome?
For context, I'm trying to create a web application. After submitting the form on a previous page, the textarea of the new page automatically has the cursor, which I do not want to happen. I've tried to use the jQuery code below, which works in Firefox but not in Chrome:
element = $("#elementID");
if (element.is(":focus")) {
element.blur();
}
In Chrome, the code does not execute the element.blur() in the if statement (meaning the if statement fails). I've checked with a debugger and the element is successfully returned by the id in Chrome. So I think the problem is the state check statement.
I assume the problem is the element state and I want to investigate the element state at that time, preferably using Chrome developer tools. Unfortunately, I can't figure out how to check the current state. I can only figure out how to check if the state is equal to a specific state.
I've searched around but I am only finding answers like set :hover state which discuss how to set a specific state using Chrome dev tools and not how to determine the current state when it could be any state.
I realize that I could check for each possible state at that point in the JavaScript, but it seems like I am missing the correct way to check the state.
Here is a JSFiddle of my specific case. However, I'd be interested to also hear the answer to the general question about determining the current state of a textarea.
Thanks for the help!
It's most likely an order of operations issue - the logic is executed before the input's focus can be detected.
I've reproduced the issue here, and fixed it by putting the code into the window .load() event.
var $el = $('textarea');
// will not execute
if ($el.is(':focus')) {
$el.blur();
console.log('outside of window load');
}
// will execute
$(window).load(function() {
if ($el.is(':focus')) {
$el.blur();
console.log('inside window load');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea autofocus></textarea>
I have the 2 sets of code:
Saves the data
myapp.activeDataWorkspace.ProjectHandlerData.saveChanges();
2.Refreshes the page
window.location.reload();
is there a way to make both of these work together on one button, as currently when i click save, the browser recognizes the changes and the (are you sure you want to leave the page) message or something along those lines pops up..
cheers
This is for the HTML client, right?
Assuming that is the case:
saveChanges() is an asynchronous operation, so you'd want to do:
myapp.activeDataWorkspace.ProjectHandlerData.saveChanges().then(function () {
window.location.reload();
});
That way it will wait until it is finished saving the changes before it reloads the screen.
However, there is a smoother way to do it, at least from the user perspective it's smoother.
On the edit screen, leave the Save method out, let LightSwitch handle that. When the user clicks save, it will close the edit screen, and go back to where they were before. Using the options parameter of the showScreen method, we can change that behavior.
Change the method that calls the edit screen like this:
myapp.showEditProject(screen.Project, {
afterClosed: function (editScreen) {
myapp.showViewProject(editScreen.Project);
}
});
This way, after the edit screen is closed, and it has handled the save changes operation for you, the application will automatically navigate to the details view screen of the recently edited item.
If you are instead wanting to refresh the browse screen after adding a new entity:
myapp.showAddEditProject(null, {
beforeShown: function (addEditScreen) {
addEditScreen.Project = new myapp.Project();
},
afterClosed: function () {
screen.Projects.load();
}
});
Those two options, beforeShown and afterClosed, give you a lot of really cool abilities to influence the navigation in your application.
I have learnt that you can save from a add/edit window, and reload the main page you are going back to by doing the following:
For Example: (adding an order to an order screen)
click on your button to add the order
enter the details required.
hit your custom save button with your validation included.
before your commitChanges(); write in the following line: screen.OrderLine.OrderTable.details.refresh(); "This needs applying to your scenario"
when you return to your screen your details should have been updated (for example the total value now displays the correct value in my case)
hope this helps...
My Website contains Radio buttons and check boxes.
When a user selects one within a form and submits it, this state is stored, such that when the user returns to the page, it is loaded in the state as per user's previous selection.
Some of these check boxes have child elements, which when their parents are checked, alter their disabled attribute so that they can be interacted with.
I use a jQuery function to achieve this.
If a user has previously selected a parent to disabled child elements, when they return to the page, I need the function that enables the child elements to run.
I also need this function to run every time the user selects one during a browsing session.
I am currently able to achieve this by duplicating my jQuery function, once inside a When DOM Ready encapsulation, and once without this.
I suspect this is bad practice, am I correct, and if so how shoudld I be doing it?
To illustrate my point here, is an example:
//First the code for DOM ready:
//You can see it disables and unchecks boxes if they are not checked etc.
$(function() {
if ($('#parent').is(':checked')) {
$('#child1').removeAttr('disabled');
$('#child2').removeAttr('disabled');
} else {
$('#child1').attr('disabled', true);
$('#child1').removeAttr('checked');
$('#child2').attr('disabled', true);
$('#child2').removeAttr('checked');
}
});
//Now, the exact same function just without the DOM ready encapsulation.
if ($('#parent').is(':checked')) {
$('#child1').removeAttr('disabled');
$('#child2').removeAttr('disabled');
} else {
$('#child1').attr('disabled', true);
$('#child1').removeAttr('checked');
$('#child2').attr('disabled', true);
$('#child2').removeAttr('checked');
}
Thanks for your advice.
So basically you want the state of your page to persist?
You can store state in several places:
Clientside storage
Cookies
URL hash
Cookies is probably the easiest.
To correctly get the state to persist you have to keep track of the actual state.
So, whenever the state of the DOM changes, store that change. Then when a user opens the page, look in the cookie and restore the state (this is the on DOM ready part).
This is not always an easy thing to do, because states can be very complex. Imagine you have a foldable tree of somesort, you'd need to keep track of which nodes are expanded.
If you just want to keep track of some checkboxes, it shouldn't be too hard.
Yes, duplicate code like that is bad practice. So if your code does what it should, you can write it like down below.
I believe you're using a CMS that performs some Form Ajax Tasks in an Ajax Framework, right? (e.g. Drupal?) Otherwise I cannot imagine why this code does what you described it does.
(function($) {
var init = function() {
if ($('#parent').is(':checked')) {
$('#child1').removeAttr('disabled');
$('#child2').removeAttr('disabled');
} else {
$('#child1').attr('disabled', true);
$('#child1').removeAttr('checked');
$('#child2').attr('disabled', true);
$('#child2').removeAttr('checked');
}
}
//first call
init();
//second call
$(function() {
init();
});
})(jQuery);
I am working on chrome extension for facebook. If you use facebook, you know that when you scroll down to the bottom of the news feed/timeline/profile it shows more posts. The extension actually adds a button beside the "like" button. So I need to check if there are more posts to add that button to.
Right now to check if the page has been modified, I use setInterval(function(){},2000).
I want to run a function when the user clicks the button. But this function doesn't work if I put it outside (or even inside) setInterval() – The Koder just now edit
How can I check if the webpage has been modified WITHOUT using a loop?
Example:
$(document).ready(function(){
window.setInterval(function(){
$(".UIActionLinks").find(".dot").css('display','none');
$(".UIActionLinks").find(".taheles_link").css('display','none');
$(".miniActionList").find(".dot").css('display','none');
$(".miniActionList").find(".taheles_link").css('display','none');
//only this function doesn't work:
$(".taheles_link").click(function(){
$(".taheles_default_message").hide();
$(".taheles_saving_message").show();
});
//end
$(".like_link").after('<span class="dot"> · </span><button class="taheles_link stat_elem as_link" title="תגיד תכל´ס" type="submit" name="taheles" onclick="apply_taheles()" data-ft="{"tn":">","type":22}"><span class="taheles_default_message">תכל´ס</span><span class="taheles_saving_message">לא תכלס</span></button>');
$(".taheles_saving_message").hide();
}, 2000);
});
In the future, this extension will use AJAX, so setInterval() can make even more problems for me.
If I understand correctly you want to get a notification when the page's DOM changes. And you want to do this without using the setInterval() function.
As your problem lies within the attaching event handlers to elements that are created after the page has loaded, you might be interested in checking out the jquery.live event attachment technique. I think it will solve your issue.
In general you want the page to throw a mutation event. There is a mutation event spec that might be what you're looking for. Here are some links that might be useful.
http://tobiasz123.wordpress.com/2009/01/19/utilizing-mutation-events-for-automatic-and-persistent-event-attaching/
Detect element content changes with jQuery
$(document).ready(function(){
setInterval('fun()',5000);
fun();
});
function fun()
{
alert(11)
}
I'm using RadScheduler for my project. In the scheduler, I need a periodical update, so in my javascript, I set interval for a method that call rebind() on the RadScheduler for every 60 seconds. The problem is that, when my user open the advanced form, the rebind() method makes the form disappear. How can I detect AdvancedForm opening and closing event so that I can stop /restart the timer ?
Thank you in advance.
While there is an event for when the RadScheduler opens its Edit form, called OnClientFormCreated, there is not one for when the edit form closes. There are ways to do this though, but you have do add some additional code.
When you think about it there are several different items that can lead to the form closing - the user can click on the close icon at the top right (or left, depending on your orientation) of the window, they can click cancel, or they can hit save.
Keeping that in mind, we can take a look at this demo, which shows the Advanced Edit Form in action, and also has some JavaScript pre-written for us.
Within the schedulerFormCreated() function we can do the following:
function schedulerFormCreated(scheduler, eventArgs) {
// Create a client-side object only for the advanced templates
var mode = eventArgs.get_mode();
if (mode == Telerik.Web.UI.SchedulerFormMode.AdvancedInsert ||
mode == Telerik.Web.UI.SchedulerFormMode.AdvancedEdit) {
// Initialize the client-side object for the advanced form
var formElement = eventArgs.get_formElement();
var cancelButton = $("[id$='_CancelButton']");
cancelButton.on("click", formClosed);
var templateKey = scheduler.get_id() + "_" + mode;
....
And then we have the formClosed event:
function formClosed(eventArgs) {
}
in formClosed you can just create your logic for resuming the timer, while in schedulerFormCreated you can directly call the function that stops the timer right after that if-statement.
In case you're wondering what we're doing here we're simply grabbing an instance of the jQuery object representing the element with an id that ends with _CancelButton (we're not interested in the beginning part) and then just binding to the click event using the .on() jQuery function.
To get an instance of the save button you just have to use _UpdateButton, and for the close icon it is _AdvancedEditCloseButton. Keep in mind that any element that ends with these substrings will be selected, so if you want to be more specific I recommend inspecting the elements of your advanced form using FireBug or the Chrome Dev tools to get their ID and plug that into the selector above.
This should allow you to get the functionality you're looking for.