Meteor - Form not being inserted into collection when submitted - javascript

I am attempting to store information that is put into this form with meteor:
<form class="form-group" id="lost_form">
<label for="item_name">Type</label>
<input id="item_name" class="form-control" type="text" placeholder="What is the item? Ex: Water bottle" required/>
<label for="item_brand">Brand</label>
<input id="item_brand" class="form-control" type="text" placeholder="What brand is the item? Ex: Nalgene" required/>
<label for="item_desc">Description</label>
<input id="item_desc" class="form-control" type="text" placeholder="Describe the item. Ex: Green, name on bottom" required/>
<label for="item_loc">Location</label>
<input id="item_loc" class="form-control" type="text" placeholder="Where did you have it last? Ex: Main common room"/>
<label for="item_date">Date Missing</label>
<input id="item_date" class="form-control" type="date"/>
<br>
<input id="submit_lost_form" class="btn btn-primary btn-block" type="submit" value="Submit" />
</form>
The JS I am using to put it into a collection is below:
LostItems = new Meteor.Collection('lostitems');
Meteor.methods({
'insertItem': function(iname, ibrand, idesc, iloc, idate){
LostItems.insert({
user: Meteor.user(),
name: iname,
brand: ibrand,
description: idesc,
location: iloc,
date: idate
})
}
});
if (Meteor.isClient) {
Template.lost_form.events({
'submit form': function (event) {
event.preventDefault();
var itemName = event.target.item_name.value;
var itemBrand = event.target.item_brand.value;
var itemDesc = event.target.item_desc.value;
var itemLoc = event.target.item_loc.value;
var itemDate = event.target.item_date.value;
Meteor.call('insertItem', itemName, itemBrand, itemDesc, itemLoc, itemDate);
}
});
}
But whenever I submit the form, nothing happens. There are no errors in the developer console, or on the meteor console, and when I do LostItems.find().fetch() there is nothing there.
I am new to meteor so this is probably a really dumb question, but I appreciate any help!

You might need to use Meteor.userId() instead of Meteor.user() in your call to insert(). Without the autopublish package, the doc returned by Meteor.user() can be different on the client than it is on the server (for security reasons). That would mean that the client-side insert into your mini-mongodb and the server-side insert into the real mongodb could conflict with each other. I would expect the client-side insert to be ignored after the result of the server-side insert propagates back to the client. I'm not sure why it isn't being replaced by the server-side insert though. What does LostItems.find().fetch() return when you run it on the server (e.g. in meteor shell)?

I fixed the issue by adding insecure, yogiben:autoform-tags and autopublish to my package list. I think autopublish is the one that made the difference. I am sure there is a better way to do this and that this probably has some security flaws to it, but this is not a big project and it isn't storing sensitive data, so this will work for now.

Related

jquery post leaving out JSON values on post

I have read a few similar questions, but no one seems to have asked about this specifically. I am sending a JSON object I know has the properties I want, but one of them disappears fromt he body durint a $.post() request. I have the following form, I know that the DOM ids are correct and that their .val()s are there, because I console log the json object before sending it as a parameter to authenticate(user):
Here is an example for completeness:
const authenticate = (user) => {
console.log(user);
$.post("http://localhost:8080/auth",user)
.done(
(data,status,xhr) => {
console.log(data.user+"---user---");
}
).fail(xhr => console.log(JSON.parse(xhr.responseText).message));
}
}
$('#login_form').on('submit', event => {
event.preventDefault();
console.log({email:$('#username').val(),password:$('#password').val()});
authenticate({email:'user#email.com',password:$('#password').val()});
});
<form id="login_form" onsubmit="false">
<label for="username">Email</label>
<input id="username" name="username" placeholder="jimmy#john.com" type="email" class="form-control" required autofocus>
<label for="password">Password</label>
<input id="password" name="password" placeholder="Password" type="password" class="form-control" required>
<button type="submit" class="btn btn-primary btn-lg btn-block" style="margin-top:10px">Log in</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
{email:$('#username').val(),password:$('password').val()}
But I have tried replacing them with string values of a real user, and I can see that the .val()s are there in the console log. What I am seeing in the beowser's dev tools is that the post request is sending this as the body:
{email:"",password:"password"}
where it definitely is passing the right object, but the email field is either empty or a blank string. I have tried stringifying the object and sending it as a template literal, and I have tried setting the $.post() datatype to JSON, but nothing seems to make it parse the email, so I get a 400 back from the server's authenticator for missing credentials. I have exhausted every path I know to try, and not found someone with this issue on Google. Pls halp, and as always, thanks!
here is the working example, seems you were using same name for const & function
$('#login_form').on('submit', event => {
event.preventDefault();
authenticate({
email: $('#username').val(),
password: $('#password').val()
});
});
function authenticate(user){
console.log(user);
$.post("http://localhost:8080/auth", user)
.done(
(data, status, xhr) => {
console.log(data.user + "---user---");
}
).fail(xhr => console.log(JSON.parse(xhr.responseText).message));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="login_form" onsubmit="false">
<label for="username">Email</label>
<input id="username" name="username" placeholder="jimmy#john.com" type="email" class="form-control" required autofocus>
<label for="password">Password</label>
<input id="password" name="password" placeholder="Password" type="password" class="form-control" required>
<button type="submit" class="btn btn-primary btn-lg btn-block" style="margin-top:10px">Log in</button>
</form>
Thanks all, I will probably be pulling this down soon because it was just one of those "i'm an idiot" things. I had another event listener that I forgot to delete that was causing the issue. I knew something was up because when I posted my jsFiddle smippet, it worked...so there is nothing wrong with my using const in an es6 function definition. The correct listener was the one I posted:
$('#login_form').on('submit', event => {
event.preventDefault();
console.log({email:$('#username').val(),password:$('#password').val()});
authenticate({email:$('#username').val(),password:$('#password').val()});
});
But there was another one that had the wrong DOM id $('#email).val():
$('#login_form').on('submit', event => {
event.preventDefault();
console.log({email:$('#email').val(),password:$('#password').val()});
authenticate({email:$('#email').val()',password:$('#password').val()});
});
Don't be dumb like me, read before you ask...

Form validation with JavaScript using XHR

I'm fairly new to JavaScript, I've been using tutorials online but they seem to often validate with php and use JavaScript for warnings, the application I'm making users xhr to post the data to the server, but before this I want to have JavaScript complete some validations. Then I'll re validate with the PHP.
Here is the form code
<form id="booking" action="">
<span class="red">*</span>First Name:
<input type="text" name="firstName" id="firstName">
<br>
<span class="red">*</span>Last Name:
<input type="text" name="lastName" id="lastName">
<br>
<span class="red">*</span>Contact Number:
<input type="text" name="number" id="number">
<br>
Unit Number(optional):
<input type="text" name="unit" id="unit">
<br>
<span class="red">*</span>Street Number:
<input type="text" name="streetNumber" id="streetNumber">
<br>
<span class="red">*</span>Street Name:
<input type="text" name="streetName" id="streetName">
<br>
<span class="red">*</span>Suburb:
<input type="text" name="pickupSuburb" id="pickupSuburb">
<br>
Destination Suburb<span class="red">*</span>:
<input type="text" name="destinationSuburb" id="destinationSuburb">
<br>
Pick-Up Date and Time<span class="red">*</span>:
<input type="datetime-local" name="dateTime" id="dateTime">
<br>
<br>
<input type="button" value="Submit"
onclick="getData('bookingprocess.php','message', firstName.value, lastName.value, number.value, unit.value, streetNumber.value, streetName.value, pickupSuburb.value, destinationSuburb.value, dateTime.value)"/>
<input type="reset" value="Reset">
</form>
<div id="message">
</div>
I've created a div for the warning messages.
Here is the JavaScript
// file simpleajax.js
var xhr = createRequest();
function getData(dataSource, divID, firstName, lastName, number, unit, streetNumber, streetName, pickupSuburb, destinationSuburb, dateTime) {
if(xhr) {
var place = document.getElementById(divID);
var requestbody = "firstName="+encodeURIComponent(firstName)+"&lastName="+encodeURIComponent(lastName)+"&number="+encodeURIComponent(number)+"&unit="+encodeURIComponent(unit)+"&streetNumber="+encodeURIComponent(streetNumber)+"&streetName="+encodeURIComponent(streetName)+"&pickupSuburb="+encodeURIComponent(pickupSuburb)+"&destinationSuburb="+encodeURIComponent(destinationSuburb)+"&dateTime="+encodeURIComponent(dateTime);
xhr.open("POST", dataSource, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
place.innerHTML = xhr.responseText;
} // end if
} // end anonymous call-back function
xhr.send(requestbody);
} // end if
} // end function getData()
function checkForm(booking) {
var valid = true;
if(firstName.value.length <= 0) {
window.alert("Name is empty");
booking.firstName.focus();
return valid = false;
}
}
Note there will be more validations, my question is how can I call the validations from the form, or directly from the XHR, which is the best practice? I understand the call to the XHR from the form could be considered bad practice as well as I've hard coded all the values?
Getting this to work has been quite troublesome, so apologies if its a little Hodge podge.
Validating while the form is filled (when the cursor leaves a field) makes more sense since you can add some hints to user. Like, if a user enters an email, you check if it contains # and it doesn't, it's much more user-friendly to notify them that something's wrong with their email input (in contrast, they may send the form, you validate it then and tell them the form is not ok, but then they have to fill the form again, which is sort of frustrating).
Try
<input type="text" onblur="alert('out!');" />
This fires when the input loses focus. Now, you may wonder how to use functions defined elsewhere in such handling. That can be done, for instance, like this:
JS:
window.myHandler = function(input,event) { ... };
HTML:
<input type="text" onblur="window.myHandler(input,event);" />
Note that in HTML onblur attribute event is a "pre-defined" variable that contains the Event object "instance", but for elder versions of IE, you should use
window.myHandler = function(input,event) {
event = event || window.event; // elder IE store the Event object in window.event
// input is your DOM element. You can use input.value to get the value
// or this.classList to add some class which indicates (via CSS) that the input is wrong
...
};

how to use autocomplete in angularjs

I have an application with add friend feature, in that feature, user must fill their friend's username in the textbox. this is the html code:
<div content-for="title">
<span>Add Friend</span>
</div>
<form class="form-inline" role="form">
<div class="form-group">
<label class="sr-only" for="exampleInputEmail2">User ID</label>
<input type="text" class="form-control" data-ng-model="add.email" id="exampleInputEmail2" placeholder="User ID">
</div>
<button type="submit" class="btn btn-default" data-ng-click="addfriends()">Add</button>
the interface will be like this
and this is the js code:
// addfriend
$scope.add = {};
$scope.addfriends = function(){
$scope.messages = {
email : $scope.add.email,
userid : $scope.datauser['data']['_id']
};
//event add friend
socket.emit('addfriend',$scope.messages,function(callback){
if(!callback['error']){
$scope.datauser['data']['penddingrequest'].push(callback['data']);
//push pendding request to localstorage user
localStorageService.remove('user');
localStorageService.add('user', $scope.datauser);
$scope.add['email'] = '';
alert('Successfully added friend');
}else{
var msg = callback['error'];
navigator.notification.alert(msg,'','Error Report','Ok');
}
});
};
I want to change this feature little bit, I want to make this textbox showing some suggestion based on the input, like if user input 'a', the textbox will show all user id that start with 'a'. something like twitter's searchbox or instagram searchbox. these user ids is from database.
example searchbox of web instagram
my question is how to change this textbox to be autocomplete but still work like before? thanks very much
There are many ways to do this.
First is this one: You basically create Angular directive for your input.
http://jsfiddle.net/sebmade/swfjT/
Another way to do is to attach onKeyUp event to your input:
<div class="form-group">
<label class="sr-only" for="exampleInputEmail2">User ID</label>
<input type="text" class="form-control" data-ng-model="add.email" id="exampleInputEmail2" placeholder="User ID" ng-keyup="searchFriends()">
<div ng-model="searchFriendsResult" />
</div>
And then, in your controller, you create a searchFriends function that will:
Search your database
Display the result in the view.
Something like this (not a complete code):
$scope.searchFriends = function(value){
// Make Ajax call
var userRes = $resource('/user/:username', {username: '#username'});
userRes.get({username:value})
.$promise.then(function(users) {
$scope.searchFriendsResult = users;
});
};
Use Bootstrap Typeahead
<input type="text" ng-model="asyncSelected"
placeholder="Locations loaded via $http"
uib-typeahead="address for address in getLocation($viewValue)"
typeahead-loading="loadingLocations"
typeahead-no-results="noResults"
class="form-control"/>

Validating Form with Javascript (Simple Test)

var name = document.getElementById('contact-name'),
email = document.getElementById('contact-email'),
phone = document.getElementById('contact-phone'),
message = document.getElementById('contact-message');
function checkForm() {
if (name.value == '') {
alert('test');
}
}
I was simply trying to make sure everything was working before I began learning actual client-side validation.
Here is the HTML
<form role='form' name='contactForm' action='#' method="POST" id='contact-form'>
<div class="form-group">
<label for="contact-name">First and Last Name</label>
<input type="text" class="form-control" id="contact-name" name="contactName" placeholder="Enter your name.." pattern="[A-Za-z]+\s[A-Za-z]+">
</div>
<div class="form-group">
<label for="contact-email">Email address</label>
<input type="email" class="form-control" id="contactEmail" name="contactEmail" placeholder="Enter Email" required>
</div>
<div class="form-group">
<label for="contact-phone">Phone Number</label>
<input type="number" class="form-control" id="contactPhone" name="contactPhone" placeholder="Enter Phone Number" required'>
</div>
<div class="form-group">
<label for='contactMessage'>Your Message</label>
<textarea class="form-control" rows="5" placeholder="Enter a brief message" name='contactMessage' id='contact-message' required></textarea>
</div>
<input type="submit" class="btn btn-default" value='Submit' onclick='checkForm()'>
</fieldset>
</form>
I took the required attribute off, and if I leave the name field empty it goes right to the other one when i click submit. To check whether javascript was working at all, i did an basic onclick function that worked.
Maybe someone can explain to me what is wrong with the checkForm function. Thanks in advance.
P.S The form-group and form-control classes belong to bootstrap
Change your javascript to this:
var contactName = document.getElementById('contact-name'),
email = document.getElementById('contact-email'),
phone = document.getElementById('contact-phone'),
message = document.getElementById('contact-message');
function checkForm() {
if (contactName.value === '') {
alert('test');
}
}
Okay, Hobbes, thank you for editing your question, now I can understand your problem.
Your code faces three two issues.
Your control flow. If you want to validate your field, you have to obtain its value upon validation. You instead populate variable name when the page loads, but the user will enter the text only after that. Hence you need to add var someVariableName = document.getElementById(...); to the beginning of the checkForm() function.
global variables. Please do not use them like that, it is a good design to avoid global variables as much as possible, otherwise you bring upon yourself the danger of introducing side effects (or suffering their impact, which happens in your situation). The global context window already contains a variable name and you cannot override that. See window.name in your console. You can of course use var name = ... inside the function or a block.
Even if you fix the above, you will still submit the form. You can prevent the form submission if you end your checkForm() function with return false;
For clarity I append the partial javascript that should work for you:
function checkForm() {
var name = document.getElementById('contact-name');
if (name.value == '') {
alert('test');
return false;
}
}
EDIT: As Eman Z pointed out, the part 1 of the problem does not really prevent the code from working as there's being retrieved an address of an object (thanks, Eman Z!),

data-bind multiple text boxes to display in one text box

I'm using a Kendo edit box that a user can enter the different parts of a SQL connection string (server name, database, user name and password). I also have a text box that will show the user the entire connection string as they type.
My question is how can I data-bind each of the four text boxes (server, database, user and password) to one text box as the user enters data into each one.
Also, the user requested seperate fields.
Thanks in advance,
Dan Plocica
Doing it using Kendo UI would be:
HTML:
<div id="form">
<label>Server : <input type="text" class="k-textbox" data-bind="value: server"></label><br/>
<label>Database : <input type="text" class="k-textbox" data-bind="value: db"></label><br/>
<label>User : <input type="text" class="k-textbox" data-bind="value: user"></label><br/>
<label>Password : <input type="password" class="k-textbox" data-bind="value: password"></label><br/>
<div id="connections" data-bind="text: connection"></div>
</div>
JavaScript:
$(document).ready(function () {
var model = kendo.observable({
server : "localhost:1521",
db : "database",
user : "scott",
password : "tiger",
connection: function () {
return this.get("user") + "/" +
this.get("password") + "#" +
this.get("server") + ":" +
this.get("db");
}
});
kendo.bind($("#form"), model);
});
In the HTML there are two parts:
The input files where I define each input to what field it is bound in my model.
A div where I found its text to connection function in my model that creates a string from the different values.
This is automatically updated and you can freely edit each input.
You might decorate the input as I did setting it's CSS class to k-textbox, that's optional. The only important thing is the data-bind="value : ...".
The JavaScript, is just create and Observable object with the fields and methods that we want.
Running example here: http://jsfiddle.net/OnaBai/xjNMf/
I will write solution using jQuery JavaScript library, and you should use jQuery because its much easier and easier to read and also to avoid errors in different browsers.
**HTML**
Server: <input type="text" id="server"/><br/>
Database: <input type="text" id="database"/><br/>
Username: <input type="text" id="username"/><br/>
Password: <input type="text" id="password"/><br/>
<br/>
Full CS: <input type="text" id="solution"/><br/>
JS
<script type="text/javascript">
var _template = 'Data Source=%server%;Initial Catalog=%db%;Persist Security Info=True;User ID=%user%;Password=%pass%';
$(document).ready(function(){
$('#server,#database,#username,#password').keyup(function(){ updateSolution();});
});
function updateSolution(){
var _t = _template.replace('%server%', $('#server').val()).replace('%db%', $('#database').val()).replace('%username%', $('#username').val()).replace('%pass%', $('#password').val());
$('#solution').val(_t);
};
</script>

Categories

Resources