Annotating Texts and Notetaking With jQuery - Annotator

File Size: 11.9 KB
Views Total: 2853
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Annotating Texts and Notetaking With jQuery - Annotator

Annotator is a powerful jQuery text annotation plugin that helps readers quickly annotate/mark a certain fragment of text with different tags and displays the corresponding note cards in the sidebar.

How to use it:

1. Load the required resources in the document.

<!--Required-->
<script src="/path/to/cdn/jquery.min.js"></script>
<!--Required-->
<script src="/path/to/cdn/popper.min.js"></script>
<!--Optional (used for Templating)-->
<script src="/path/to/cdn/jsrender.min.js"></script>
<!--Optional (used for Semantic UI)-->
<link rel="stylesheet" href="/path/to/cdn/semantic.min.css" />
<script src="/path/to/cdn/semantic.min.js"></script>

2. Load the jQuery Annotator's files in the document.

<!--Annotator CSS-->
<link rel="stylesheet" href="css/annotator.css" />
<!--Annotator jQuery Plugin-->
<script src="js/annotator.js"></script>

3. Add the text to be annotated to the page.

<div class="example" spellcheck="false">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ultricies est ullamcorper enim euismod, ac facilisis tortor ultricies. Quisque interdum enim tortor, hendrerit efficitur nunc sollicitudin non. Phasellus diam ligula, consequat sollicitudin quam vel, laoreet ultrices quam. Etiam varius lectus sagittis placerat finibus.
</div>

<div class="example" spellcheck="false">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ultricies est ullamcorper enim euismod, ac facilisis tortor ultricies. Quisque interdum enim tortor, hendrerit efficitur nunc sollicitudin non. Phasellus diam ligula, consequat sollicitudin quam vel, laoreet ultrices quam. Etiam varius lectus sagittis placerat finibus.
</div>

<div class="example" spellcheck="false">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ultricies est ullamcorper enim euismod, ac facilisis tortor ultricies. Quisque interdum enim tortor, hendrerit efficitur nunc sollicitudin non. Phasellus diam ligula, consequat sollicitudin quam vel, laoreet ultrices quam. Etiam varius lectus sagittis placerat finibus.
</div>

4. Create the html for the text annotations.

<div id="annotations_list">
  <div class="ui info message">
    <div class="header">
      Not sure what to do?
    </div>
    <p>
      Select some text from the <strong>Transcript</strong>, choose a
      <strong>Tag</strong> and hit <strong>Save</strong>.
    </p>
  </div>
</div>

5. Create the html for the Annotator Popover.

<!--Annotator Popover Contents-->
<div id="annotate_settings" class="ui form raised segments" style="display: none">
  <!--Notes-->
  <div class="required field p-around_small">
    <label>Type some notes</label>
    <textarea rows="5" onchange="App.handlers.captureNotes( this )"></textarea>
  </div>
  <!--Tags-->
  <div class="p-around_small m-bottom_medium">
    <div class="ui dropdown labeled icon fluid button">
      <i class="tag icon"></i>
      <span class="text">Select a Tag</span>
      <div class="menu">
        <div class="ui icon search input">
          <i class="search icon"></i>
          <input type="text" placeholder="Search tags...">
        </div>
        <div class="divider"></div>
        <div class="header">
          <i class="tags icon"></i>
          Tag Label
        </div>
        <div class="scrolling menu">
          <div name="Requirement" class="item">
            <div class="ui orange empty circular label"></div>
            Requirement
          </div>
          <div name="Backlog" class="item">
            <div class="ui teal empty circular label"></div>
            Backlog
          </div>
          <div name="Internal" class="item">
            <div class="ui blue empty circular label"></div>
            Internal
          </div>
        </div>
      </div>
    </div>
  </div>
  <!--Action Buttons-->
  <div class="field p-around_small m-bottom_medium">
    <button class="ui right floated olive button" onclick="App.handlers.saveAnnotation();">Save</button>
    <button class="ui left floated button" onclick="App.handlers.cancelAnnotation();">Cancel</button>
  </div>
  <!--Placeholder-->
  <div class="field p-around_small m-bottom_medium">
  </div>
  <!--Arrow-->
  <div id="arrow" data-popper-arrow></div>
</div>

6. The JavaScript to enable the Annotator.

var App = {
  elements: {
    tags: null
  },
  constants: {
    errors: {
      MISSING_FIELDS: {
        heading: "Required Fields Missing",
        message: "Please make sure you specify a Note and select a Tag"
      },
      INSUFFICIENT_CHARS: {
        heading: "Insufficient Characters",
        message: "Please select atleast 10 characters"
      }
    }
  },
  variables: {
    messageDisplayed: false
  },
  helpers: {
    resetControls: function() {
      App.elements.tags.dropdown("clear").dropdown("set text", "Select Tag");
      $("textarea").val("");
    },
    showBackdrop: function(isShown) {
      $(".backdrop")[isShown ? "show" : "hide"]();
    },
    showError: function(error) {
      if (!App.variables.messageDisplayed) {
        App.variables.messageDisplayed = true;

        $("#error_message").find(".header").html(error.heading);
        $("#error_message").find(".message").html(error.message);

        $("#error_message").transition("fly down");

        window.setTimeout(
          function() {
            App.variables.messageDisplayed = false;

            $("#error_message").transition("fly up");
          },
          5000
        );
      }
    }
  },
  handlers: {
    fillNotes: function(selection) {
      $("textarea").val(selection).trigger("change");
    },
    captureNotes: function(text) {
      $.Annotator.api.captureActiveAnnotationNotes(text.value);
    },
    applyTag: function(tagName) {
      $.Annotator.api.tagActiveAnnotation(tagName);
    },
    cancelAnnotation: function() {
      App.helpers.resetControls();
      App.helpers.showBackdrop(false);

      $.Annotator.api.destroyActiveAnnotation();
    },
    saveAnnotation: function() {
      var result = $.Annotator.api.saveActiveAnnotation();

      if (!result.isSaved) {
        App.helpers.showError(App.constants.errors[result.errorCode]);
      } else {
        App.helpers.resetControls();
        App.helpers.showBackdrop(false);
      }
    },
    renderSavedAnnotations: function(annotations) {
      var html = $.templates("#annotations_tmpl").render({
        annotations: annotations.map((item) => {
          if (item.type === "Requirement") {
            item.color = "orange";
          } else if (item.type === "Backlog") {
            item.color = "teal";
          } else {
            item.color = "blue";
          }

          return item;
        })
      });

      $("#annotations_list").html(html);
    },
    deleteAnnotation: function(annotationId) {
      var remainingAnnotations =
        $.Annotator.api.deleteAnnotation(annotationId);

      App.handlers.renderSavedAnnotations(remainingAnnotations);
    }
  },
  init: function() {
    $(".example").annotator({
      popoverContents: "#annotate_settings",
      minimumCharacters: 10,
      makeTextEditable: true,
      onannotationsaved: function() {
        App.handlers.renderSavedAnnotations(this.annotations);
      },
      onselectioncomplete: function() {
        App.handlers.fillNotes(this.outerText);
        App.helpers.showBackdrop(true);
      },
      onerror: function() {
        App.helpers.showError(App.constants.errors[this]);
      }
    });

    App.elements.tags = $(".ui.dropdown")
      .dropdown({
        clearable: true,
        direction: "upward",
        onChange: function(value, text, $choice) {
          if ($choice)
            App.handlers.applyTag($choice.attr("name"));
        }
      });
  }
};

App.init();

This awesome jQuery plugin is developed by Deepak-K-Anand. For more Advanced Usages, please check the demo page or visit the official website.