Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to resetAttributes for specific attributes #15

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions backbone.trackit.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,62 @@
// Wrap Backbone.History.navigate so that in-app routing
// (`router.navigate('/path')`) can be intercepted with a
// confirmation if there are any unsaved models.

//Keep the un wrapped method so we can call it directly in the checkUrl method
var originalNavigate = Backbone.History.prototype.navigate;

Backbone.History.prototype.navigate = _.wrap(Backbone.History.prototype.navigate, function(oldNav, fragment, options) {
var prompt = getPrompt('unloadRouterPrompt', fragment, options);
if (prompt) {
if (confirm(prompt + ' \n\nAre you sure you want to leave this page?')) {
oldNav.call(this, fragment, options);
return oldNav.call(this, fragment, options);
}
} else {
return oldNav.call(this, fragment, options);
}
});


//To detect back button press with pushState navigation (not page loads)
//We need to intercept the Backbone.history internal popstate events

//First remove binding to the handler so we can update it (it doesn't update otherwise)
Backbone.$(window).off('popstate', Backbone.history.checkUrl).off('hashchange', Backbone.history.checkUrl);

//Now wrap the handler with out check
Backbone.history.checkUrl = _.wrap(Backbone.history.checkUrl, function(oldUrl, e) {
//at this point history.fragment is the fragment we are leaving, and history.getFragment is the fragment we are going to.
var currentFragment = Backbone.history.fragment;

var prompt = getPrompt('unloadRouterPrompt', currentFragment);
if (prompt) {
if (confirm(prompt + ' \n\nAre you sure you want to leave this page?')) {
return oldUrl.call(Backbone.history, e);
} else {
//As the fragment is the one we are leaving, calling the original navigate will do nothing, as the fragments match
//So we need to change the history fragment to the one in the URL, and then we can swap it back again
Backbone.history.fragment = Backbone.history.getFragment();
return originalNavigate.call(Backbone.history, currentFragment, {trigger:false});
}
} else {
oldNav.call(this, fragment, options);
return oldUrl.call(Backbone.history, e);
}
});

//Now Re bind to the wrapped event
Backbone.$(window).on('popstate', Backbone.history.checkUrl).on('hashchange', Backbone.history.checkUrl);




// Create a browser unload handler which is triggered
// on the refresh, back, or forward button.
window.onbeforeunload = function(e) {
return getPrompt('unloadWindowPrompt', e);
};



// Backbone.Model API
// ------------------

Expand Down Expand Up @@ -103,11 +142,23 @@
// Restores this model's attributes to
// their original values since tracking
// started, the last save, or last restart.
resetAttributes: function() {
resetAttributes: function(attrs) {

if (!this._trackingChanges) return;
this.attributes = this._originalAttrs;

if(!attrs) {
this.set(this._originalAttrs);
} else {
for (var i in attrs) {
var key=attrs[i];
delete this._unsavedChanges[key];
this.set(key, this._originalAttrs[key]);
}
}

this._resetTracking();
this._triggerUnsavedChanges();

return this;
},

Expand Down Expand Up @@ -189,4 +240,4 @@
return oldSync(method, model, options);
});

})();
})();