Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added database support and editing and deleting feature #24

Merged
merged 1 commit into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ Then, you are ready to run the Notes-app as an android application. To run an an
To run the app in android run the command `cordova run android` in your terminal.

**For other platforms like OSX,Electron or if you need any other help in setting cordova CLI or your environment for the application you can look at the [Cordova Documentation site](https://cordova.apache.org/docs/en/latest/)**

## After Setup
So, by now you will have a running setup of the application either in your browser or in your mobile. You can also look into the code to understand the database setup of the application.
We are using [nanoSQL](https://nanosql.io/) for our database setup and configuring it in our project using the plugin `adapter-sqlite-cordova`. The reason for using this is that it provides database support for both browser and android application by switching to the respected mode of database depending upon the environment i.e, for browser it uses `Web SQL / Indexed SQl` and for android it uses `SQLite`. You can learn more about it through the links [SQLite(Cordova)](https://nanosql.io/adapters/sqlite-cordova.html) or [@nano-sql/adapter-sqlite-cordova](https://www.npmjs.com/package/@nano-sql/adapter-sqlite-cordova). If you have basic knowledge of SQL then, you can go through the [Documentation](https://nanosql.io/setup.html) to understand more regarding the usage of SQLite cordova query structures.

Here, we are creating the database and table dynamically if it doesn't exists in your memory by using the connect() method by specifying the database name and table name. We need to connect to the database and the table inside it to run any query on it, so we are saving the connection in a variable `db_connect` and then using it to run the other queries in the later part of our code. Few of the queries used in the code are `select, upsert(insert) and delete` for executing the tasks. You can learn about it by going through the documentation link mentioned above.
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@
"author": "Apache Cordova Team",
"license": "Apache-2.0",
"dependencies": {
"@nano-sql/adapter-sqlite-cordova": "2.1.2",
"cordova": "^9.0.0",
"cordova-android": "^6.3.0",
"cordova-browser": "^5.0.1",
"cordova-plugin-whitelist": "^1.3.3"
"cordova-plugin-device": "2.0.2",
"cordova-plugin-whitelist": "^1.3.3",
"cordova-sqlite-storage": "3.2.0"
},
"cordova": {
"plugins": {
"cordova-plugin-whitelist": {}
"cordova-plugin-whitelist": {},
"adapter-sqlite-cordova": {}
},
"platforms": [
"browser",
"android"
]
}
}
}
14 changes: 10 additions & 4 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,20 @@
<div class="list-container">
<ul id="list"></ul>
</div>
<button class="btn btn-primary" id='show'>+</button>
<button class="btn btn-primary" id='show'>
<i class="fa fa-plus"></i>
</button>
<div class="add-note-container">
<form id="add-note-form">
<div class="input-group">
<input class="form-control" type="text" id="idea" placeholder="Type here" />
<input class="form-control" type="text" id="note" placeholder="Enter your note here ..." autocomplete="off" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<button type="submit" class="btn btn-primary" id="submit-button" disabled="true">
<i class="fa fa-paper-plane" aria-hidden="true"></i>
</button>
<button type="button" class="btn btn-danger" id="close" >
<i class="fa fa-remove"></i>
</button>
</span>
</div>
</form>
Expand All @@ -53,7 +58,8 @@
<script type="text/javascript" src="javascripts/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="javascripts/popper.js"></script>
<script type="text/javascript" src="javascripts/bootstrap.min.js"></script>
<script src="javascripts/index.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="javascripts/index.js"></script>
</body>

</html>
197 changes: 144 additions & 53 deletions www/javascripts/index.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,153 @@
$(() => {
const fbutton = $('#show');
const next = $('.add-note-container');
fbutton.click(() => {
fbutton.hide(250, () => {
next.show(250);

//Connecting to database
document.addEventListener(typeof cordova !== "undefined" ? "deviceready" : "DOMContentLoaded", () => {
var db_connect = nSQL().connect({
id: "my_db",
mode: "PERM",
tables: [
{
name: "note_table",
model: {
"id:int": {pk: true, ai:true},
"note:string": {},
},
}
],
});/*then(()=>{
alert("sa");
});*/

const add_button = $('#show');
const close_button = $('#close');
const note_input = $('.add-note-container');
const input = $('#note');
var update_check, update_id;

//Check to see if there is any text entered
//If there is no text within the input then disable the button
$(input).keyup( function() {
$('#submit-button').prop('disabled',this.value==""? true : false);
});

//Showing input option on clicking add button
add_button.click(() => {
add_button.hide(250, () => {
note_input.show(250);
input.focus();
});
});
});

// hide button when focus is lost
$('#idea').blur(() => {
fbutton.hide(250, () => {
next.show(250);
// Hide input if the target of the click isn't the container
$(document).mouseup(function(e){
if(!note_input.is(e.target) && note_input.has(e.target).length === 0 && $(e.target).attr('data-edit-id') == undefined){
note_input.hide(250, () => {
add_button.show(250);
});
}
});
});

function generateUID() {
// I generate the UID from two parts here
// to ensure the random number provide enough bits.
let firstPart = (Math.random() * 46656) | 0;
let secondPart = (Math.random() * 46656) | 0;
firstPart = ("000" + firstPart.toString(36)).slice(-3);
secondPart = ("000" + secondPart.toString(36)).slice(-3);
return firstPart + secondPart;
}

const list = new Map(JSON.parse(localStorage.getItem("todoList")) || []);

function saveTodoList() {
localStorage.setItem('todoList', JSON.stringify(Array.from(list)));
}

$("#add-note-form").submit((e) => {
e.preventDefault();
const text = $("#idea").val();
list.set(generateUID(), text);
saveTodoList();
$('#idea').val("");
render();
const container = $('.list-container');
container.delay(500).animate({
scrollTop: container[0].scrollHeight
//scrollTop: 0

//Hide button on clicking close button
close_button.click(() => {
note_input.hide(250, () => {
add_button.show(250);
});
});
});

function render() {
$('#list').html('');
for (let [k, v] of list) {
const listed = $('<li data-id' + k + '>' + v + '</li>');
const button = $('<button class="btn btn-danger">Remove</button>');
button.click(() => {
list.delete(k);
saveTodoList();

//Adding data to the database
$("#add-note-form").submit((e) => {
e.preventDefault();
var text = $(input).val();
if (update_check) { //If data is being updated
if (confirm("Are you sure you want to update?")) {
db_connect.then(() => {
nSQL("note_table").query("upsert",{note: text}).where(["id","=",update_id]).exec();
});
}
else
return false;
}
else { //If new data is added
db_connect.then(() => {
nSQL("note_table").query("upsert",{note: text}).exec();
});
}
setTimeout(function(){
if (update_check) {
update_check = 0;
$('#list').html('');
}
render();
}, 50);
$(input).val("");
$('#submit-button').prop('disabled', true);
const container = $('.list-container');
container.delay(25).animate({
scrollTop: container[0].scrollHeight
});
listed.append(button);
$('#list').append(listed);
});

//Delete a data
function delete_data(id) {
var x=parseInt(id);
if (confirm("Are you sure you want to delete it?")) {
db_connect.then(() => {
nSQL("note_table").query("delete").where(["id","=",x]).exec();
});
setTimeout(function(){
$('#list').html('');
render();
}, 75);
}
else
return false;
}
}
render();

//Edit an existing data
function edit_data(id) {
var x=parseInt(id);
$(input).val("");
var text = $('li[data-id='+x+']').text();
add_button.hide(250, () => {
note_input.show(250);
input.focus();
});
$(input).val(text);
text = $(input).val();
$('#submit-button').prop('disabled', false);
update_check=1;
update_id=x;
}

//Check if delete or edit button is clicked
$(document).click(function(event) {
if ($(event.target).attr('data-del-id') != undefined) {
delete_data($(event.target).attr('data-del-id'));
}
else if ($(event.target).attr('data-edit-id') != undefined) {
edit_data($(event.target).attr('data-edit-id'));
}
});

//Displaying the data
function render() {
var listed, delete_button, edit_button;
db_connect.then(() => {
return nSQL("note_table").query("select").exec();
}).then((row) => {
for (let i=0;i<row.length;i++) {
if ($('li[data-id='+row[i]['id']+']').length==0) {
listed = $('<li data-id=' + row[i]['id'] + '>' + row[i]['note'] + '</li>');
delete_button = $('<button data-del-id=' + row[i]['id'] + ' class="remove"><i data-del-id=' + row[i]['id'] + ' class="fa fa-trash-o"></i></button>');
edit_button = $('<button data-edit-id=' + row[i]['id'] + ' class="edit"><i data-edit-id=' + row[i]['id'] + ' class="fa fa-pencil"></i></button>');
listed.append(delete_button);
listed.append(edit_button);
$('#list').append(listed);
}
}
});
}

render();
});
});
34 changes: 33 additions & 1 deletion www/stylesheets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,22 @@ main {
height: 100%;
}

.remove{
margin-left: 8px;
border: 0;
color: red;
background: transparent;
vertical-align: middle;
}

.edit {
margin-left: 5px;
border: 0;
background: transparent;
vertical-align: middle;
}

#show{
background-color: darkblue;
color: white;
display: inline-block;
width: 50px;
Expand All @@ -23,6 +37,24 @@ main {
bottom: 15px;
}

#note{
border-top-left-radius: 30px;
border-top-right-radius: 30px;
border-bottom-left-radius: 30px;
border-bottom-right-radius: 30px;
}

#submit-button{
margin: 5px;
border-radius: 50%;
}

#close{
margin: 5px;
border-radius: 50%;
color: white;
}

.list-container {
flex-grow: 1;
overflow-y: auto;
Expand Down