Skip to content

Commit

Permalink
Added angularJS to insert text a caret and clear input as well as liv…
Browse files Browse the repository at this point in the history
…e custom markdown formula preview. Closes #97
  • Loading branch information
michaelplews committed Sep 6, 2016
1 parent 1e4a901 commit 2f64673
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
angular.module('chemicalInventory')
//angular.module('chemicalInventory', ['ngSanitize'])

// Let the user search using an interactive periodic table
.controller('periodicTable', ['$scope', function($scope) {
Expand Down Expand Up @@ -233,3 +234,67 @@ angular.module('chemicalInventory')
});
})};
}])


//Adding characters to a specific point where cursor is in specified element. if cursor in null (element hasn't yet been clicked) then nothing happens
.controller("AddWords", function($scope) {

$scope.lastFocused;
angular.element("input[id='id_formula']").focus(function() {
$scope.lastFocused = document.activeElement;
});

//http://stackoverflow.com/questions/1064089/inserting-a-text-where-cursor-is-using-javascript-jquery
$scope.insertText = function(text) {
var input = $scope.lastFocused;
console.log(input);
if (input == undefined) { return; }
var scrollPos = input.scrollTop;
var pos = 0;
var browser = ((input.selectionStart || input.selectionStart == "0") ?
"ff" : (document.selection ? "ie" : false ) );
if (browser == "ie") {
input.focus();
var range = document.selection.createRange();
range.moveStart ("character", -input.value.length);
pos = range.text.length;
}
else if (browser == "ff") { pos = input.selectionStart };

var front = (input.value).substring(0, pos);
var back = (input.value).substring(pos, input.value.length);
input.value = front+text+back;
pos = pos + text.length;
if (browser == "ie") {
input.focus();
var range = document.selection.createRange();
range.moveStart ("character", -input.value.length);
range.moveStart ("character", pos);
range.moveEnd ("character", 0);
range.select();
}
else if (browser == "ff") {
input.selectionStart = pos;
input.selectionEnd = pos;
input.focus();
}
input.scrollTop = scrollPos;
console.log(angular.element(input).val());
angular.element(input).trigger('input');
}

})


// Provides a preview of the custom markdown in the formula field
.controller('formulaPreview', ['$scope', '$sce', function($scope, $sce) {
$scope.preview = "This is a <sup>test</sup> |H_2O";
$scope.sanitizedPreview = function(input) {
return $sce.trustAsHtml(input
.replace(/<[^>]+>/gm, '') //Removes any pre-existing tags
.replace(/\|/g, "&bull;") //replacing for hydrate
.replace(/_(.){1}/g, "<sub>$1</sub>") //replacing for subscript
.replace(/\^(.)/g, "<sup>$1</sup>") //replacing for superscript
)
};
}])
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ angular.module('chemicalInventory')
newChemical.gloves[i] = newChemical.gloves[i].toString();
}
// Disable the chemical entry if an existing chemical has been selected
inputs = elem.find('.chemical-form input,.chemical-form select,#btn_hydrate,#btn_superscript,#btn_subscript,#btn_clear');
inputs = elem.find('.chemical-form input,.chemical-form select,#hydrate,#superscript,#subscript,#clear');

if (newId > 0) {
inputs.attr('disabled', 'disabled');
Expand Down Expand Up @@ -402,3 +402,30 @@ angular.module('chemicalInventory')
templateUrl: staticUrls.nfpaDiamond,
}
}])

.directive('mark', ['$rootScope', function($rootScope) {
return {
link: function(scope, element, attrs) {
$rootScope.$on('add', function(e, val) {
var domElement = elelment[0];

if (document.selection) {
domElement.focus();
var sel = document.selection.createRange();
sel.text = val;
domElement.focus();
} else if (domElement.selectionStart || domElement.selectionStart === 0) {
var startPos = domElement.selectionStart;
var endPos = domElement.selectionEnd;
var scrollTop = domElement.scrollTop;
domElement.value = domElement.value.substring(0, startPos) + val + domElement.value.substring(endPos, domElement.value.length);
domElement.focus();
domElement.selectionStart = startPos + val.length;
domElement.selectionEnd = staartPos + val.length;
domElement.scrollTop = scrollTop;
} else {
domElement.value += val;
domElement.focus();
}
})}}
}])
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ angular.module('chemicalInventory', ['ngResource', 'ngAnimate', 'toaster', 'ng.d
.config(function($resourceProvider) {
$resourceProvider.defaults.stripTrailingSlashes = false;
})

angular.module('livePreview', ['ngSanitize'])
80 changes: 24 additions & 56 deletions chemical_inventory/templates/chemical_edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,31 @@ <h1>Edit Chemical Information for {{ chemical.name }}</h1>
<dt>{{ field.label_tag }}</dt>
<dd>{{ field }}</dd>
{% if field.auto_id == 'id_formula' %}
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with insert buttons">
<div class="btn-group" role="group" aria-label="Insert Buttons">
<button title="Insert superscript" type="button" id="superscript" class="btn btn-secondary" onclick="insertAtCaret('id_formula','^');return false;"><span class="glyphicon glyphicon-superscript"/></button>
<button title="Insert subscript" type="button" id="subscript" class="btn btn-secondary" onclick="insertAtCaret('id_formula','_');return false;"><span class="glyphicon glyphicon-subscript"/></button>
<button title="Insert hydrate" type="button" id="hydrate" class="btn btn-secondary" onclick="insertAtCaret('id_formula','|H_2O');return false;"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>H<sub>2</sub>O</button>
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with insert buttons">
<div class="btn-group" role="group" aria-label="Insert Buttons" ng-controller="AddWords">
<button title="Insert superscript" type="button" id="superscript" class="btn btn-secondary" ng-click="insertText('^')"><span class="glyphicon glyphicon-superscript"/></button>
<button title="Insert subscript" type="button" id="subscript" class="btn btn-secondary" ng-click="insertText('_')" ><span class="glyphicon glyphicon-subscript"/></button>
<button title="Insert hydrate" type="button" id="hydrate" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown">Hydrate</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#" ng-click="insertText('|H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|2H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>2H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|3H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>3H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|4H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>4H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|5H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>5H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|6H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>6H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|7H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>7H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|8H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>8H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|9H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>9H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|10H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>10H<sub>2</sub>O</a></li>
</ul>
</div>
<div class="btn-group" role="group" aria-label="Second group">
<button title='Clear' type="button" id="clear" class="btn btn-secondary" ng-click="chemical['formula']=''"><span class="glyphicon glyphicon-remove"/></button>
</div>
<div class="btn-group pull-right" role="group" aria-label="Inactive Preview" ng-controller="formulaPreview">
<text title="Preview of formula" type="button" id="formula_preview" class="btn btn-secondary"><strong>Formula Preview: </strong><text ng-bind-html="sanitizedPreview(chemical['formula'])"></text></text>
</div>
</div>
<div class="btn-group" role="group" aria-label="Second group">
<button title='Clear' type="button" id="clear" class="btn btn-secondary" onclick="clearThis('id_formula')"><span class="glyphicon glyphicon-remove"/></button>
</div>
</div>
{% endif %}
{% endfor %}
<!-- Form submission buttons -->
Expand All @@ -50,52 +65,5 @@ <h1>Edit Chemical Information for {{ chemical.name }}</h1>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<script>
$(document).ready(function() {
$('.datepicker').datepicker();
});
</script>
<script>
function clearThis(areaId){
var target = document.getElementById(areaId);
target.value= "";
}
</script>
<!-- From http://stackoverflow.com/questions/1064089/ -->
<script>
function insertAtCaret(areaId,text) {
var txtarea = document.getElementById(areaId);
var scrollPos = txtarea.scrollTop;
var strPos = 0;
var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
"ff" : (document.selection ? "ie" : false ) );
if (br == "ie") {
txtarea.focus();
var range = document.selection.createRange();
range.moveStart ('character', -txtarea.value.length);
strPos = range.text.length;
}
else if (br == "ff") strPos = txtarea.selectionStart;

var front = (txtarea.value).substring(0,strPos);
var back = (txtarea.value).substring(strPos,txtarea.value.length);
txtarea.value=front+text+back;
strPos = strPos + text.length;
if (br == "ie") {
txtarea.focus();
var range = document.selection.createRange();
range.moveStart ('character', -txtarea.value.length);
range.moveStart ('character', strPos);
range.moveEnd ('character', 0);
range.select();
}
else if (br == "ff") {
txtarea.selectionStart = strPos;
txtarea.selectionEnd = strPos;
txtarea.focus();
}
txtarea.scrollTop = scrollPos;
}
</script>

{% endblock %}
35 changes: 25 additions & 10 deletions chemical_inventory/templates/container_add.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,31 @@ <h2>
<dt>{{ field.label_tag }}</dt>
<dd>{{ field }}</dd>
{% if field.auto_id == 'id_formula' %}
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with insert buttons" >
<div class="btn-group" role="group" aria-label="Insert Buttons">
<button title="Insert superscript" type="button" id="btn_superscript" class="btn btn-secondary" onclick="insertAtCaret('id_formula','^');return false;"><span class="glyphicon glyphicon-superscript"/></button>
<button title="Insert subscript" type="button" id="btn_subscript" class="btn btn-secondary" onclick="insertAtCaret('id_formula','_');return false;"><span class="glyphicon glyphicon-subscript"/></button>
<button title="Insert hydrate" type="button" id="btn_hydrate" class="btn btn-secondary" onclick="insertAtCaret('id_formula','|H_2O');return false;"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>H<sub>2</sub>O</button>
</div>
<div class="btn-group" role="group" aria-label="Second group">
<button title='Clear' type="button" id="btn_clear" class="btn btn-secondary" onclick="clearThis('id_formula')"><span class="glyphicon glyphicon-remove"/></button>
</div>
</div>
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with insert buttons">
<div class="btn-group" role="group" aria-label="Insert Buttons" ng-controller="AddWords">
<button title="Insert superscript" type="button" id="superscript" class="btn btn-secondary" ng-click="insertText('^')"><span class="glyphicon glyphicon-superscript"/></button>
<button title="Insert subscript" type="button" id="subscript" class="btn btn-secondary" ng-click="insertText('_')" ><span class="glyphicon glyphicon-subscript"/></button>
<button title="Insert hydrate" type="button" id="hydrate" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown">Hydrate</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#" ng-click="insertText('|H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|2H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>2H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|3H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>3H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|4H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>4H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|5H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>5H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|6H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>6H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|7H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>7H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|8H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>8H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|9H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>9H<sub>2</sub>O</a></li>
<li><a href="#" ng-click="insertText('|10H_2O')"><i class="fa fa-circle" style="font-size:0.4em; vertical-align:middle"></i>10H<sub>2</sub>O</a></li>
</ul>
</div>
<div class="btn-group" role="group" aria-label="Second group">
<button title='Clear' type="button" id="clear" class="btn btn-secondary" ng-click="chemical['formula']=''"><span class="glyphicon glyphicon-remove"/></button>
</div>
<div class="btn-group pull-right" role="group" aria-label="Inactive Preview" ng-controller="formulaPreview">
<text title="Preview of formula" type="button" id="formula_preview" class="btn btn-secondary"><strong>Formula Preview: </strong><text ng-bind-html="sanitizedPreview(chemical['formula'])"></text></text>
</div>
</div>
{% endif %}
</div>
{% endfor %}
Expand Down
1 change: 1 addition & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ <h1>Professor Oak Lab Management</h1>
{% browserid_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular-sanitize.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular-resource.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/0.4.15/toaster.min.js"></script>
Expand Down

0 comments on commit 2f64673

Please sign in to comment.