2013-04-22 77 views
3

Im新的解析,我想做一個登錄頁面。我有什麼是用戶名(不是電子郵件)和密碼這個工程。我也爲註冊有一個用戶名,密碼和電子郵件字段。 這也適用。我想要做的是添加一種解析方式,當用戶輸入電子郵件地址時向用戶發送電子郵件。我正在使用JavaScript SDK。如何使用解析密碼重置

<!DOCTYPE html> 
<html> 
<meta charset="utf-8"> 
<title>Parse JavaScript Todo App</title> 
<link href="css/todos.css" media="all" rel="stylesheet" type="text/css"/> 
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
<script src="js/underscore-1.1.6.js"></script> 
<script src="//www.parsecdn.com/js/parse-1.1.15.min.js"></script> 
<script src="js/todos.js"></script> 
<body> 

<!-- Todo App Interface --> 

<div id="todoapp"> 
    <div class="title"> 
    <h1>Parse Todos</h1> 
    </div> 

    <div class="content"> 
    </div> 
</div> 

<div id="credits"> 
    Powered by <a href="https://www.parse.com">Parse</a> using the <a href="https://www.parse.com/docs/js_guide">JavaScript SDK</a> 
</div> 

<!-- Templates --> 

<script type="text/template" id="login-template"> 
    <header id="header"></header> 
    <div class="login"> 
    <form class="login-form"> 
     <h2>Log In</h2> 
     <div class="error" style="display:none"></div> 
     <input type="text" id="login-username" placeholder="Username" /> 
     <input type="password" id="login-password" placeholder="Password" /> 
     <button>Log In</button> 
    </form> 

    <form class="signup-form"> 
     <h2>Sign Up</h2> 
     <div class="error" style="display:none"></div> 
     <input type="text" id="signup-username" placeholder="Username" /> 
     <input type="password" id="signup-password" placeholder="Create a Password" /> 
     <input type="email" id="signup-email" placeholder="Enter your Email" /> 
     <button>Sign Up</button> 
     <a href="passReset.htm">Forgot Password?</a> 
    </div> 
</script> 

<script type="text/template" id="manage-todos-template"> 
    <div id="user-info"> 
    Signed in as <%= Parse.User.current().get("username") %> (<a href="#" class="log-out">Log out</a>) 
    </div> 

    <div class="section"> 

    <header id="header"> 
     <input id="new-todo" placeholder="What needs to be done?" type="text" /> 
    </header> 

    <div id="main"> 
     <input id="toggle-all" type="checkbox"> 
     <label for="toggle-all">Mark all as complete</label> 

     <ul id="todo-list"> 
     <img src='images/spinner.gif' class='spinner' /> 
     </ul> 
    </div> 

    <div id="todo-stats"></div> 
    </div> 
</script> 

<script type="text/template" id="item-template"> 
    <li class="<%= done ? 'completed' : '' %>"> 
<div class="view"> 
    <input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %>> 
    <label class="todo-content"><%= content %></label> 
    <button class="todo-destroy"></button> 
</div> 
<input class="edit" value="<%= content %>"> 
    </li> 
</script> 

<script type="text/template" id="stats-template"> 
    <footer id="footer"> 
<span id="todo-count"><strong><%= remaining %></strong> <%= remaining == 1 ? 'item' : 'items' %> left</span> 
<ul id="filters"> 
    <li> 
    <a href="javascript:void(0)" id="all" class="selected">All</a> 
    </li> 
    <li> 
    <a href="javascript:void(0)" id="active">Active</a> 
    </li> 
    <li> 
    <a href="javascript:void(0)" id="completed">Completed</a> 
    </li> 
</ul> 
<button id="clear-completed">Clear completed (<%= done %>)</button> 
    </footer> 
</script> 

下一步是使上述工作的JavaScript。

$(function() { 

Parse.$ = jQuery; 

// Initialize Parse with your Parse application javascript keys 
Parse.initialize("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 
       "XXXXXXXXXXXXXXXXXXXXXXX"); 

// Todo Model 
// ---------- 

// Our basic Todo model has `content`, `order`, and `done` attributes. 
var Todo = Parse.Object.extend("Todo", { 
// Default attributes for the todo. 
defaults: { 
    content: "empty todo...", 
    done: false 
}, 

// Ensure that each todo created has `content`. 
initialize: function() { 
    if (!this.get("content")) { 
    this.set({"content": this.defaults.content}); 
    } 
}, 

// Toggle the `done` state of this todo item. 
toggle: function() { 
    this.save({done: !this.get("done")}); 
} 
}); 

// This is the transient application state, not persisted on Parse 
var AppState = Parse.Object.extend("AppState", { 
defaults: { 
    filter: "all" 
} 
}); 

// Todo Collection 
// --------------- 

var TodoList = Parse.Collection.extend({ 

// Reference to this collection's model. 
model: Todo, 

// Filter down the list of all todo items that are finished. 
done: function() { 
    return this.filter(function(todo){ return todo.get('done'); }); 
}, 

// Filter down the list to only todo items that are still not finished. 
remaining: function() { 
    return this.without.apply(this, this.done()); 
}, 

// We keep the Todos in sequential order, despite being saved by unordered 
// GUID in the database. This generates the next order number for new items. 
nextOrder: function() { 
    if (!this.length) return 1; 
    return this.last().get('order') + 1; 
}, 

// Todos are sorted by their original insertion order. 
comparator: function(todo) { 
    return todo.get('order'); 
} 

}); 

// Todo Item View 
// -------------- 

// The DOM element for a todo item... 
var TodoView = Parse.View.extend({ 

//... is a list tag. 
tagName: "li", 

// Cache the template function for a single item. 
template: _.template($('#item-template').html()), 

// The DOM events specific to an item. 
events: { 
    "click .toggle"    : "toggleDone", 
    "dblclick label.todo-content" : "edit", 
    "click .todo-destroy" : "clear", 
    "keypress .edit"  : "updateOnEnter", 
    "blur .edit"   : "close" 
}, 

// The TodoView listens for changes to its model, re-rendering. Since there's 
// a one-to-one correspondence between a Todo and a TodoView in this 
// app, we set a direct reference on the model for convenience. 
initialize: function() { 
    _.bindAll(this, 'render', 'close', 'remove'); 
    this.model.bind('change', this.render); 
    this.model.bind('destroy', this.remove); 
}, 

// Re-render the contents of the todo item. 
render: function() { 
    $(this.el).html(this.template(this.model.toJSON())); 
    this.input = this.$('.edit'); 
    return this; 
}, 

// Toggle the `"done"` state of the model. 
toggleDone: function() { 
    this.model.toggle(); 
}, 

// Switch this view into `"editing"` mode, displaying the input field. 
edit: function() { 
    $(this.el).addClass("editing"); 
    this.input.focus(); 
}, 

// Close the `"editing"` mode, saving changes to the todo. 
close: function() { 
    this.model.save({content: this.input.val()}); 
    $(this.el).removeClass("editing"); 
}, 

// If you hit `enter`, we're through editing the item. 
updateOnEnter: function(e) { 
    if (e.keyCode == 13) this.close(); 
}, 

// Remove the item, destroy the model. 
clear: function() { 
    this.model.destroy(); 
} 

}); 

// The Application 
// --------------- 

// The main view that lets a user manage their todo items 
var ManageTodosView = Parse.View.extend({ 

// Our template for the line of statistics at the bottom of the app. 
statsTemplate: _.template($('#stats-template').html()), 

// Delegated events for creating new items, and clearing completed ones. 
events: { 
    "keypress #new-todo": "createOnEnter", 
    "click #clear-completed": "clearCompleted", 
    "click #toggle-all": "toggleAllComplete", 
    "click .log-out": "logOut", 
    "click ul#filters a": "selectFilter" 
}, 

el: ".content", 

// At initialization we bind to the relevant events on the `Todos` 
// collection, when items are added or changed. Kick things off by 
// loading any preexisting todos that might be saved to Parse. 
initialize: function() { 
    var self = this; 

    _.bindAll(this, 'addOne', 'addAll', 'addSome', 'render', 'toggleAllComplete', 'logOut', 'createOnEnter'); 

    // Main todo management template 
    this.$el.html(_.template($("#manage-todos-template").html())); 

    this.input = this.$("#new-todo"); 
    this.allCheckbox = this.$("#toggle-all")[0]; 

    // Create our collection of Todos 
    this.todos = new TodoList; 

    // Setup the query for the collection to look for todos from the current user 
    this.todos.query = new Parse.Query(Todo); 
    this.todos.query.equalTo("user", Parse.User.current()); 

    this.todos.bind('add',  this.addOne); 
    this.todos.bind('reset', this.addAll); 
    this.todos.bind('all',  this.render); 

    // Fetch all the todo items for this user 
    this.todos.fetch(); 

    state.on("change", this.filter, this); 
}, 

// Logs out the user and shows the login view 
logOut: function(e) { 
    Parse.User.logOut(); 
    new LogInView(); 
    this.undelegateEvents(); 
    delete this; 
}, 

// Re-rendering the App just means refreshing the statistics -- the rest 
// of the app doesn't change. 
render: function() { 
    var done = this.todos.done().length; 
    var remaining = this.todos.remaining().length; 

    this.$('#todo-stats').html(this.statsTemplate({ 
    total:  this.todos.length, 
    done:  done, 
    remaining: remaining 
    })); 

    this.delegateEvents(); 

    this.allCheckbox.checked = !remaining; 
}, 

// Filters the list based on which type of filter is selected 
selectFilter: function(e) { 
    var el = $(e.target); 
    var filterValue = el.attr("id"); 
    state.set({filter: filterValue}); 
    Parse.history.navigate(filterValue); 
}, 

filter: function() { 
    var filterValue = state.get("filter"); 
    this.$("ul#filters a").removeClass("selected"); 
    this.$("ul#filters a#" + filterValue).addClass("selected"); 
    if (filterValue === "all") { 
    this.addAll(); 
    } else if (filterValue === "completed") { 
    this.addSome(function(item) { return item.get('done') }); 
    } else { 
    this.addSome(function(item) { return !item.get('done') }); 
    } 
}, 

// Resets the filters to display all todos 
resetFilters: function() { 
    this.$("ul#filters a").removeClass("selected"); 
    this.$("ul#filters a#all").addClass("selected"); 
    this.addAll(); 
}, 

// Add a single todo item to the list by creating a view for it, and 
// appending its element to the `<ul>`. 
addOne: function(todo) { 
    var view = new TodoView({model: todo}); 
    this.$("#todo-list").append(view.render().el); 
}, 

// Add all items in the Todos collection at once. 
addAll: function(collection, filter) { 
    this.$("#todo-list").html(""); 
    this.todos.each(this.addOne); 
}, 

// Only adds some todos, based on a filtering function that is passed in 
addSome: function(filter) { 
    var self = this; 
    this.$("#todo-list").html(""); 
    this.todos.chain().filter(filter).each(function(item) { self.addOne(item) }); 
}, 

// If you hit return in the main input field, create new Todo model 
createOnEnter: function(e) { 
    var self = this; 
    if (e.keyCode != 13) return; 

    this.todos.create({ 
    content: this.input.val(), 
    order: this.todos.nextOrder(), 
    done: false, 
    user: Parse.User.current(), 
    ACL:  new Parse.ACL(Parse.User.current()) 
    }); 

    this.input.val(''); 
    this.resetFilters(); 
}, 

// Clear all done todo items, destroying their models. 
clearCompleted: function() { 
    _.each(this.todos.done(), function(todo){ todo.destroy(); }); 
    return false; 
}, 

toggleAllComplete: function() { 
    var done = this.allCheckbox.checked; 
    this.todos.each(function (todo) { todo.save({'done': done}); }); 
} 
}); 

var LogInView = Parse.View.extend({ 
events: { 
    "submit form.login-form": "logIn", 
    "submit form.signup-form": "signUp", 
    "submit form.reset-form": "reset" 
}, 

el: ".content", 

initialize: function() { 
    _.bindAll(this, "logIn", "signUp","reset"); 
    this.render(); 
}, 

logIn: function(e) { 
    var self = this; 
    var username = this.$("#login-username").val(); 
    var password = this.$("#login-password").val(); 

    Parse.User.logIn(username, password, { 
    success: function(user) { 
     new ManageTodosView(); 
     self.undelegateEvents(); 
     delete self; 
    }, 

    error: function(user, error) { 
     self.$(".login-form .error").html("Invalid username or password. Please try again.").show(); 
     this.$(".login-form button").removeAttr("disabled"); 
    } 
    }); 

    this.$(".login-form button").attr("disabled", "disabled"); 

    return false; 
}, 

signUp: function(e) { 
    var self = this; 
    var username = this.$("#signup-username").val(); 
    var password = this.$("#signup-password").val(); 
    var email = this.$("#signup-email").val(); 

    Parse.User.signUp(username, password,{email:email, ACL: new Parse.ACL() }, { 
    success: function(user) { 
     new ManageTodosView(); 
     self.undelegateEvents(); 
     delete self; 
    }, 

    error: function(user, error) { 
     self.$(".signup-form .error").html(error.message).show(); 
     this.$(".signup-form button").removeAttr("disabled"); 
    } 
    }); 

    this.$(".signup-form button").attr("disabled", "disabled"); 

    return false; 
}, 

render: function() { 
    this.$el.html(_.template($("#login-template").html())); 
    this.delegateEvents(); 
} 
}); 

// The main view for the app 
var AppView = Parse.View.extend({ 
// Instead of generating a new element, bind to the existing skeleton of 
// the App already present in the HTML. 
el: $("#todoapp"), 

initialize: function() { 
    this.render(); 
}, 

render: function() { 
    if (Parse.User.current()) { 
    new ManageTodosView(); 
    } else { 
    new LogInView(); 
    } 
} 
}); 

var AppRouter = Parse.Router.extend({ 
routes: { 
    "all": "all", 
    "active": "active", 
    "completed": "completed" 
}, 

initialize: function(options) { 
}, 

all: function() { 
    state.set({ filter: "all" }); 
}, 

active: function() { 
    state.set({ filter: "active" }); 
}, 

completed: function() { 
    state.set({ filter: "completed" }); 
} 
}); 

var state = new AppState; 

new AppRouter; 
new AppView; 
Parse.history.start(); 
}); 

我知道的

Parse.User.requestPasswordReset("[email protected]", { 
success: function() { 
// Password reset request was sent successfully 
}, 
error: function(error) { 
// Show the error message somewhere 
alert("Error: " + error.code + " " + error.message); 
} 
}); 

,但無法弄清楚如何得到它的工作。

在此先感謝。

Thomas。

編輯: 基本上我問的是我如何去設置一個重置/忘記密碼鏈接/按鈕在解析。

我現在有一個電子郵件地址和一個按鈕的輸入。當點擊按鈕時,我想讓Parse向用戶發送一封電子郵件,以允許用戶更改密碼。

我已經改變了上面的代碼,並與更多的知識,我認爲以下

reset: function (e) { 
     var self = this; 
     var email = this.$("reset-email").val(); 

     Parse.User.requestPasswordReset({email:email}, { 
      success: function() { 
       new LogInView(); 
       self.undelegateEvents(); 
       delete self; 
      }, 
      error: function(error) { 
       // Show the error message somewhere 
       self.$(".reset-form .error").html(error.message).show(); 
       this.$(".reset-form button").removeAttr("disabled"); 
      } 

     }); 

     this.$(".reset-form button").attr("disabled", "disabled"); 

     return false; 
    }, 

我與得到的錯誤是我縮小了問題:無效的電子郵件{}

對不起這樣一個馬虎的帖子我完全失去了。

最後編輯:

我得到了上述工作的問題得到回答的解析論壇 https://www.parse.com/questions/parseuserrequestpasswordreset

+0

什麼不工作 – Gabe 2013-04-22 16:04:51

+0

你能簡化嗎?有很多代碼。請使用[jsfiddle](http://jsfiddle.net)。 – Dom 2013-04-22 16:28:37

+0

你能否詳細說明哪些方法無效? – 2013-04-22 16:56:28

回答

1

首先,你可以檢查如果給定的電子郵件是與助手Java腳本功能有效,然後進行請求與Parse.User.requestPasswordReset

function checkEmail(email) 
{ 
    var atpos = email.indexOf("@"); 
    var dotpos = email.lastIndexOf("."); 

    if (atpos<1 || dotpos<atpos+2 || dotpos+2>=email.length) 
    { 
     return false; 
    } 
    return true; 
} 

function resetPassword() 
{   
    var email = document.forms["resetpassword"]["email"].value; 
    var emailIsValid = checkEmail(email); 

    if (!emailIsValid) 
    { 
     window.alert("Not a valid e-mail address"); 
     return false; 
    } 

    Parse.User.requestPasswordReset(email, { 
       success:function() { 
        window.alert("Password reset link has been sent to "+ email); 
        return true; 
       }, 
       error:function(error) { 
        window.alert(error.message); 
        return false; 
       } 
      }); 
}