Enhanced Bookmark Functionality

Discussions about the Notes and Journal tool on LDS.org. This includes the Study Toolbar as well as the scriptures and other content on LDS.org that is integrated with Notes and Journal.
Post Reply
boushley
New Member
Posts: 6
Joined: Sat Jan 14, 2012 5:53 pm

Enhanced Bookmark Functionality

#1

Post by boushley »

I really like the features of the Study Notebook, however the bookmarks don't function quite like I would like them to. As far as I can tell there is no way to move bookmarks between articles / chapters. I'm not sure if this is by design, hasn't been implemented yet or if I just couldn't find the functionality. The situation I'm trying to fulfill is that I want a "Daily Book of Mormon" bookmark and a "Sunday School" bookmark that allow me to move them to where I'm at.

I've implemented something on my own that gives the basic functionality that I'm looking for. The js script here when loaded on a lds.org page with the study toolbar extends the bookmarks list to provide this functionality. Now when you click on "Bookmarks" in the study toolbar you can drag one of the items in the list onto the current page. The code will then update the bookmark so that it is on this new page.

Currently I'm using this in Google Chrome using this extension to put the script onto all pages that are part of lds.org. If there are bugs people would like fixed or people are interested, I can turn this into a Chrome extension. Ideally it would be nice to see this get picked up and included as part of the study notebook itself.
jdlessley
Community Moderators
Posts: 9858
Joined: Mon Mar 17, 2008 12:30 am
Location: USA, TX

#2

Post by jdlessley »

We can discuss this in the forums, but to get it before the development team is by using the Submit Feedback link on LDS.org.
JD Lessley
Have you tried finding your answer on the ChurchofJesusChrist.org Help Center or Tech Wiki?
boushley
New Member
Posts: 6
Joined: Sat Jan 14, 2012 5:53 pm

#3

Post by boushley »

Thanks for pointing that out. I submitted it as feedback, but wanted to get it out here just in case anyone else was looking for similar functionality.
ndaman
New Member
Posts: 2
Joined: Tue Mar 06, 2012 8:21 am

#4

Post by ndaman »

This is an amazing idea while we wait for the development team to add the feature, I'm not so good at javascript, though, and I'm having trouble getting it to work. All I've done is paste your code into the javascript section of Personalized Web and made a little regex for the lds website, and I get this error on the javascript console: [PersonalizedWeb] Exception in custom JS code.
ReferenceError: jQuery is not defined
I tried adding some html to load jQuery but that didn't seem to work either. Thanks for this awesome script, I can't wait to get it working!
boushley
New Member
Posts: 6
Joined: Sat Jan 14, 2012 5:53 pm

#5

Post by boushley »

At the end of this post I've attached the PersonalizedWeb rule dump. You can load that dump and it should work for you. You have to embed it as 'Add HTML' so that it is in the same domain as the pages javascript. Try loading this rule, and let me know how that goes.

{"name":"LDS Bookmarks","urlRegex":"^https://(www\\.)?lds\\.org","urlExcludeRegex":"","enabled":true,"preserveDocWrite":false,"css":"","html":"<script type=\"text/javascript\">\n(function ($, undefined) {\n \u0020 \u0020if ((location.hostname !== 'lds.org' && location.hostname !== 'www.lds.org' ) || location.protocol !== 'https:')\n \u0020 \u0020 \u0020 \u0020return;\n\n \u0020 \u0020window.ExtendedLDSBookmarks = { };\n\n \u0020 \u0020var model = ExtendedLDSBookmarks.model = {\n \u0020 \u0020 \u0020 \u0020DRAG_THRESHOLD: 30,\n\n \u0020 \u0020 \u0020 \u0020bookmarks: null,\n \u0020 \u0020 \u0020 \u0020studyToolbar: null,\n\n \u0020 \u0020 \u0020 \u0020dragDeltaMet: false,\n \u0020 \u0020 \u0020 \u0020draggingStart: {x: null, y: null},\n \u0020 \u0020 \u0020 \u0020draggingBookmark: null,\n \u0020 \u0020 \u0020 \u0020startDraggingBookmark: function (id) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020for (var i = 0; i < this.bookmarks.length; i++) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (this.bookmarks.id === id)\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020{\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020this.draggingBookmark = this.bookmarks;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020break;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020 \u0020 \u0020},\n \u0020 \u0020 \u0020 \u0020stopDraggingBookmark: function () {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020this.draggingBookmark = null;\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020addObserver: function (callback) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020this.callbacks = this.callbacks || [];\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020this.callbacks.push(callback);\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020notifyObservers: function (parameters) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (this.callbacks) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var l = this.callbacks.length;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020for (var i=0; i < l; i++) this.callbacks(parameters);\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020getDefaultTitle: function () {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020return defaultTitle = $.trim($('title').html().replace(' ',' '));\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020getPageBaseUri: function () {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020return document.location.pathname.replace(/\\..*/,'');\n \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020};\n\n \u0020 \u0020var commands = ExtendedLDSBookmarks.commands = {\n \u0020 \u0020 \u0020 \u0020initialize: function () {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020console.log('Initializing Extended LDS Bookmarks');\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020this.loadToolbarInformation();\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020views.initialize();\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020loadToolbarInformation: function () {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.studyToolbar = $('body').data().studyToolbar;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (model.studyToolbar && model.studyToolbar.options)\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.bookmarks = model.studyToolbar.options.bookmarks;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (!model.studyToolbar || !model.Bookmarks)\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020setTimeout(commands.loadToolbarInformation, 100);\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020startDraggingBookmark: function (id) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.startDraggingBookmark(id);\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020processBookmarkPlacement: function (placementPosition) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var paragraph = $(model.studyToolbar.findParagraph(placementPosition, 'p[uri^=\"' + model.getPageBaseUri() + '\"]'));\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var bookmark = model.draggingBookmark;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var uri = paragraph.attr('uri');\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var pageUri = document.location.pathname;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020// TODO Handle title updating\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020// However, for bookmarks being moved between areas I expect they'll have a more meaningful\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020// title. Like Sunday School Reading or Daily Scripture Study\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020SERVICE.ANNOTATIONS.save({\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020id: bookmark.id,\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020data: {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020title: bookmark.title,\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020note: bookmark.note,\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020folders: bookmark.folderGuids,\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020tags: bookmark.tags,\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020source: (bookmark.source !== undefined) ? bookmark.source : '',\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020device: (bookmark.device !== undefined) ? bookmark.device : '',\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020pageUri : pageUri,\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020uri : uri\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020},\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020callback: function(data) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (model.studyToolbar.handleAjaxResponse(data)) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.studyToolbar.bookmark(data.response.annotation);\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.studyToolbar.resetBookmarkForm(true);\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020});\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.stopDraggingBookmark();\n \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020};\n\n \u0020 \u0020var views = ExtendedLDSBookmarks.views = {\n \u0020 \u0020 \u0020 \u0020initialize: function () {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var toolbar = $('#saveAndShareToolbar');\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020$('#bookmark-box .bookmark-list ul li', toolbar).live('mousedown', views.startDragging);\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020views.topOffset = $('#content').offset().top;\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020startDragging: function (e) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020commands.startDraggingBookmark($(this).attr('id'));\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.dragDeltaMet = false;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.draggingStart.x = e.pageX;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.draggingStart.y = e.pageY;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020$(document).bind('mousemove', views.mouseMove);\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020$(document).bind('mouseup', views.stopDragging);\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020e.stopImmediatePropagation();\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020return false;\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020mouseMove: function (e) {\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (!model.dragDeltaMet) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var currentPoint = {x: e.pageX, y: e.pageY};\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (util.distance(model.draggingStart, currentPoint) > model.DRAG_THRESHOLD)\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020{\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020model.dragDeltaMet = true;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020views.mark = $('<div></div>').addClass('bookmark').css({\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020'top': e.pageY - views.topOffset\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}).appendTo('#primary');\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020}\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (model.dragDeltaMet)\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020views.mark.css({'top': e.pageY - views.topOffset});\n \u0020 \u0020 \u0020 \u0020},\n\n \u0020 \u0020 \u0020 \u0020stopDragging: function (e) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020if (model.dragDeltaMet)\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020 \u0020commands.processBookmarkPlacement(e.pageY);\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020$(document).unbind('mousemove', views.mouseMove);\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020$(document).unbind('mouseup', views.stopDragging);\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020views.mark = null;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020e.stopImmediatePropagation();\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020return false;\n \u0020 \u0020 \u0020 \u0020},\n \u0020 \u0020};\n\n \u0020 \u0020commands.initialize();\n\n \u0020 \u0020// Utility function\n \u0020 \u0020ExtendedLDSBookmarks.util = util = {\n \u0020 \u0020 \u0020 \u0020distance: function (point1, point2) {\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var xSquare = point2.x - point1.x;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020xSquare *= xSquare;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020var ySquare = point2.y - point1.y;\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020ySquare *= ySquare;\n\n \u0020 \u0020 \u0020 \u0020 \u0020 \u0020return Math.sqrt(xSquare + ySquare);\n \u0020 \u0020 \u0020 \u0020}\n \u0020 \u0020};\n})(jQuery)\n</script>","js":"","filters":[]}
ndaman
New Member
Posts: 2
Joined: Tue Mar 06, 2012 8:21 am

#6

Post by ndaman »

Works like a champ, thanks again for the wonderful code!
boushley
New Member
Posts: 6
Joined: Sat Jan 14, 2012 5:53 pm

#7

Post by boushley »

Glad to hear it! Hopefully it will get integrated into the site.
User avatar
barkeraj
Church Employee
Church Employee
Posts: 175
Joined: Thu Nov 09, 2006 9:15 am
Location: Springville, UT

#8

Post by barkeraj »

We know that the bookmark functionality is a bit wonky (technical term). Bookmark has different meanings to different people. There are bookmarks that the browser has, which is always the same, and bookmarks used in a book which you update regularly.

We do have a bit of an overhaul to the study tools coming in an unspecified point in the future (hint, before the millenium) where we will make sure to address both desires.
Aaron Barker
Front-end Development Lead for LDS.org (content portions, not apps) and Ward Executive Secretary.
boushley
New Member
Posts: 6
Joined: Sat Jan 14, 2012 5:53 pm

#9

Post by boushley »

Glad to hear there is an overhaul. Hopefully this functionality will be built in. The ability to just pull a bookmark from the bookmark list and place it on the screen is awesome. I assumed that highlights filled the bookmarks like browser bookmarks area. Especially since you could already move bookmarks within the given page, so I just reused that api to move bookmarks between pages.

I look forward to the new work.
rrichey4430
New Member
Posts: 7
Joined: Sun Sep 18, 2011 10:10 pm

Re: Enhanced Bookmark Functionality

#10

Post by rrichey4430 »

This used to work for me (after a few tweaks) but no longer works. When I get some time I will troubleshoot I will try to figure out what the problem is. Anyone else using this successfully in 2016?
Post Reply

Return to “Notes and Journal, and Online Scriptures”