Angular bind-html + $sce still remove the inline style - html

I write simple custom filter that return string value.
The value contain html string and inline style
When binding angular remove the styles
Here is my filter
siteApp.filter('specialText', ['$filter', '$sce', function ($filter, $sce) {
return function (code, items, defaults) {
var out = defaults;
if (items && items.length) {
var arr = $filter('filter')(items, { code: code }, true);
if (arr && arr.length > 0) {
out = arr[0].value;
$sce.trustAsHtml(out);
}
}
return out;
};
}]);
And This is my html
<div ng-bind-html="'body_message' | specialText : specific_texts :''"></div>
The original text contain inline style but angular remove inline style on binding
How can I keep the inline styles
FULL EXAMPLE CODE
<body >
<div ng-app="siteApp">
<div ng-controller="ctrl">
{{'test1' | specialText : arr :'missing....' }}
<div ng-bind-html="'test1' | specialText : arr :'missing....'"></div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.5.6/angular-sanitize.js"></script>
<script>
var siteApp = angular.module('siteApp', ['ngSanitize']);
siteApp.filter('specialText', ['$filter', '$sce', function ($filter, $sce) {
return function (code, items, defaults) {
var out = defaults;
if (items && items.length) {
var arr = $filter('filter')(items, { code: code }, true);
if (arr && arr.length > 0) {
out = arr[0].value;
$sce.trustAsHtml(out);
}
}
return out;
};
}]);
siteApp.controller('ctrl', ['$scope', function ($scope) {
$scope.arr = [{ "code": "test1", "rte": true, "value": "<p style=\"text-align: left;\">First Row</p>\n<h1 style=\"text-align: center;\">Second Center Row</h1>" }];
}]);
</script>
</body>

You are not using the output of $sce.trustAsHtml(out). Inside your if statement try out = $sce.trustAsHtml(out); and it should be ok.

Related

Angularjs custom filter not working

I am trying to filter elements based on the range. I am using two controllers & $rootScope broadcast-on approach to retrieve the min-max range of a slider & sharing it with the other controller.
HTML-
<body ng-app="myApp">
<div ng-controller="RangeController as vm">
<rzslider rz-slider-model="vm.slider.minValue" rz-slider-high="vm.slider.maxValue" rz-slider-options="vm.slider.options"></rzslider>
</div>
<div ng-controller="SampleController">
<div ng-repeat="x in elements | inRange:min:max">
{{x}}
</div>
</div>
</body>
AngularJS-
var app = angular.module('myApp', ['rzModule']);
app.controller('SampleController', function($scope,$rootScope) {
$scope.min = 1500;
$scope.max = 5500;
$scope.elements = [1530,2100,2780,3323,3420,4680,5020,5300,5402];
$scope.$on('MIN_PRICE', function(response) {
$scope.min = minPrice;
})
$scope.$on('MAX_PRICE', function(response) {
$scope.max = maxPrice;
})
});
app.value('minPrice',1500);
app.value('maxPrice',5500);
app.controller('RangeController', RangeController);
function RangeController($scope,$rootScope) {
var vm = this;
vm.changeListener = function() {
minPrice = vm.slider.minValue;
maxPrice = vm.slider.maxValue;
console.log(minPrice + " " +maxPrice);
$rootScope.$broadcast('MIN_PRICE', minPrice);
$rootScope.$broadcast('MAX_PRICE', maxPrice);
};
vm.slider = {
minValue: 1500,
maxValue: 5500,
options: {
floor: 1500,
ceil: 5500,
step: 500,
translate: function(value) {
return '₹' + value;
},
onChange:vm.changeListener
}
}
}
app.filter('inRange', function() {
return function(array, min, max) {
array = array.filter(function(element) {
return (element >= min && element <= max);
});
console.log(array);
};
});
I tried debugging, the filter works fine but it won't reflect in the template.
The self-assignment to array inside your filter (array = array.filter(…);) seems slightly suspicious to me. Have you tried simply returning array.filter(…); directly?
app.filter('inRange', function() {
return function(array, min, max) {
return array.filter(function(element) {
return (element >= min && element <= max);
});
};
});

Polymer - reload core-list data

I wanted reload a core-list element to show new data, but it´s not refreshing.
I re-call the JS function thats generate the data but doesn t work... and reload like a 'normal' div doesn t work either! The list only shows the new data if i reload the entire page...
function values(sender, textomsg, datacriacao, senderfoto){
var sender2 = sender.split(",");
var textomsg2 = textomsg.split(",");
var datacriacao2 = datacriacao.split(",");
var senderfoto2 = senderfoto.split(",");
var namegen = {
generateString: function (inLength) {
var s = '';
for (var i = 0; i < inLength; i++) {
s += String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
return s;
},
generateName: function (inMin, inMax) {
return this.generateString(Math.floor(Math.random() * (inMax - inMin + 1) + inMin));
}
};
Polymer('list-test', {
count: sender.length,
ready: function () {
this.data = this.generateData();
},
generateData: function () {
var names = [], data = [];
for (var i = 0; i < this.count; i++) {
names.push(namegen.generateName(4, 8));
}
names.sort();
for (var i = 0; i < this.count; i++) {
data.push({
index: i,
sender: sender2[i],
textomsg: textomsg2[i],
datacriacao: datacriacao2[i],
senderfoto: senderfoto2[i]
});
}
return data;
},
tapAction: function (e) {
console.log('tap', e);
}
});
}
<%----%>
<template id="templateConversas" runat="server">
<div id="item" class="item {{ {selected: selected} | tokenList }}" ><%--onClick="conversa('{{name}}');"--%>
<div class="message" style="background-image: url({{senderfoto}});">
<span class="from"><br/>{{sender}}</span>
<span class="timestamp">{{datacriacao}}</span>
<div class="subject"><br/>{{textomsg}} </div><%--------Infinite List. {{index}}--%>
<%--<div class="body"><br/>Mensagem de teste...........</div>--%>
</div>
</div>
</template>
The problem is also reload the 'list-test'. if i call the js function after the list is loaded it doesn't apply the new data...
Your code isn't complete so it is hard to understand but I think that the problem is that you don't assign the result of the generateData() function to the template's model. Try following script for your component
Polymer('list-test', {
created: function () {
this.data = [];
},
refresh: function () {
this.data = this.generateData();
},
generateData: function () {
// your original code here
}
});
Now the list content should be updated with newly generated data when you call refresh() of the list-test element. To fill the list when element is created add
ready: function () {
this.refresh();
},

watch changes on JSON object properties

I'm trying to implement a directive for typing money values.
var myApp = angular.module('myApp', []);
var ctrl = function($scope) {
$scope.amount = '0.00';
$scope.values = {
amount: 0.00
};
};
myApp.directive('currency', function($filter) {
return {
restrict: "A",
require: "ngModel",
scope: {
separator: "=",
fractionSize: "=",
ngModel: "="
},
link: function(scope, element, attrs) {
if (typeof attrs.separator === 'undefined' ||
attrs.separator === 'point') {
scope.separator = ".";
} else {
scope.separator = ",";
};
if (typeof attrs.fractionSize === 'undefined') {
scope.fractionSize = "2";
};
scope[attrs.ngModel] = "0" + scope.separator;
for(var i = 0; i < scope.fractionSize; i++) {
scope[attrs.ngModel] += "0";
};
scope.$watch(attrs.ngModel, function(newValue, oldValue) {
if (newValue === oldValue) {
return;
};
var pattern = /^\s*(\-|\+)?(\d*[\.,])$/;
if (pattern.test(newValue)) {
scope[attrs.ngModel] += "00";
return;
};
}, true);
}
};
});
HTML template:
<div ng-app="myApp">
<div ng-controller="ctrl">
{{amount}}<br>
<input type="text" style="text-align: right;" ng-model="amount" currency separator="point" fraction-size="2"></input>
</div>
</div>
I want to bind the value in my input element to values.amount item in controller but the watch instruction of my directive doesn't work.
How do I leverage two-way-data-binding to watch JSON objects?
To understand problem more precise I've created a jsfiddle.
The task is the following: Add extra zeros to the input element if user put a point. I mean if the value in input element say "42" and user put there a point, so the value now is "42." two extra zeros have to be aded like this "42.00".
My problems:
If I use ng-model="amount" the logic in input element works, but amount value of outer controller doesn't update.
If I use ng-model="values.amount" for binding, neither amount of outer controller nor input element logic works.
I really have to use ng-model="values.amount" instruction, but it doesn't work and I don't know why.
Any ideas?

AngularJS Drirective Template with variables(dynamic template)

Not able to reflect values of the scope variables into
the template of a directive(dash-board-directive). Please help
On Template I have a button and would like to display button color as blue/black/yellow based on the value of scope.btnAttribData(which is holding values data-theme="a"/data-theme="b"/data-theme="e" etc)
/-----------
1)Markup:
Here is how I call my directive:
<div ng-controller="MyDashBoardCtrl">
<dash-board-directive list-item-value="listItemName" items="btnAttribData" ></navtree>
</div>
Where listItemName, and btnAttribData are the parent scope variables(plz refer DashBoardController item#4 ***)
/--------------------------------------
2) Controller on this div : ng-controller="MyDashBoardCtrl" as follows
app.controller('MyDashBoardCtrl', function ($scope)
{
$scope.itemselected = "None";
$scope.organizations={
"kind": "TestData",
"columns":["Row1","Row2","Row3"],
"rows":[
["Yes","No","No"],
["No","Yes","No"],
["No","No","Yes"]
]
};
this.setSelected = function (ID) {
//$scope.itemselected = ID;
$scope.itemselected = ID.btnValue;
}
})
/---------------------
3) code on directivce "dash-board-directive" as follows:
app.directive('dashBoardDirective', function ()
{
return {
template: '<btn-directive ng-repeat="item in items" item="item" itemselected="itemselected" ></navtree-node>',
restrict: 'E',
replace: true,
scope: {
items: '=items', //items holding btnAttribValue ie
//btnAttribValue: '=btnAttribData',
rowItemValue: '=listItemValue',
},
link: function (scope, elem, attrs)
{
}
};
});
app.directive('btnDirective', function ($compile)
{
var btnTemplate = '<button ng-model="tempTheme" >TEST!!!</button>'
return {
restrict: 'E',
require:"^ngController",
scope: {
item: "=",
itemselected: '='
},
compile:function(tElement,tAttrs, transclude)
{
console.log("###---In a linking function directive-btnDirective");
tElement.html(btnTemplate);
return function(scope, element, attrs)
scope.classEnable = scope.item.classEnable; //: "class='ui-disabled'"
scope.tempTheme = scope.item.tempTheme; //: "data-theme=a"
scope.uiBlockValue = scope.item.uiBlockValue; //: "class='ui-block-a'"
if ((angular.isDefined(scope.item)) && (scope.item.length > 0))
{
var btnElement = $compile('<btnDirective items="item"></navtree>')(scope);
elm.append(btnElement);
}
scope.itemSelect = function(id){
//alert(id);
myGreatParentControler.setSelected(id)
}
}
};
});
/---------------
***
4)
listItemName, and btnAttribData are the parent
scope variable from parent controller "DashBoardController" as follows(which stored into an scope.listItemName and scope.btnAttribData on a click event
var app = angular.module('AppDashBoard', [])
app.controller('DashBoardController', function($scope, $window)
{
$scope.listItemName;
$scope.listItemRowDataArray;
$scope.listItemRowDataAttributes={};
$scope.btnAttribData = new Array();
$scope.listItemData={
"kind": "TestData",
"columns":["Row1","Row2","Row3"],
"rows":[
["Yes","No","No"],
["No","Yes","No"],
["No","No","Yes"]
]
};
$scope.listItemClick = function(inputObj){
$scope.listItemName = inputObj;
console.log("### --- $scope.listItemName = "+inputObj )
var colData = $scope.listItemData.columns;
var rowData = $scope.listItemData.rows;
var iColDataIndex = colData.indexOf(inputObj);
var listItemRowData = new Array();
var arrayUiBlock = new Array();
arrayUiBlock[0] = "class='ui-block-a'";
arrayUiBlock[1] = "class='ui-block-b'";
arrayUiBlock[2] = "class='ui-block-c'";
uiBlockCtr=0;
for ( var j = 0; j < rowData[iColDataIndex].length; j++ )
{
var colName = inputObj
var colValue = rowData[iColDataIndex][j];
var tempTheme="";
var btnId = "btnId_"+colName;
var isTempThemeBlue=false;
var classEnable = ""
//$scope.listItemRowDataArray;
listItemRowData.push(colValue);
var buttonAtributes= new Array();
if(colValue=="Yes")
{ buttonAtributes['rowItemValue']=inputObj;
buttonAtributes['btnValue']=colValue;
buttonAtributes['tempTheme']='data-theme="a"';
buttonAtributes['isTempThemeBlue']=true;
buttonAtributes['classEnable']="class='ui-disabled'";
}
else
{
buttonAtributes['rowItemValue']=inputObj;
buttonAtributes['btnValue']=colValue;
buttonAtributes['tempTheme']='data-theme="e"';
buttonAtributes['isTempThemeBlue']=false;
buttonAtributes['classEnable']="class='ui-enable'";
}
if(uiBlockCtr<3)
{
buttonAtributes['uiBlockValue']=arrayUiBlock[uiBlockCtr]
}
else
{ uiBlockCtr=0;
buttonAtributes['uiBlockValue']=arrayUiBlock[uiBlockCtr]
}
uiBlockCtr++;
$scope.btnAttribData.push(buttonAtributes);
}
$scope.listItemRowDataArray=listItemRowData;
};
})
/-------------------
5) index.html as follows:
<!DOCTYPE html>
<html ng-app="AppDashBoard">
<head>
<title>Rating Directive Demo</title>
<link rel="stylesheet" href="rating.css"/>
<link rel="stylesheet" href="vendor/foundation/foundation.min.css"/>
</head>
<body ng-controller="DashBoardController">
<div data-role="page" id="mainPageId">
<div data-role="header" href="" data-role="button" data-theme="b" >
<h1>ListVIEW</h1>
</div>
<div data-role="content" id="mainPageIdContent" >
<div>
<ul data-role="listview" >
<li ng-repeat="item in listItemData.columns">
{{item}}
</li>
</ul>
</div>
</div>
</div>
<div data-role="page" id="listItemDetailPageId">
<div data-role="header" href="" data-role="button" data-theme="b" >
<h1>ListVIEWDetails</h1>
Back
</div>
<div ng-controller="MyDashBoardCtrl">
<dash-board-directive list-item-value="listItemName" items="btnAttribData" ></navtree>
</div>
</div>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script type="text/javascript" src="rating.js"></script>
</body>
</html>
/-------------------
6) rating.js as follows;
var app = angular.module('AppDashBoard', [])
app.controller('DashBoardController', function($scope, $window)
{
$scope.listItemName;
$scope.listItemRowDataArray;
$scope.listItemRowDataAttributes={};
$scope.btnAttribData = new Array();
$scope.listItemData={
"kind": "TestData",
"columns":["Row1","Row2","Row3"],
"rows":[
["Yes","No","No"],
["No","Yes","No"],
["No","No","Yes"]
]
};
$scope.listItemClick = function(inputObj){
$scope.listItemName = inputObj;
console.log("### --- $scope.listItemName = "+inputObj )
var colData = $scope.listItemData.columns;
var rowData = $scope.listItemData.rows;
var iColDataIndex = colData.indexOf(inputObj);
var listItemRowData = new Array();
var arrayUiBlock = new Array();
arrayUiBlock[0] = "class='ui-block-a'";
arrayUiBlock[1] = "class='ui-block-b'";
arrayUiBlock[2] = "class='ui-block-c'";
uiBlockCtr=0;
for ( var j = 0; j < rowData[iColDataIndex].length; j++ )
{
var colName = inputObj
//arrayColName.push(jsonObjColumn[index]);
var colValue = rowData[iColDataIndex][j];
var tempTheme="";
var btnId = "btnId_"+colName;
var isTempThemeBlue=false;
var classEnable = ""
//for a listItem(Row1), add buttons value to the array "listItemRowData",then, assign this array to
//$scope.listItemRowDataArray;
listItemRowData.push(colValue);
var buttonAtributes= new Array();
if(colValue=="Yes")
{ buttonAtributes['rowItemValue']=inputObj;
buttonAtributes['btnValue']=colValue;
buttonAtributes['tempTheme']='data-theme="a"';
buttonAtributes['isTempThemeBlue']=true;
buttonAtributes['classEnable']="class='ui-disabled'";
}
else
{
buttonAtributes['rowItemValue']=inputObj;
buttonAtributes['btnValue']=colValue;
buttonAtributes['tempTheme']='data-theme="e"';
buttonAtributes['isTempThemeBlue']=false;
buttonAtributes['classEnable']="class='ui-enable'";
}
if(uiBlockCtr<3)
{
buttonAtributes['uiBlockValue']=arrayUiBlock[uiBlockCtr]
}
else
{ uiBlockCtr=0;
buttonAtributes['uiBlockValue']=arrayUiBlock[uiBlockCtr]
}
uiBlockCtr++;
$scope.btnAttribData.push(buttonAtributes);
}
console.log("$scope.btnAttribData");
console.log($scope.btnAttribData)
$scope.listItemRowDataArray=listItemRowData;
console.log("$scope.listItemRowDataArray");
console.log($scope.listItemRowDataArray);
};
})
app.controller('MyDashBoardCtrl', function ($scope)
{
$scope.itemselected = "None";
$scope.organizations={
"kind": "TestData",
"columns":["Row1","Row2","Row3"],
"rows":[
["Yes","No","No"],
["No","Yes","No"],
["No","No","Yes"]
]
};
this.setSelected = function (ID) {
$scope.itemselected = ID.btnValue;
}
})
app.directive('dashBoardDirective', function ()
{
return {
template: '<btn-directive ng-repeat="item in items" item="item" itemselected="itemselected" ></navtree-node>',
restrict: 'E',
replace: true,
scope: {
items: '=items', //items holding btnAttribValue ie
//btnAttribValue: '=btnAttribData',
rowItemValue: '=listItemValue',
},
link: function (scope, elem, attrs)
{
}
};
});
app.directive('btnDirective', function ($compile)
{
var btnTemplate = '<button ng-model="tempTheme" >TEST!!!</button>'
return {
restrict: 'E',
require:"^ngController",
scope: {
item: "=",
itemselected: '='
},
//link: function (scope, elm, attrs, myGreatParentControler) {
compile:function(tElement,tAttrs, transclude)
{
console.log("###---In a linking function directive-btnDirective");
tElement.html(btnTemplate);
return function(scope, element, attrs)
scope.classEnable = scope.item.classEnable; //: "class='ui-disabled'"
scope.tempTheme = scope.item.tempTheme; //: "data-theme=a"
scope.uiBlockValue = scope.item.uiBlockValue; //: "class='ui-block-a'"
console.log("item =", scope.classEnable);
console.log("item =", scope.tempTheme);
console.log("item =", scope.uiBlockValue);
if ((angular.isDefined(scope.item)) && (scope.item.length > 0))
{
var btnElement = $compile('<btnDirective items="item"></navtree>')(scope);
elm.append(btnElement);
}
scope.itemSelect = function(id){
//alert(id);
myGreatParentControler.setSelected(id)
}
}
};
});

Prototype Remove HTML?

I have the following HTML
<div id="top-right">
<span id="top-right-name">sometexthere</span> | link
</div>
And the following prototype JS
Event.observe(window, 'load', function() {
try {
if ($$('#top-right')!=null) {
var topmenu = document.getElementById('top-right');
var value = topmenu.innerHTML;
// define an array of replacements
var replacements = [
{ from: '|', to: ' ' },
{ from: '|', to: ' ' },
{ from: '|', to: ' ' },
{ from: '|', to: ' ' }
];
for (var i = 0, replacement; i < replacements.length, replacement = replacements[i]; i++) {
// replace
value = value.replace(replacement.from, replacement.to);
}
// replace the old text with the new
topmenu.innerHTML = value;
}
}
catch(ex) {
}
});
I am trying to remove the " | " after the </span> automatically onload of the this JS - but I just cant seem to do it .
Can someone assist ?
Thanks
It seems to be a syntax error somewhere, perhaps in your loading of Prototype. The below snippet worked fine for me :)
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js"></script>
<div id="top-right">
<span id="top-right-name">sometexthere</span> | link
</div>
<script type="text/javascript">
Event.observe(window, 'load', function() {
try {
if ($$('#top-right')!=null) {
var topmenu = document.getElementById('top-right');
var value = topmenu.innerHTML;
// define an array of replacements
var replacements = [
{ from: '|', to: ' ' }
];
for (var i = 0, replacement; i < replacements.length, replacement = replacements[i]; i++) {
// replace
value = value.replace(replacement.from, replacement.to);
}
// replace the old text with the new
topmenu.innerHTML = value;
}
}
catch(ex) {
}
});
</script>
Edited to reflect problem