<!DOCTYPE html>
<html ng-app="x">
<head>
<meta charset="utf-8" />
<title>UI.Codemirror : demo </title>
<!-- Le css -->
<link rel="stylesheet" type="text/css" href="http://codemirror.net/lib/codemirror.css"/>
</head>
<body>
<!-- Le content... -->
<section ng-controller="CodemirrorCtrl">
<p>Non Repeating Version</p>
<div ui-codemirror="piecesOfCode[0].options" ng-model="piecesOfCode[0].code"></div>
<div ng-repeat="c in piecesOfCode">
<p>Code should be: {{c.code}}</p>
<div ui-codemirror="c.options" ng-model="c.code"></div>
</div>
</section>
<!-- Le vendor... -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<script src="http://codemirror.net/lib/codemirror.js"></script>
<script src="http://codemirror.net/mode/scheme/scheme.js"></script>
<script src="http://codemirror.net/mode/javascript/javascript.js"></script>
<script src="http://codemirror.net/mode/xml/xml.js"></script>
<script src="ui-codemirror.js"></script>
<script src="app.js"></script>
</body>
</html>
var app = angular.module('x', ['ui.codemirror']);
app.controller('CodemirrorCtrl', ['$scope', function($scope) {
$scope.piecesOfCode = [
{
code: ";; Scheme code in here.\n" +
"(define (double x)\n\t(* x x))\n",
options: {mode: "scheme", lineNumbers: true, indentWithTabs: true}
},
{
code: '<!-- XML code in here. -->\n' +
'<root>\n\t<foo>\n\t</foo>\n\t<bar/>\n</root>',
options: {mode: "xml", lineNumbers: true, indentWithTabs: true}
},
{
code: '// Javascript code in here.\n' +
'function foo(msg) {\n\tvar r = Math.random();\n\treturn "" + r + " : " + msg;\n}',
options: {mode: "javascript", lineNumbers: true, indentWithTabs: true}
}
];
}]);
/**
* Binds a CodeMirror widget to a <textarea> element.
*/
angular.module('ui.codemirror', [])
.constant('uiCodemirrorConfig', {})
.directive('uiCodemirror', ['uiCodemirrorConfig', function (uiCodemirrorConfig) {
'use strict';
return {
restrict: 'EA',
require: '?ngModel',
compile: function compile(tElement, tAttrs, transclude) {
// Require CodeMirror
if (angular.isUndefined(window.CodeMirror)) {
throw new Error('ui-codemirror need CodeMirror to work... (o rly?)');
}
var value = tElement.text();
return function postLink(scope, iElement, iAttrs, ngModel) {
// Create a codemirror instance with
// - the function that will to place the editor into the document.
// - the initial content of the editor.
// see http://codemirror.net/doc/manual.html#api_constructor
var codeMirror = new CodeMirror(function (cm_el) {
iElement.append(cm_el);
}, {value: value});
var options, opts, onChange;
options = uiCodemirrorConfig.codemirror || {};
opts = angular.extend({}, options, scope.$eval(iAttrs.uiCodemirror), scope.$eval(iAttrs.uiCodemirrorOpts));
function updateOptions(newValues) {
for (var key in newValues) {
if (newValues.hasOwnProperty(key)) {
codeMirror.setOption(key, newValues[key]);
}
}
}
updateOptions(opts);
if (angular.isDefined(scope[iAttrs.uiCodemirror])) {
scope.$watch(iAttrs.uiCodemirror, updateOptions, true);
}
// Specialize change event
codeMirror.on("change", function (instance, changeObj) {
var newValue = instance.getValue();
if (ngModel && newValue !== ngModel.$viewValue) {
ngModel.$setViewValue(newValue);
}
if (!scope.$$phase) {
scope.$apply();
}
});
if (ngModel) {
// CodeMirror expects a string, so make sure it gets one.
// This does not change the model.
ngModel.$formatters.push(function (value) {
if (angular.isUndefined(value) || value === null) {
return '';
}
else if (angular.isObject(value) || angular.isArray(value)) {
throw new Error('ui-codemirror cannot use an object or an array as a model');
}
return value;
});
// Override the ngModelController $render method, which is what gets called when the model is updated.
// This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
ngModel.$render = function () {
//Code mirror expects a string so make sure it gets one
//Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive)
var safeViewValue = ngModel.$viewValue || '';
codeMirror.setValue(safeViewValue);
};
}
// Watch ui-refresh and refresh the directive
if (iAttrs.uiRefresh) {
scope.$watch(iAttrs.uiRefresh, function (newVal, oldVal) {
// Skip the initial watch firing
if (newVal !== oldVal) {
codeMirror.refresh();
}
});
}
// onLoad callback
if (angular.isFunction(opts.onLoad)) {
opts.onLoad(codeMirror);
}
};
}
};
}]);