Retrieving strings in Parse - javascript

I am trying to retrieve two strings from my Parse Customers class. I want to compare these strings (usernameAdmin, and passwordAdmin respectively) with the input field entered by the user, and if they matched it will take them to a specific page.
I am taking this approach for a particular reason, and would appreciate feedback.
$scope.logIn = function(form) {
var Customer = Parse.Object.extend("Customers");
parseAdminUsername = Customer.get('usernameAdmin');
parseAdminPassword = Customer.get('passwordAdmin');
if (form.lusername == parseAdminUsername && form.lpassword == parseAdminPassword) {
window.location = 'adminSelect.php'
} else {
alert('error');
}
};
The html code looks as follow:
<form role="form" ng-show="scenario == 'Sign up'">
<h4 id="wrongCredentials"></h4>
<input id="signupformItem" ng-model="user.lusername" type="email" name="email" placeholder="Email Address"> <br>
<input id="signupformItem" ng-model="user.lpassword" type="password" name="password" placeholder=" Password"> <br>
<br>
<button id="signupbuttonFinal" ng-click="logIn(user)" class="btn btn-danger"> Sign In</button>
</form>
I receive the following error on console:
undefined is not a function
at Object.$scope.logIn
below is the line
parseAdminUsername = Customer.get('usernameAdmin');

You are better off using Parse in built users instead of creating a separate object and then you would use Parse.User.logIn.
If you were to use your table instead. Customer.get('usernameAdmin') is used to return a field after you have performed a query to return records/s. You are best to perform a find query to check the username and password like so:
var Customer = Parse.Object.extend("Customers");
var query = new Parse.Query(Customer);
query.equalTo("usernameAdmin", form.lusername);
query.equalTo("passwordAdmin", form.lpassword);
query.find({
success: function(results) {
if (results.length > 0) {
window.location = 'adminSelect.php';
}
},
error: function(error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
}
});
I'd recommend not to use window and instead $window so that you can unit test your code. Better yet use angular routing and create a Single page app.

Related

The form does not work correctly when sent

I wrote the code for a form validation.
Should work like this:
It checks (allLetter (uName)) and if it's true, then validate the next input.
If any validation is false then it should return false.
My problem is that if both validations are true, then everything is exactly false and the form is not sent.
If I set true in formValidation (), if at least one check false, the form should not be sent.
<form name='registration' method="POST" onSubmit="return formValidation();">
<label for="userName">Name:</label>
<input type="text" name="userName" size="20" />
<label for="userPhone">Phone:</label>
<input type="text" name="userPhone" size="20" />
<input type="submit" name="submit" value="Submit" />
</form>
function formValidation() {
var uName = document.registration.userName;
var uPhone = document.registration.userPhone;
if(allLetter(uName)) {
if(phone(uPhone)) {}
}
return false;
}
function phone(uPhone){
var digts = /^[0-9]+$/;
if(uPhone.value.match(digts)){
return true;
} else {
alert('Phone must have only digits');
uPhone.focus();
return false;
}
}
function allLetter(uName) {
var letters = /^[A-Za-z]+$/;
if(uName.value.match(letters)) {
return true;
}else{
alert('Username must have alphabet characters only');
uName.focus();
return false;
}
}
First, you are using a 20+ year old way to gain references to your elements (document.form.formElementNameAttributeValue) and, while this still works for legacy reasons, it doesn't follow the standard Document Object Model (DOM) API.
Next, you've broken up your validation tests into different methods (and that's certainly not a bad idea for reusability), but in this case is is adding a ton of code that you just don't need. I've always found it's best to start simple and get the code working, then refactor it.
You're also not using the <label> elements correctly.
One other point, your form is set to send its data via a POST request. POST should only be used when you are changing the state of the server (i.e. you are adding, editing or deleting some data on the server). If that's what your form does, you'r fine. But, if not, you should be using a GET request.
Lastly, you are also using a 20+ year old technique for setting up event handlers using inline HTML event attributes (onsubmit), which should no longer be used for many reasons. Additionally, when using this technique, you have to use return false from your validation function and then return in front of the validation function name in the attribute to cancel the event instead of just using event.preventDefault().
So, here is a modern, standards-based approach to your validation:
// Get references to the elements you'll be working with using the DOM API
var frm = document.querySelector("form[name='registration']");
var user = document.getElementById("userName");
var phone = document.getElementById("userPhone");
// Set up event handlers in JavaScript, not with HTML attributes
frm.addEventListener("submit", formValidation);
// Validation function will automatically be passed a reference
// the to event it's associated with (the submit event in this case).
// As you can see, the function is prepared to recieve that argument
// with the "event" parameter.
function formValidation(event) {
var letters = /^[A-Za-z]+$/;
var digts = /^[0-9]+$/;
// This will not only be used to show any errors, but we'll also use
// it to know if there were any errors.
var errorMessage = "";
// Validate the user name
if(user.value.match(letters)) {
// We've already validated the user name, so all we need to
// know now is if the phone is NOT valid. By prepending a !
// to the test, we reverse the logic and are now testing to
// see if the phone does NOT match the regular expression
if(!phone.value.match(digts)) {
// Invalid phone number
errorMessage = "Phone must have only digits";
phone.focus();
}
} else {
// Invalid user name
errorMessage = "Username must have alphabet characters only";
user.focus();
}
// If there is an error message, we've got a validation issue
if(errorMessage !== ""){
alert(errorMessage);
event.preventDefault(); // Stop the form submission
}
}
<!-- 20 is the default size for input elements, but if you do
want to change it do it via CSS, not HTML attributes -->
<form name='registration' method="POST">
<!-- The for attribute of a label must be equal to the id
attribute of some other element, not the name attribute -->
<label for="userName">Name:</label>
<input type="text" name="userName" id="userName">
<label for="userPhone">Phone:</label>
<input type="text" name="userPhone" id="userPhone">
<input type="submit" name="submit" value="Submit">
</form>

Parse Data and Javascript/HTML Form

I'm using the Data module from Parse. I'm using HTML to create an email form. I use Javascript to get the form data (email), and then generate a username from the email address. This information is then saved to the Parse database.
Here's the HTML form code:
<form method="post" class="center">
<input id="email" name="email" type="email" placeholder="Type your email to create a Mail Link" />
<button id="submit" onclick="formSubmit();">Create</button>
</form>
Here's the Javascript:
function formSubmit() {
var emailValue = document.getElementById("email").value;
var userValue = emailValue.substr(0, emailValue.indexOf('#'));
Parse.initialize("---KEY---", "---KEY---");
var Users = Parse.Object.extend("Users");
var users = new Users();
users.save({username: userValue}).then(function(object) {
alert("Saved user");
});
users.save({email: emailValue}).then(function(object) {
alert("Saved email");
});
}
The problem is that the console is showing that the values are saved, however the data isn't saved into Parse.
Any ideas would be greatly appreciated!
In can make button a simple button, no need to change the button to a button as mention in the link you've mentioned, your code'll work fine.
You've written .then() method after saving the user data, but actually it's called to run the callbacks when the promise is fulfilled.
But here you're using simple Parse.Object, so either you've to use Parse.Promise, or if you want to use only simple Parse.Object when something like:-
users.save({
username: "Jake Cutter"
}, {
success: function(userObject) {
alert('The save was successful');
},
error: function(userObject, error) {
// The save failed. Error is an instance of Parse.Error.
// Do something if you want to do on error
}
});
For details you can check:-
https://www.parse.com/docs/js/symbols/Parse.Object.html#save
https://www.parse.com/docs/js/symbols/Parse.Promise.html#then
Okay, I awarded Indra the bounty, but here's the full answer for more context. This is an annoying problem, but you can solve it.
First, the form should use onsubmit.
<form method="post" onsubmit="formSubmit();">
Second, your function should use Indra's method to save data. But, you need event.preventDefault(); before it.
event.preventDefault();
userList.save({
username: "Peter Adams"
}, {
success: function(userList) {
alert('Success');
},
error: function(userList, error) {
alert('Failed to create new object, with error code: ' + error.message);
}
});
You can use jquery to store the form values and create a sub class of your parse class and also a new parse object to store the values in parse.
Example:
<form id="contact-form" >
First name:<br>
<input type="text" name="firstname" id="firstname">
<br>
Last name:<br>
<input type="text" name="lastname" id="lastname">
email:<br>
<input type="text" name="email" id="email">
<input type="submit" value="Get Access" />
</form>
Javascript code:
Parse.initialize("--KEY--", "--KEY--");
var Subscribers = Parse.Object.extend('Subscribers'); //create local parse object from your Parse class
$('#contact-form').submit(function(e) {
//on form submit
e.preventDefault();
//get data from form
var data = {
firstname: $("#firstname").val(),
lastname: $("#lastname").val(),
email: $("#email").val()
};
//create new Parse object
subscribers = new Subscribers();
//match the key values from the form, to your parse class, then save it
subscribers.save(data, {
//if successful
success: function(parseObj) {
alert(subscribers.get('firstname') + " " + subscribers.get('lastname') + " " + subscribers.get('email') + " saved to Parse.")
}
,
error: function(parseObj, error) {
console.log(parseObj);
console.log(error);
}
});
});

gs function passing 'undefined' to jsfunction (Dynamic Form Update)

I'm having a problem with a dynamically updated form in Google Apps Script. The form is in an HTML template (say index.html) as follows:
<form id="login">
<p>Enter username and password below, or use the links to the right for more services:</p>
<input type="text" placeholder="username" id="username" name="username" />
<input type="password" placeholder="password" id="password" name="password"/>
<input type="button" value="Login" onclick="google.script.run.withSuccessHandler(form_login).processForm(this.parentNode)" id="login_button" />
</form>
There is also a div designated for the output:
<div id="output">test value</div>
And a javascript function to update said div:
function form_login(msg) {
var div = document.getElementById('output');
div.innerHTML = div.innerHTML+msg;
}
The function within the gs file that deals with this is as follows:
function form_login(formObject) {
//connect to users spread sheet
var userssheet = SpreadsheetApp.openById("SPREADSHEET-ID-STRING");
//get variables handed over and existing on page
var username = formObject.username;
var pass = formObject.password;
//get where data range in spreadsheet
var searchrange = userssheet.getActiveSheet().getDataRange();
//check if username exists and return password (change to check if password and username are correct and)
if (find(username, searchrange)) {
var enteredpassword = searchrange.getCell(find(username, searchrange),4).getValue();
var message = (username+" Found! Password is "+enteredpassword); //get password value
} else {
var message = (username+" Not Found!");
}
//check if password entered is correct
if (enteredpassword) {
if (enteredpassword==pass) {
message = message + "Correct Password";
} else {
message = message + "Incorrect Password";
}
}
return message;
}
(Obviously I'm still building the functionality).
The problem, which will probably turn out to be an obvious oversight on my part, is with the gs function. Whatever it returns is outputted as 'undefined' into the HTML. Even when i change return message; in the function to something like return "hello";, I still get undefined appended to the output div (I tried using toString(); in the javascript function, but that didn't change anything).
Any ideas? What am I missing?
Found out what the problem was, and as I assumed, it was a mistake on my side. The button action (which I copied then edited from developers.google.com/apps-script/guides/html/communication#forms was:
onclick="google.script.run
.withSuccessHandler(form_login)
.processForm(this.parentNode)"
The problem was that I forgot to change processForm to the new gs function name: form_login. I changed it (to do_form_login, and changed the function name in the code to avoid confusion with the javascript code), and it worked like a charm (:
Note: Thanks Sandy for the help, you made me scrutinize the code and find out this mistake.

Cannot trap undefined error in input form submission

Using parse.com and javascript/jquery.
The below code should capture the input from the user in the "friendsearch" input box.
Once the submit button is clicked, it should query the parse.com backend and find out if the user exists. At the moment I keep getting "undefined" returned in "friendName" which I cannot spot why or what is causing the error?
<form class="Find Friend">
<div class="error" style="display:none"></div>
<input type="text" id="friendsearch" placeholder="Find Friend" class="input-field" required/>
<button type="submit" class="btn btn-login">Find</button>
</form>
var friendName;
$('#friendsearch').on('keyup', function(e) {
friendName = $(this).val();
});
var friendFinder = Parse.Object.extend("_User");
var query = new Parse.Query(Parse.User);
query.equalTo("username", friendName); // find users that match
query.find({
success: function(friend) {
alert(friendName);
},
error: function (error) {
//Show if no user was found to match
alert("Error: " + error.code + " " + error.message);
}
});
Ok, I revised your code so that the friendName variable actually contains the contents of the input box on your form. The problem was that your original code was trying to get access to the contents of your input box before it was even loaded into the DOM.
Try this for your HTML:
<form class="Find Friend">
<div class="error" style="display:none"></div>
<input type="text" id="friendsearch" placeholder="Find Friend" class="input-field" />
<button id="find_button" type="submit" class="btn btn-login">Find</button>
</form>
And this for your javascript:
var friendName;
function findFriend(){
friendName = $('#friendsearch').val();
alert(friendName);
var friendFinder = Parse.Object.extend("_User");
var query = new Parse.Query(Parse.User);
query.equalTo("username", friendName); // find users that match
query.find({
success: function(friend) {
alert(friendName);
},
error: function (error) {
//Show if no user was found to match
alert("Error: " + error.code + " " + error.message);
}
});
}
$('#find_button').click(function(e){
findFriend();
});
I updated the live jsFiddle example here: http://jsfiddle.net/LWA48/2/
In the jsFiddle example, the Parse object prints {"error": "Please use POST request"} when you click the button, but at least your friendName variable contains the name you typed in the box! Hopefully, this can take you the rest of the way.
I believe the problem is where you're assigning friendName = $(this).val();
Try using e.target to get a reference to the value currently in the text input box. I'm not sure if it's e.target off the top of my head but I'm fairly certain that you want a property contained inside the e argument.
Try $(e.target).val() or $(e.currentTarget).val() something like that instead of $(this).val();
What I also like to do when I'm trying to figure out why something isn't being set properly is to set a breakpoint in the chrome debugger. In this case, you can put 'debugger' in your code where you want the browser to break on. So in your example, you could write this:
$('#friendsearch').on('keyup', function(e) {
debugger
friendName = $(this).val();
});
And in your Chrome Dev Tools you can inspect the value of e and determine what properties and values are available.

Validate Dynamic Object using can.Map.Validate

I was looking for form validation in CanJS and came to know about can.Map.Validate plugin http://canjs.com/docs/can.Map.validations.prototype.errors.html
In the below example taken from the documentation itself, we need to give the properties of the object like 'dueDate' before the creating of the object itself
Task = can.Map.extend({
init : function(){
this.validatePresenceOf("dueDate")
}
},{});
var task = new Task(),
errors = task.errors()
Now my requirement is I want to build a Map which checks whether my field attribute is empty and returns me a suitable error. But the problem is, there are multiple forms on my page and formObject gets generated dynamically. Now in the above scenario before the creation of object itself, you need to allot the property in init method on which validation needs to be performed. It is not good for my requirement as the object is getting build and properties are unknown before the creation of the object. I searched over the web a lot but unable to crack it.
Providing the code for better understanding
EJS File: login.ejs
<form id="registrationForm" name="registrationForm" method="POST">
<input type="text" name="userName" placeholder="UserName" class="inputFieldStyle"></input>
<input type="password" name="password" placeholder="Password" class="inputFieldStyle"></input>
<input type="password" name="confirmPassword" placeholder="Confirm Password" class="inputFieldStyle"></input>
<input type="email" name="email" placeholder="Email" class="inputFieldStyle"></input>
<input type="button" name="registrationSubmit" value="Register" class="registrationLoginButton"></input>
<input type="hidden" name="formType" value="registration"></input>
</form>
<form id="loginForm" name="loginForm" method="POST">
<input type="userName" name="userName" placeholder="UserName or Email" class="inputFieldStyle"></input>
<input type="password" name="password" placeholder="Password" class="inputFieldStyle"></input>
<input type="button" name="loginSubmit" value="Login" class="registrationLoginButton"></input>
<input type="hidden" name="formType" value="login"></input>
</form>
Controller:
var LoginController=can.Control({
defaults: {view:'login.ejs'}
},
{
init:function(element,options)
{
var fragment=can.view(this.options.view);
this.element.html(fragment)
},
'input[name="registrationSubmit"],input[name="loginSubmit"] click':function(el,ev)
{
ev.preventDefault();
var formDOMObject=el.parent('form');
var formValueObject=can.deparam(formDOMObject.serialize());
/*Need to validate formValueObject. Problem is either formDOMObject can be resgitrationForm or LoginForm. Now both have different properties, So i cannot provide predefined properties in init method */
}
});
Is there any way of validating the dynamic object properties using ca.Map.Validate plugin?
How can I access the instance object passed inside the init method?
Thanks in advance :)
Seems like what you want is to make temporary, throwaway classes with validations that are built from an existing object, which can then be observed for errors.
Here's an example showing that the validations are observable and change dynamically with the source can.Map
can.Map("DynamicFormValidator", {
newInstance : function(data) {
var cls = this.extend();
can.each(data.serialize(), function(val, key) {
cls.validatePresenceOf(key);
});
//cls.prototypes.data = data;
return can.Map.newInstance.call(cls, data);
}
}, {
init : function(data) {
var that = this;
this.attr("data", data);
this.bind("change", function(ev, attr, how, newVal) {
if(attr.indexOf('data.') === 0) {
that.attr(attr.substr(5), newVal);
}
})
}
, computed_errors : can.compute(function() { return this.errors(); })
});
See it in action at
http://jsfiddle.net/air_hadoken/8rK2n/2/
You need to make ,can.map (or compute) for the state and mustache helpers to reflect the state in the dom for this I use an approach from sebastion proto http://sporto.github.io/blog/2014/03/04/form-validations-with-canjs/
and here is the jsfiddle
can.fixture({
"GET contacts":function(){
return [{'fname':'Cherif','lname':'BOUCHELAGHEM'}]
}
})
can.Model.extend('Contact',{
init:function(){
this.validatePresenceOf(['fname','lname']);
},
findAll: 'GET contacts'
},{});
can.Control.extend('ContactForm',{
init:function(el,options){
this.contact=new Contact();
this.errors=new can.Map({});
this.element.html(can.view('validation',contact:this.contact, errors:this.errors}));
},
'form submit': function () {
var errors = this.contact.errors();
this.errors.attr(errors, true);
return false;
}
});
Mustache.registerHelper('showErrors', function (errors, prop) {
var attr = errors.attr(prop);
if (attr) {
return prop + ' ' + attr[0];
} else {
return '';
}
});
new ContactForm('#val');

Categories