This is a quick example to see how to wire up a Firestore database to a simple jQuery app that will demonstrate basic CRUD operations (create/read/update/delete).
1. Setup Firestore Database
- Go to Firebase console and add new project
- On the side menu: Develop > Database > Cloud Firestore > Create Database. Select Start in test mode to allow all reads and writes to your database.
- Add a new collection called "contacts"
- Enable Anonymous authentication at Authentication > SIGN-IN METHOD > Anonymous > Enable > SAVE.
- Go to Project Overview > click "Add Firebase to your web app" and copy initialization config and place it in this example Javascript.
- For more info, check Firebase Web Setup.
2. HTML5 Code
Now will create a new HTML page that includes Firebase javascript library, jQuery and Bootstrap (for quick styling).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Contacts</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/5.2.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.2.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.2.0/firebase-firestore.js"></script>
<script>
// Initialize Firebase : Replace with your Project Config!!!!!!
var config = {
apiKey: "?",
authDomain: "?",
databaseURL: "?",
projectId: "?",
storageBucket: "?",
messagingSenderId: "?"
};
//////////////////////////////////////////////////////////////
firebase.initializeApp(config);
</script>
<!-- Bootstrap/jQuery JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<!-- Contacts JS-->
<script src="index.js"></script>
</head>
<body>
<!-- Contacts Table -->
<table id="ContactTable" class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<td>...</td>
</tr>
</thead>
<tbody>
<tr class="data-temp">
<td data-prop="name"></td>
<td data-prop="email"></td>
<td data-prop="phone"></td>
<td>
<button class="btn btn-secondary edit">edit</button>
<button class="btn btn-danger remove">remove</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3"></td>
<td><button class="btn btn-dark add" id="ContactAdd">add</button></td>
</tr>
</tfoot>
</table>
<!-- Contact Form -->
<form id="ContactForm">
<div class="modal fade" id="ContactModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" data-prop="name" placeholder="Enter name" maxlength="100" required />
</div>
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" data-prop="email" placeholder="Enter email" maxlength="100" required />
</div>
<div class="form-group">
<label>Phone</label>
<input type="tel" pattern="^[\d\-+]*$" class="form-control" data-prop="phone" placeholder="Enter phone" maxlength="50" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
</form>
</body>
</html>
Note it is only including the components we need : firebase-app, firebase-auth and firebase-firestore.
Note the "data-prop" attribute with values matching the contact fields in table template row and also in the form inputs.
3. Javascript Code
This is the jQuery code saved in "index.js"
(function ($) {
// firestore ref
var db;
// auth and setup event handlers
var init = function () {
auth();
$('#ContactTable').on('click', 'button.edit', edit);
$('#ContactTable').on('click', 'button.remove', remove);
$('#ContactAdd').click(add);
$('#ContactForm').submit(save);
};
// init on doc ready
$(document).ready(init);
// sign-in anonymously
var auth = function () {
firebase.auth().signInAnonymously()
.then(function (result) {
db = firebase.firestore();
db.settings({ timestampsInSnapshots: true });
list();
})
.catch(function (error) {
alert("failed to anonymously sign-in");
});
};
var listTempTr;
// load list
var list = function () {
var tblBody = $('#ContactTable > tbody');
//remove any data rows
tblBody.find('tr.data').remove();
//get template row
var tempTr = tblBody.find('tr.data-temp').removeClass('data-temp').addClass('data').remove();
if (tempTr.length) {
listTempTr = tempTr;
} else {
tempTr = listTempTr;
}
// get collection of Contacts
db.collection("contacts").get().then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
// clone template row and append to table body
var tr = tempTr.clone();
tr.data('id', doc.id);
var data = doc.data();
// set cell values from Contact data
tr.find('td[data-prop]').each(function () {
var td = $(this);
td.text(data[td.data('prop')] || '');
});
tblBody.append(tr);
});
});
};
// on remove
var remove = function (e) {
e.preventDefault();
var id = $(this).parents('tr:first').data('id');
db.collection("contacts").doc(id).delete().then(function () {
// reload list
list();
})
.catch(function (error) {
alert("failed to remove contact");
});
};
// on add
var add = function (e) {
e.preventDefault();
open('');
};
// on edit
var edit = function (e) {
e.preventDefault();
var id = $(this).parents('tr:first').data('id');
open(id);
};
// open form modal
var open = function (id) {
var modal = $('#ContactModal');
// set current Contact id
modal.data('id', id);
// reset all inputs
modal.find('input').val('');
modal.modal('show');
if (!id) return;
// get Contact to edit
db.collection("contacts").doc(id).get().then(function (doc) {
if (doc.exists) {
var data = doc.data();
//set form inputs from Contact data
modal.find('input[data-prop]').each(function () {
var inp = $(this);
inp.val(data[inp.data('prop')] || '');
});
} else {
alert("No such record");
}
}).catch(function (error) {
alert("failed to read contact");
});
};
// update or add
var save = function (e) {
e.preventDefault();
var modal = $('#ContactModal');
var id = modal.data('id');
var data = {};
//read values from form inputs
modal.find('input[data-prop]').each(function () {
var inp = $(this);
data[inp.data('prop')] = inp.val();
});
// update or add
(id ? db.collection("contacts").doc(id).update(data) : db.collection("contacts").add(data)).then(function (result) {
// hide modal and reload list
modal.modal('hide');
list();
})
.catch(function (error) {
alert("failed to save contact");
});
};
}(jQuery));
First -on Document Ready- it will anonymously sign-in user. Also attaching event handlers for the edit/remove/add buttons and form submisson.
Then get the contacts collection, and loop each document to add a new row in the contacts table.
On Add/Edit, it will open a Bootstrap modal to display the form. and will load existing Contact data to edit.
On Save, will decide to use update() or add() based on contact ID.
Now, save the HTML and Javascript files and give it a try.
0 comments
Post a Comment