Since a few days I'm looking for a non-html (markdown, bbcode) WYSIWYG really minimalist for a kind of forum.
I just need to allow users to add links, bold italic and break line in a non html way.
But all I can found is some dirty old wysiwyg with too many functionality and without directives for angularjs or just html wysiwyg..
Do you have any suggestions ?
At this time I'm thinking that I should make it by myself.
Thank you in advance for any responses.
Have a look on this example implemented in AngularJs; You can customise and convert it into Angular module as per your need;
Example
angular.module("myApp", [])
.directive("click", function () {
return {
restrict: "A",
link: function (scope, element, attrs) {
element.bind("click", function () {
scope.$evalAsync(attrs.click);
});
}
};
})
.controller("Example", function ($scope) {
$scope.supported = function (cmd) {
var css = !!document.queryCommandSupported(cmd.cmd) ? "btn-succes" : "btn-error"
return css
};
$scope.icon = function (cmd) {
return (typeof cmd.icon !== "undefined") ? "fa fa-" + cmd.icon : "";
};
$scope.doCommand = function (cmd) {
if ($scope.supported(cmd) === "btn-error") {
alert("execCommand(“" + cmd.cmd + "”)\nis not supported in your browser");
return;
}
val = (typeof cmd.val !== "undefined") ? prompt("Value for " + cmd.cmd + "?", cmd.val) : "";
document.execCommand(cmd.cmd, false, (cmd.val || ""));
}
$scope.commands = commands;
$scope.tags = [
'Bootstrap', 'AngularJS', 'execCommand'
]
})
Related
I have 2 different directives. The first one is returns an iframe with a live video, and the second returns an iframe with a recent video.
The condition is: if live content is present, append live directive, else append recent video directive.
Ive tried with normal html instead of the directives and it works, but when i put the directive element, unfortunately doesnt work.
WORKING
controller.js
function isLiveOn() {
var liveIframe = '<h2>LIVE</h2>';
var videoIframe = '<h2>VIDEO</h2>';
if (vm.live.items[0] != undefined) {
$('.iframe-container').append(liveIframe);
} else {
$('.iframe-container').append(videoIframe);
}
};
NOT WORKING
controller.js
function isLiveOn() {
var liveIframe = '<live-iframe live="vm.live.items[0]"></live-iframe>';
var videoIframe = '<last-video video="vm.activity.items[0]"></last-video>';
if (vm.live.items[0] != undefined) {
$('.iframe-container').append(liveIframe);
} else {
$('.iframe-container').append(videoIframe);
}
};
Each directive has its own html and js file.
Something like that:
directive.html
<div class="live">
<iframe ng-src="{{getIframeSrc(live.id.videoId)}}"></iframe>
</div>
<div class="live-description">
<h4>{{live.snippet.title}}</h4>
</div>
directive.js
app.directive('live', live);
live.$inject = ['$window'];
function live($window) {
var directive = {
link: link,
restrict: 'EA',
templateUrl: 'path',
scope: {
live: '='
}
};
return directive;
function link(scope, element, attrs) {
scope.getIframeSrc = function(id) {
return 'https://www.youtube.com/embed/' + id;
};
}
}
So im thinking its some problem with the directives that im probably missing.
Any help will be appreciated!
Instead of handling the logic in the controller you can control it in UI as it will be easier.
-----Other Html Codes-----
<live-iframe ng-if="vm.live.items[0]" live="vm.live.items[0]"></live-iframe>
<last-video ng-if="!vm.live.items[0]" video="vm.activity.items[0]"></last-video>
-----Other Html Codes-----
And you can remove following lines of code from the controller
var liveIframe = '<live-iframe live="vm.live.items[0]"></live-iframe>';
var videoIframe = '<last-video video="vm.activity.items[0]"></last-video>';
if (vm.live.items[0] != undefined) {
$('.iframe-container').append(liveIframe);
} else {
$('.iframe-container').append(videoIframe);
}
I am using imgcache.js and a custom directive to download images and save locally to use it offline.
Libraries:
https://github.com/chrisben/imgcache.js
https://github.com/sunsus/ngImgCache/
The case is that I need to apply a background image to the content (normally we apply a background-image to the .scroll-content class) and in css we can't use the directive or the service to save the file locally.
I know the imgcache.js library has a function named: ImgCache.cacheBackground(), but I don't know how to use it and apply the local file to .scroll-content.
Please, any help? Any example?
I've found a way to implement cache using: https://github.com/chrisben/imgcache.js
I've applied the image to the .scroll-content:
.scroll-content{
background-image: url(http://test.com/background.jpg);
}
And created a directive:
.directive('cacheBackground', function($timeout) {
return {
restrict: 'A',
link: function(scope, el, attrs) {
// timeout to give time to init imgCache
$timeout(function() {
ImgCache.isBackgroundCached(el, function(path, success) {
if (success) {
ImgCache.useCachedBackground(el);
} else {
ImgCache.cacheBackground(el, function() {
ImgCache.useCachedBackground(el);
});
}
});
}, 200);
}
};
})
Modified DomHelpers.getBackgroundImage in imgCache.js to use getComputedStyle even when we have jQueryLite:
DomHelpers.getBackgroundImage = function (element) {
if (ImgCache.jQuery) {
return element.attr('data-old-background') ? "url(" + element.attr('data-old-background') + ")" : element.css('background-image');
} else if (ImgCache.jQueryLite) {
var style = window.getComputedStyle(element[0], null);
if (!style) {
return;
}
return element[0].getAttribute("data-old-background") ? "url(" + element[0].getAttribute("data-old-background") + ")" : style.backgroundImage;
} else {
var style = window.getComputedStyle(element, null);
if (!style) {
return;
}
return element.getAttribute("data-old-background") ? "url(" + element.getAttribute("data-old-background") + ")" : style.backgroundImage;
}
};
And then I've applied the directive to ion-content in my view:
And now the background-image is working offline too.
Thank you!
I'm writing an AngularJS application and I'm searching for a way to unit test every single aspect.
In this particular case, I need to unit test a custom directive which I've written that represents a control.
The directive can be found here:
var officeButton = angular.module('OfficeButton', []);
officeButton.directive('officeButton', function() {
return {
restrict: 'E',
replace: false,
scope: {
isDefault: '#',
isDisabled: '#',
control: '=',
label: '#'
},
template: '<div class="button-wrapper" data-ng-click="onClick()">' +
'<a href="#" class="button normal-button">' +
'<span>{{label}}</span>' +
'</a>' +
'</div>',
controller: ['$scope', function($scope) {
var event = this;
var api = {
changeLabel: function(label) {
$scope.label = label;
},
enable: function() {
$scope.isDisabled = false;
},
disable: function() {
$scope.isDisabled = true;
},
setAsDefault: function() {
$scope.isDefault = true;
},
removeDefault: function() {
$scope.isDefault = false;
}
};
event.onClick = function() {
if (typeof $scope.control.onClick === 'function') { $scope.control.onClick(); }
};
$.extend($scope.control, api);
function Init() {
if ($scope.isDefault === 'true') { $scope.isDefault = true; }
else { $scope.isDefault = false; }
}
Init();
}],
link: function(scope, element, attributes, controller) {
scope.$watch('isDefault', function(value) {
if (value === 'true' || value) { $('a', element).addClass('button-default'); }
else { $('a', element).removeClass('button-default'); }
});
scope.onClick = function() { controller.onClick(); }
}
}
});
This directive can be called by using the following HTML snippet:
<office-button label="Office Web Controls" control="buttonController"></office-button>
Now, this directive exposes an API which functions such as changeLabel, enable, disable, ....
Now, those functions are not defined on the load of the application, meaning if at the bottom of my HTML I call the following code:
$scope.buttonController.changeLabel('Office Web Controls for Web Applications Directive Demo');
It will throw an error because the changeLabel() method is not defined.
In order to make it function, I need to wrap those calls in an angular.ready function, such as:
angular.element(document).ready(function () {
$scope.buttonController.changeLabel('Office Web Controls for Web Applications Directive Demo');
});
Here's a plunker for your information.
Now, I'm writing unit tests using Jasmine, and here's what I have for the moment:
describe('Office Web Controls for Web Applications - Button Testing.', function() {
// Provides all the required variables to perform Unit Testing against the 'button' directive.
var $scope, element;
var buttonController = {};
// Loads the directive 'OfficeButton' before every test is being executed.
beforeEach(module('OfficeButton'));
// Build the element so that it can be called.
beforeEach(inject(function($rootScope, $compile) {
// Sets the $scope variable so that it can be used in the future.
$scope = $rootScope;
$scope.control = buttonController;
element = angular.element('<office-button control="buttonController"></office-button>');
$compile(element)($scope);
$scope.$digest();
}));
it('Should expose an API with certain functions.', function() {
});
});
Now, in the it function, I would like to test if the $scope.control does expose the API as defined in the directive.
The problem is that the page needs to be ready before the API is available.
Any tought on how to change the code or how to unit test this correctly?
I've found the issue, it was just a wrong configuration on the unit test.
When using this code:
$scope.control = buttonController;
element = angular.element('<office-button control="buttonController"></office-button>');
I must change the element to:
$scope.control = buttonController;
element = angular.element('<office-button control="control"></office-button>');
I got any application where I need to display file from urls I got in database. Now this file can be an image and it can be a pdf. So I need to set some binding dynamically. I looked on internet and object tag looked promising but it is not working in IE11. It is working fine in Chrome and Firefox. SO that is why I am asking here for help.
I have created a directive just to make sure If we have to do any dom manipulation. Here goes my directive code.
mainApp.directive("displayFile", function () {
return {
restrict: 'AE', // only activate on element attribute
scope: {
displayFile: "=",
fileType:"="
},
link: function (scope, elem, attrs) {
scope.filePath = "";
var element = angular.element(elem);
// observe the other value and re-validate on change
scope.$watch('displayFile', function (val) {
if (val !== "") {
scope.filePath = val;
scope.type="application/"+ fileType;
//element.attr("data", scope.filePath)
}
});
},
template: '<object data="{{filePath}}" type="{{type}}">'
}
});
My html for directive
<div data-display-pdf="fileUrl" file-type="type"></div>
Attaching an image also for IE and Chrome/FF output
Above image is a comparison between IE and FF
Final cut of directive which is working on IE11, Chrome and Firefox
use it like
<div data-display-file="fileObject"></div>
where fileObject is like
$scope.fileObject = {
fileUrl: "",
type: ""
}
mainApp.directive("displayFile", function () {
var updateElem = function (element) {
return function (displayFile) {
element.empty();
var objectElem = {}
if (displayFile && displayFile.type !== "") {
if (displayFile.type === "pdf") {
objectElem = angular.element(document.createElement("object"));
objectElem.attr("data", displayFile.fileUrl);
objectElem.attr("type", "application/pdf");
}
else {
objectElem = angular.element(document.createElement("img"));
objectElem.attr("src", displayFile.fileUrl);
}
}
element.append(objectElem);
};
};
return {
restrict: "EA",
scope: {
displayFile: "="
},
link: function (scope, element) {
scope.$watch("displayFile", updateElem (element));
}
};
});
What is the basic method of styling text inside input boxes? Can you show me the most simple example of how to change text color separately?
Very simply:
window.document.designMode = “On”;
document.execCommand(‘ForeColor’, false, ‘red’);
For more detail:
http://shakthydoss.com/javascript/html-rich-text-editor/
and then
http://shakthydoss.com/javascript/stxe-html-rich-text-editor/
There are 4 approaches you can adopt
Create a textarea. Let user modify the content. On key press or button click insertHtml to preview div. Trix uses the same approach but programmatically.
Add some textarea. Use some markdown processor which can render the the content of textarea.
Handle every movement of blinking cursor and implement something like Google docs which doesn't use execCommands. I believe quilljs also doesn't use execCommands.
You can use execCommands which are supported by almost all modern browsers. Here is the simplest example. Or check this example which uses this small code to run set of execCommands to make a rich text editor. You can simplify it more.
Example
angular.module("myApp", [])
.directive("click", function () {
return {
restrict: "A",
link: function (scope, element, attrs) {
element.bind("click", function () {
scope.$evalAsync(attrs.click);
});
}
};
})
.controller("Example", function ($scope) {
$scope.supported = function (cmd) {
var css = !!document.queryCommandSupported(cmd.cmd) ? "btn-succes" : "btn-error"
return css
};
$scope.icon = function (cmd) {
return (typeof cmd.icon !== "undefined") ? "fa fa-" + cmd.icon : "";
};
$scope.doCommand = function (cmd) {
if ($scope.supported(cmd) === "btn-error") {
alert("execCommand(“" + cmd.cmd + "”)\nis not supported in your browser");
return;
}
val = (typeof cmd.val !== "undefined") ? prompt("Value for " + cmd.cmd + "?", cmd.val) : "";
document.execCommand(cmd.cmd, false, (cmd.val || ""));
}
$scope.commands = commands;
$scope.tags = [
'Bootstrap', 'AngularJS', 'execCommand'
]
})