I have a user structure where I can create and update a user but I cannot remove a user due to a reference child error due to some kind of string.
Basically, I have a realtime database consists of different users ID then there's the Name, Age and Nationlaity.
I want to be able to try and delete a user by its user ID for instance (usr5) so that when I enter that it'll delete the user from the database.
Can anyone help?
The Error:
Reference.child failed: First argument was an invalid path = "[object HTMLInputElement]". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"
at fi (validation.ts:382)
at o.child (Reference.ts:90)
at removeUser ((fie path folders) index.html:115:58)
My HTML:
<body>
<div>
<h4>Create User: </h4>
<form>
<label>Create User ID: </label><input type="text" id="usrID"/><br/>
<label>First Name: </label><input type="text" id="usrFName"/><br/>
<label>Age: </label><input type="number" id="usrAge"/><br/>
<label>Nationality: </label>
<select id="usrNation">
<option value="American">American</option>
<option value="British">British</option>
<option value="French">French</option>
</select>
<button id="createUserBtn">Create</button>
</form>
</div>
<div>
<h4>Remove User: </h4>
<form>
<label>Create User ID: </label><input type="text" id="usrID"/><br/>
<button id="removeUserBtn">Remove</button>
</form>
</div>
My Firebase/Javascript:
<script>
var database = new Firebase("https://(my db url)/"),
userdb = database.child("/users");
userID = document.getElementById('usrID'),
userFirstName = document.getElementById('usrFName'),
userAge = document.getElementById('usrAge'),
userNationality = document.getElementById('usrNation');
function createUser(userID, usrFName, usrAge, usrNation){
firebase.database().ref('users/' + userID).set({
usrFName: usrFName,
usrAge: usrAge,
usrNation: usrNation
});
console.log('Success');
}
function insertAutoKey(usrFName, usrAge, usrNation){
var newPost = {
usrFName: usrFName,
usrAge: usrAge,
usrNation: usrNation
};
var newPostKey = firebase.database().ref().child('users').push().key;
var updates = {};
updates['/users/' + newPostKey] = newPost;
return firebase.database().ref().update(updates);
}
document.getElementById('createUserBtn').addEventListener('click', function(){
var usrID = userID.value,
usrFName = userFirstName.value,
usrAge = userAge.value,
usrNation = userNationality.value;
if(usrID && usrFName && usrAge && usrNation) {
createUser(usrID, usrFName, usrAge, usrNation);
}
});
function removeUser(){
var userRef = firebase.database().ref().child("users").child(userID);
userRef.once('value', function(snapshot) {
if (snapshot.val() === null) {
alert("no user found");
}else{
userRef.remove();
}
});
console.log('Remove Success');
}
document.getElementById('removeUserBtn').addEventListener('click', function(){
removeUser();
});
Change this:
userID = document.getElementById('usrID'),
userFirstName = document.getElementById('usrFName'),
userAge = document.getElementById('usrAge'),
userNationality = document.getElementById('usrNation');
into this:
userID = document.getElementById('usrID').value;
userFirstName = document.getElementById('usrFName').value;
userAge = document.getElementById('usrAge').value;
userNationality = document.getElementById('usrNation').value;
You need to add the property value to retrieve the value of each element.
Related
Edit - Updated JS code to display suggestions made in comments, still having issues.. Now the button <input id="edit" type="submit" value="Submit"> won't go to edit.html, instead it is returning action.html? It is nested inside of the editForm?
I have a simple form which I have managed to learn to submit, add, remove, and display bookings using the localStorage (thanks to those who helped on here!).
My last task is to amend a booking, I think I am almost there with it, but not sure how to call the indexes (excuse my jargon), to replace the values.
The form submits and the web address reads something like edit.html?OldFirstName=NewFirstName&OldLastName=NewLastName, however the values don't update in storage, and it throws an error saying
Uncaught TypeError: Cannot read property 'fname' of undefined`.
I expected this to happen as I know I am not finding the values correctly, but I can't figure out how I should be writing it out? My thought process was that it would be similar to the original submit function but with the [i] values for fname and lname?
Here's my JS code - if you need anything else from me let me know:
// ~~~ add bookings to localStorage
var bookings = localStorage.getItem("bookings");
$("#submit").click(function () {
bookings = (bookings) ? JSON.parse(bookings) : [];
var newBookings = {
fname: $('#fname').val(),
lname: $('#lname').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
});
// ~~~ edit bookings in localStorage
$("#edit").click(function (e) {
e.preventDefault();
bookings = (bookings) ? JSON.parse(bookings) : [];
var parent_form = $('#editForm');
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
var newBookings = {
fname: fname,
lname: lname
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
});
// ~~~ display bookings in browser
function showBooking(i) {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML = "";
for (let i = 0; i < bookingItems.length; i++) {
bookingResult.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookingItems[i].fname + " " + bookingItems[i].lname}
<button onclick="deleteBooking(${i})" class="btn btn-danger text-light ">Delete</button>
<button onclick="editBooking(${i})" class="btn btn-danger text-light ">Edit</button>
</h3>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
var bookingResult = document.getElementById("editAppt");
var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML =
`<form id="editForm" name="editForm" onsubmit="return editForm(this)" class="col-sm-6">
<div class="row">
<input type="text" class="input" id="fname_${i}" placeholder="${bookingItems[i].fname}" name="${bookingItems[i].fname}" required>
<input type="text" id="lname_${i}" class="input" placeholder="${bookingItems[i].lname}" name="${bookingItems[i].lname}" required>
<input id="edit" type="submit" value="Submit">
</div>
</form>`;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i){
var bookingItems = JSON.parse(localStorage.getItem("bookings"));
bookingItems.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookingItems));
showBooking();
}
// ~~~ form submit handlers
function setAction(form) {
form.action = "action.html";
}
function editForm(form) {
form.action = "edit.html";
}
I can see that the issue comes from this like :
$("#edit").click(function (i) {
You expect the click event to return an index but it's not, the i will represent the event object, so you may need to use $(this) to get the related inputs like :
$("#edit").click(function (e) {
var parent_form = $(this.form);
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
....
NOTE: The id must not be duplicated, so you need to avoid that, you may use prefix like:
<input type="text" class="input" id="fname_${i}" placeholder="${bookingItems[i].fname}" name="${bookingItems[i].fname}" required>
<input type="text" class="input" id="lname_${i}" placeholder="${bookingItems[i].lname}" name="${bookingItems[i].lname}" required>
I need some help I have created a login and registration form and its stores its values to the local storage. This is for a class, how can I make it to accept more than one user. Right now it only takes one username and password.
Thanks in advance,
<!-- sign up form -->
<div class="container pt-5">
<!-- registration form -->
<form id="register-form">
<input id="uName" type="text" placeholder="Name" value="" />
<input id="uPw" type="password" placeholder="Password" value="" />
<input id="rgstr_btn" type="submit" value="get Account" onClick="store()" />
</form>
<!-- login form -->
<form id="login-form" action="./index.html">
<input id="userName" type="text" placeholder="Enter Username" value="" />
<input id="userPw" type="password" placeholder="Enter Password" value="" />
<input id="login_btn" type="submit" value="Login" onClick="check()" />
</form>
</div>
// Name and Password from the register-form
var name = [document.getElementById('uName')];
var pw = document.getElementById('uPw');
// storing input from register-form
function store() {
localStorage.setItem('name', uName.value);
localStorage.setItem('pw', uPw.value);
}
// check if stored data from register-form is equal to entered data in the login-form
function check() {
// stored data from the register-form
var storedName = localStorage.getItem('name');
var storedPw = localStorage.getItem('pw');
// entered data from the login-form
var usrName = document.getElementById('userName').value;
var usrPw = document.getElementById('userPw').value;
// check if stored data from register-form is equal to data from login form
if (userName.value == storedName && userPw.value == storedPw) {
alert('You are logged in ' + usrName);
location.replace("./index.html")
} else {
alert('Access denied. Valid username and password is required.');
}
}
You would want to use an array of objects where each objects stores a username and password. However localStorage only stores strings, so the array needs to be encoded and decoded into a string, which can be done by JSON.
The check function would look like:
function check() {
var usrName = document.getElementById('userName').value;
var usrPw = document.getElementById('userPw').value;
let stored_users = JSON.parse(localStorage.getItem('users'))
if(stored_users) {
for (let u = 0; u < stored_users.length; u++){
if (usrName == stored_users[u].name && usrPw == stored_users[u].password) {
alert('You are logged in ' + usrName);
return location.replace("./index.html");
}
}
} else {
localStorage.setItem('users', '[]');
}
return alert('Access denied. Valid username and password is required.');
}
Then store would look like:
function store() {
var usrName = document.getElementById('userName').value;
var usrPw = document.getElementById('userPw').value;
let stored_users = JSON.parse(localStorage.getItem('users'));
if(stored_users) {
stored_users.push({name: usrName, password: usrPw});
localStorage.setItem('users', JSON.stringify(stored_users));
} else {
localStorage.setItem('users', JSON.stringify([{name: usrName, password: usrPw}]));
}
}
You could store an Object at localStorage instead of property. Just parse it into a JSON string like this:
var users = {
userA: {
name: 'usernameA',
pw: 'passwordA'
},
userB: {
name: 'usernameB',
pw: 'passwordB'
}
};
localStorage.setItem('users', JSON.stringify(users));
Then you can iterate over users object:
var users = JSON.parse(localStorage.getItem('users'));
console.log(users.userA);
console.log(users.userB);
I dont't know the context, I suppose security is not an issue, but I would do something like this:
const jsonObject=localStorage.getItem(key);
//"[{\"user\":\"John\",\"password\":\"12345\"},{\"user\":\"Doe\",\"password\":\"password\"}]"
const theObject=JSON.parse(jsonObject);
// [{user:"John",password:"12345"},{user:"Doe",password:"password"}];
theObject.push ({user:"Jerry",password:"tom"});
const updatedJson=JSON.stringify(theObject);
localStorage.setItem(key, updatedJson);
I have a java program for coupon system and one of the methods is to update company details the code in java:
public Company updateCompanyDetailes(Company companyToUpDate) throws CustomException {
Company companyFromDb = companyRpository.findById(companyToUpDate.getId()).get();
companyFromDb.setPassword(companyToUpDate.getPassword());
companyFromDb.setEmail(companyToUpDate.getEmail());
companyToUpDate = companyRpository.save(companyFromDb);
return companyToUpDate;
}
It works great but when i want to call this method from my HTML page the javascript is crashing all the time and not transfer the company details as an object,
$scope.companyToUpDate = function() {
$scope.hideAll();
$scope.UpdateComp = true;
$scope.executeForCompany = function() {
if ($scope.id == '') {
window.alert("You must enter ID")
}else {
alert("do you want update company?");
var id = $scope.id;
var password = $scope.password;
var email = $scope.email;
var company = {
companyId: id,
email: email,
password: password
};
$http.put('http://localhost:8999/rest/api/admin/updateCompany', company)
.then(function (response){
window.alert('updated');
// $scope.id = '';
//$scope.password = '';
// $scope.email= '';
$scope.hideAll();
$scope.WelcomePage =true;
}, function(error) {
alert('operation failed' + error.data);
});
}
}
}
As I try is rest when I send aJASON with the parameters id, password, and this is the HTML code:
<div class="col-md-9" ng-show="UpdateComp">
<h2>choose company id to update:</h2>
<input type="number" ng-model="id" min="1">ID</input>
<h4>fill the fields (Password is mandatory):</h4>
* Password<input type="text" ng-model="password">
</input>
Email<input
type="text" ng-model="email"></input>
<button type="button" class="btn btn-primary"
ng-click="executeForCompany()">UPD</button>
<div ng-show="UpdateComp" ng-model="company">
</div>
</div>
i am getting the companyId from the user, all the Javascript are working beside this one
i get this error:
java.lang.IllegalArgumentException: The given id must not be null
When you pass data in json from javascript and are catching that json in a Object(Company) then you need to be careful that the keys are the same as defined in class level.
There is an error for id, check that are you getting you data here
var id = $scope.id;
var password = $scope.password;
var email = $scope.email;
by printing or any means you use.
Also in $http.put('http://localhost:8999/rest/api/admin/updateCompany', company) you passing object named company but receiving it as companyToUpDate make them same.
I need to display the answer from the form in a story. The story must be displayed below the form only after the form is successfully submitted (not an alert), and with the form remaining on the page (not a new page). I am able to insert the form values into the story, but need help with displaying the story after form is submitted. I cannot use anything but html and javascript. I think this can be done with innerHTML.
<head><title>Questions</title>
<script type = "text/javascript" src="quiz1.js">
</script>
</head><body>
<h1>Tell Me About Yourself</h1>
<form name = "the_form" action = "" method = "post"
onSubmit = "var the_result = checkMandatory(); return the_result;">
Full Name:<input type = "text" name = "name" id = "name" /><br/>
Favourite Animal:<input type = "text" name = "animal" id = "animal"><br/>
Favourite Food:<input type = "text" name = "favFood" id = "favFood"><br/>
Favourite Destination:<input type = "text" name = "destination" id = "desitnation"><br/>
Least Favourite Food:<input type = "text" name = "leastFav" id = "leastFav"><br/>
Happiest Moment:<input type = "text" name = "moment" id = "moment"><br/>
Adjective that describes you:<input type = "text" name = "adjective" id = "adjective"><br/>
<br>
<input type="button" value="Submit" onClick = "checkMandatory(); return false;"/><br />
<br />
</form>
<div id="storyDiv"></div>
</body>
</html>
function checkMandatory()
{
// check the text field
// make a var for each question to access easier eg "favMeal"
var name = window.document.the_form.name.value;
//! means 'not'... flips around the if
if (!(name.indexOf(" ") > 0))
{
alert("You must give your full name.");
//return false stops the program
return false;
} else {
//firstName checks all character from 0 to whenever (space) occurs and strips it
var firstName = name.substring(0,name.indexOf(" "));
var name = window.document.the_form.name.value;
var animal = window.document.the_form.animal.value;
var favFood = window.document.the_form.favFood.value;
var destination = window.document.the_form.destination.value;
var leastFav = window.document.the_form.leastFav.value;
var moment = window.document.the_form.moment.value;
var adjective = window.document.the_form.adjective.value;
//alert("first name is " + firstName);
//use alert firstName to test the firstName function
document.write("The young person's name was "+firstName+". "+firstName+" loved to ride
"+animal+
" almost every day. "+firstName+"'s second happiest moment, only next to "+moment+", was in
"+destination+", where "+favFood+
" was served for breakfast, lunch and dinner. It was only when "+firstName+" was told that
"+favFood+
" is actually made from "+animal+", that it instantly became "+firstName+"'s least
favourite food, even worse than "+leastFav+
", and that made "+firstName+" feel very "+adjective+" indeed.")
//document.getElementById('storyDiv').innerHTML = document.getElementById('name').value;
//document.getElementById(‘storyDiv’).innerHTML="The boy's name was "+firstName;
//document.write(‘storyDiv’).innerHTML="The boy's name was " + firstName;
}
}
You can achieve this by posting your form using ajax.
Don't call writethetext(); in your submit button
I'll use jQuery in my solution:
$(function() {
$("form").on("submit", function(e) {
var data = JSON.stringify($("form").serializeArray());
e.preventDefault();
$.post("yourserver/path/", data, function(result) {
writethetext(result);
});
});
});
function checkMandatory() {
// check the text field
// make a var for each question to access easier eg "favMeal"
var name = window.document.the_form.name.value;
//! means 'not'... flips around the if
if (!(name.indexOf(" ") > 0)) {
alert("You must give your full name.");
//return false stops the program
return false;
} else {
//firstName checks all character from 0 to whenever (space) occurs and strips it
var firstName = name.substring(0, name.indexOf(" "));
//alert("first name is " + firstName);
//use alert firstName to test the firstName function
}
}
function writethetext() {
document.getElementById(‘storyDiv’).innerHTML =
("There once was a boy named" + name;)
var firstName = name.substring(0, name.indexOf(" "));
var name = window.document.the_form.name.value;
var animal = window.document.the_form.animal.value;
var favFood = window.document.the_form.favFood.value;
var destination = window.document.the_form.destination.value;
var leastFav = window.document.the_form.leastFav.value;
var moment = window.document.the_form.moment.value;
var adjective = window.document.the_form.adjective.value;
}
function writethetext(text) {
document.getElementById(‘storyDiv’).innerHTML = text;
}
}
<html>
<head>
<title>Questions</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="quiz1.js">
</script>
</head>
<body>
<h1>Tell Me About Yourself</h1>
<form name="the_form" action="" method="post" onSubmit="var the_result = checkMandatory(); return the_result;">
Full Name:
<input type="text" name="name" id="name" />
<br/>Favourite Animal:
<input type="text" name="animal" id="animal">
<br/>Favourite Food:
<input type="text" name="favFood" id="favFood">
<br/>Favourite Destination:
<input type="text" name="destination" id="desitnation">
<br/>Least Favourite Food:
<input type="text" name="leastFav" id="leastFav">
<br/>Happiest Moment:
<input type="text" name="moment" id="moment">
<br/>Adjective that describes you:
<input type="text" name="adjective" id="adjective">
<br/>
<br>
<input type="button" value="Submit" onClick="checkMandatory();
return false;" />
<br />
<br />
</form>
<div id="storyDiv"></div>
</body>
</html>
I am trying to redirect to a different page after details have been submitted.
I have tried the commented-out code. It does re-direct BUT then doesn't take in the data.
When I take comment it out, it doesn't redirect but it takes in the data.
I hope I explained this properly.
Any ideas?
<script>
var curatio = {};
curatio.webdb = {};
curatio.webdb.db = null;
curatio.webdb.open = function() {
var dbSize = 5 * 1024 * 1024; // 5MB
curatio.webdb.db = openDatabase("Curatio", "1.0", "Todo manager", dbSize);
}
curatio.webdb.createTable = function() {
var db = curatio.webdb.db;
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS weight(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME, date TEXT, note TEXT )", []);
});
}
curatio.webdb.addTodo = function(todoText) {
var db = curatio.webdb.db;
db.transaction(function(tx){
var addedOn = new Date();
var date = document.getElementById("date").value;
var note = document.getElementById("note").value;
tx.executeSql("INSERT INTO weight(todo, added_on, date, note) VALUES (?,?,?,?)",
[todoText, addedOn, date, note],
curatio.webdb.onSuccess,
curatio.webdb.onError);
});
}
curatio.webdb.onError = function(tx, e) {
alert("There has been an error: " + e.message);
}
curatio.webdb.onSuccess = function(tx, r) {
// re-render the data.
curatio.webdb.getAllTodoItems(loadTodoItems);
}
curatio.webdb.getAllTodoItems = function(renderFunc) {
var db = curatio.webdb.db;
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM weight", [], renderFunc,
curatio.webdb.onError);
});
}
curatio.webdb.deleteTodo = function(id) {
var db = curatio.webdb.db;
db.transaction(function(tx){
tx.executeSql("DELETE FROM weight WHERE ID=?", [id],
curatio.webdb.onSuccess,
curatio.webdb.onError);
});
}
function loadTodoItems(tx, rs) {
var rowOutput = "";
var todoItems = document.getElementById("todoItems");
for (var i=0; i < rs.rows.length; i++) {
rowOutput += renderTodo(rs.rows.item(i));
}
todoItems.innerHTML = rowOutput;
}
function renderTodo(row) {
return "<li> Weight: " + row.todo + " kg " + "<br />" + " Date: " + row.date + "<br />" + " Note: " + row.note + " [<a href='javascript:void(0);' onclick='curatio.webdb.deleteTodo(" + row.ID +");'>Delete</a>]</li>";
}
function init() {
curatio.webdb.open();
curatio.webdb.createTable();
curatio.webdb.getAllTodoItems(loadTodoItems);
}
function addTodo() {
var todo = document.getElementById("todo");
curatio.webdb.addTodo(todo.value);
todo.value = "";
alert("Your weight has been added");
//window.location = 'users.html'
//location.href="users.html";
}
</script>
...
...
<form type="post" onsubmit="addTodo(); return false;">
<div data-role="fieldcontain">
<label for="todo">
Weight
</label>
<input name="" id="todo" placeholder="75" value="" type="text">
</div>
<div data-role="fieldcontain">
<label for="date">
Date
</label>
<input name="" id="date" placeholder="" value="" type="date">
</div>
<div data-role="fieldcontain">
<label for="note">
Notes
</label>
<input name="" id="note" placeholder="short note"></input>
</div>
<input type="submit" value="Submit" data-inline="true"/>
<a rel="external" data-role="button" data-inline="true" href="users.html">
Cancel
</a>
</form>
http is a stateless, you have to carry your parameter to your other page by using query string
for example
window.location.href = "users.html?myVlue=9"
and then you have process myvalue in your other page
I hope this helpful
Change your onsubmit to return the function and not false...then in your JS function simply return false to halt submission of the form or true to submit the form as normal. Here is a short example of what I mean
<script>
function validateForm(){
var x=document.forms["myForm"]["fname"].value;
if (x==null || x==""){
alert("First name must be filled out");
return false;
}
}
</script>
<form name="myForm" action="demo_form.asp" onsubmit="return validateForm()" method="post">
First name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>
You can try window.opener to send your data from one page to another. Though this will open the page in a new window. There are lots of pages on this, try googling window.opener.
Do let me know if this works for you.
I found a work-around!
Give the DB a second or two to update - and THEN redirect
This works for me:
function addTodo() {
var todo = document.getElementById("todo");
curatio.webdb.addTodo(todo.value);
todo.value = "";
alert("Your weight has been added");
setTimeout(function () {
window.location.href = "users.html"; //will redirect to your blog page (an ex: blog.html)
}, 1000);
}