Skip to content

Commit 0a29fcd

Browse files
Dimitar DyakovDimitar Dyakov
Dimitar Dyakov
authored and
Dimitar Dyakov
committed
Initial commit
1 parent 7205e37 commit 0a29fcd

10 files changed

+517
-0
lines changed

App/css/bootstrap.min.css

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

App/css/style.css

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
body {
2+
padding-top: 20px;
3+
padding-bottom: 20px;
4+
}
5+
6+
.header,
7+
.marketing,
8+
.footer {
9+
padding-right: 15px;
10+
padding-left: 15px;
11+
}
12+
13+
.header {
14+
padding-bottom: 20px;
15+
border-bottom: 1px solid #e5e5e5;
16+
}
17+
18+
.header h3 {
19+
margin-top: 0;
20+
margin-bottom: 0;
21+
line-height: 40px;
22+
}
23+
24+
.footer {
25+
padding-top: 19px;
26+
color: #777;
27+
border-top: 1px solid #e5e5e5;
28+
}
29+
30+
@media (min-width: 768px) {
31+
.container {
32+
max-width: 730px;
33+
}
34+
}
35+
36+
.container-narrow > hr {
37+
margin: 30px 0;
38+
}
39+
40+
.jumbotron {
41+
text-align: center;
42+
border-bottom: 1px solid #e5e5e5;
43+
}
44+
45+
.jumbotron .btn {
46+
padding: 14px 24px;
47+
font-size: 21px;
48+
}
49+
50+
.marketing {
51+
margin: 40px 0;
52+
}
53+
54+
.marketing p + h4 {
55+
margin-top: 28px;
56+
}
57+
58+
@media screen and (min-width: 768px) {
59+
.header,
60+
.marketing,
61+
.footer {
62+
padding-right: 0;
63+
padding-left: 0;
64+
}
65+
66+
.header {
67+
margin-bottom: 30px;
68+
}
69+
70+
.jumbotron {
71+
border-bottom: 0;
72+
}
73+
}
19.7 KB
Binary file not shown.

App/fonts/glyphicons-halflings-regular.svg

+288
Loading
44.3 KB
Binary file not shown.
22.9 KB
Binary file not shown.
17.6 KB
Binary file not shown.

App/index.html

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2+
<!DOCTYPE html>
3+
<html lang="en">
4+
<head>
5+
<meta charset="utf-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
<title>My Bookmarker</title>
9+
10+
<link href="css/bootstrap.min.css" rel="stylesheet">
11+
<link href="css/style.css" rel="stylesheet">
12+
</head>
13+
14+
<body onload="fetchBookmarks()">
15+
16+
<div class="container">
17+
<div class="header clearfix">
18+
<h3 class="text-muted">My Bookmarker</h3>
19+
</div>
20+
21+
<div class="jumbotron">
22+
<h2>Bookmark Your Favourite Sites</h2>
23+
24+
<form id="postForm" name="postForm">
25+
<div id="validation-result" class="alert alert-danger" hidden="hidden"></div>
26+
<div class="form-group">
27+
28+
<label>Site Name</label>
29+
<input type="text" class="form-control" id="siteName" placeholder="Website Name" />
30+
</div>
31+
<div class="form-group">
32+
<label>Site URL</label>
33+
<input type="text" class="form-control" id="siteUrl" placeholder="Website URL" />
34+
</div>
35+
36+
<button type="submit" class="btn btn-primary">Add Bookmark</button>
37+
</form>
38+
</div>
39+
40+
<div class="row marketing">
41+
<div class="col-lg-12">
42+
<div id="bookmarksResults">
43+
44+
</div>
45+
</div>
46+
</div>
47+
48+
<footer class="footer">
49+
<p>&copy; 2016 My Bookmarker, Inc.</p>
50+
</footer>
51+
52+
</div>
53+
54+
<script srv="js/bootstrap.min.js "></script>
55+
<script src="js/main.js"></script>
56+
<script
57+
src="https://code.jquery.com/jquery-3.1.1.js"
58+
integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
59+
crossorigin="anonymous">
60+
</script>
61+
62+
</body>
63+
</html>

App/js/bootstrap.min.js

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

App/js/main.js

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
document.getElementById('postForm').addEventListener('submit', addBookmark);
2+
3+
function addBookmark(e) {
4+
var siteName = document.getElementById('siteName').value;
5+
var siteUrl = document.getElementById('siteUrl').value;
6+
var error = document.getElementById('validation-result');
7+
8+
if (!siteName || !siteUrl) {
9+
error.innerHTML = '<strong>Please fill in the form</strong>';
10+
error.removeAttribute('hidden');
11+
12+
return false;
13+
}
14+
var expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
15+
var regex = new RegExp(expression);
16+
17+
if (!siteUrl.match(regex)) {
18+
error.innerHTML = '<strong>Invalid URL</strong>';
19+
error.removeAttribute('hidden');
20+
21+
return false;
22+
}
23+
24+
var bookmark = {
25+
name: siteName,
26+
url: siteUrl
27+
};
28+
29+
if (localStorage.getItem('bookmarks') === null) {
30+
var bookmarks = [];
31+
32+
bookmarks.push(bookmark);
33+
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
34+
} else {
35+
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
36+
bookmarks.push(bookmark);
37+
38+
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
39+
}
40+
41+
fetchBookmarks();
42+
43+
document.postForm.reset();
44+
//Prevent form from submitting
45+
e.preventDefault();
46+
}
47+
48+
function deleteBookmark(url){
49+
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
50+
51+
for (var i = 0; i < bookmarks.length; i++) {
52+
if (bookmarks[i].url == url) {
53+
bookmarks.splice(i, 1);
54+
}
55+
}
56+
57+
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
58+
59+
fetchBookmarks();
60+
}
61+
62+
function fetchBookmarks() {
63+
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
64+
var bookmarksResults = document.getElementById('bookmarksResults');
65+
66+
bookmarksResults.innerHTML = '';
67+
for (var i = 0; i < bookmarks.length; i++) {
68+
var name = bookmarks[i].name;
69+
var url = bookmarks[i].url;
70+
71+
bookmarksResults.innerHTML += '<div class="well">' +
72+
'<h3>' + name +
73+
' <a class="btn btn-primary" target="_blank" href="'+ url + '">Visit</a> ' +
74+
' <a onclick="deleteBookmark(\''+url+'\')" class="btn btn-danger pull-right" href="#">Delete</a> '
75+
'</h3>' +
76+
'</div>';
77+
}
78+
79+
}
80+

0 commit comments

Comments
 (0)