angularjs sanitize not work properly with ng-model - angularjs

I use AntiXss Encoder on serverside for XSS atacks so all response includes html unescape characters like "&lt:script&gt:alert(1);&lt:/script&gt:" (replaced ';' as ':')
on binding i use sanitize with ng-bind-html there is no problem wih that.
There is an other control input for update mode. When user needs to update text they click update icon then i show textarea and hide binded tag with ng-if. textarea has ng-model attr. i cant escape html characters on textarea like ng-bind-html here is the snippet pls help im getting creazy..
in fiddle; edit mode textarea must display "<script>alert(1);</script>" with no alert action and data will be sent to the server must display same too...
here is the fiddle
var app = angular.module('myApp',['ngSanitize']);
app.controller('MyCtrl', function($scope, $sce, $sanitize) {
$scope.post1 = "<script>alert(1);</script>";
//$scope.post2 = $sce.parseAsHtml("<h1>alert(1)</h1>");
$scope.logs = ["log created"];
$scope.log = function(val){
$scope.logs.push(val);
}
});
.label {
text-decoration:underline;
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-sanitize.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<div class="label">Edit mode :</div>
<textarea ng-model="post1" style="width:100%;" rows="5"></textarea><br />
<div class="label">Binding mode :</div>
<div ng-bind-html="post1"></div><br />
<div class="label">Data will be send to the server :</div>
<div>{{post1}}</div><br />
<div class="label">Logs (if needed) :</div>
<div ng-repeat="d in logs">
<p>{{($index+1) + ". " + d}}</p>
</div>
</div>
</div>

Related

AngularJS Formly - dynamic change of field type

What I wish to achieve is a single page (a form) used for both edit and display a record's data. I would like to have an edit button which would switch modes from edit to display and vice versa.
In terms of layout both modes looks the same.
In edit mode I have inputs/selects/typeaheads/multiple selects/datetime pickers etc. But in display mode values are displayed like in simple span. Something like that :)
So my question is: Is it possible to change field type after form is being rendered by formly? Any tips how to achieve such behaviour?
You can simply hide an edit form and bind your data to each form so that changes on one of them will be visible on another. Here is a quick demo:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.text = "demo";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-if="!edit">
{{$parent.text}}
</div>
<div ng-if="edit">
<input type="text" ng-model="$parent.text" />
</div>
<button ng-click="edit = !edit">Edit</button>
</div>

Controller properties (like $scope.data) are working on page1.html, but not working on page2.html

I am new to Angular JS. I have 1 controller and 2 views. 1st view is supposed to be filled with user. when user filling the data I am storing those values using ng-model in controller(For $scope). After submission of the form, I want to use that data in 2nd page. But I am not getting anything. is there any rule like one controller should be specific to one view. Because when I try to display data on 1st pageI am getting correctly. But when I try the same code onpage2.html I am not getting any value and any error even though page is loaded. I searched a lot on SO. but could not find proper solution. I would be very thankful to U, if anyone of U helps me.Thanks a lot in advance
script.js
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.item="";
$scope.remarks="";
$scope.divCount=[{}];
$scope.addDiv=function(){
$scope.divCount.push({});
};
})
Page1.html
<html>
<head>
<title>My AngularJS App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body
<form action="page2.html">
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="count in divCount">
Item : <textarea rows="4" cols="50" ng-model="item"> </textarea> <br><br/>
Remarks: <textarea ng-model="remarks" rows="2" cols="50"></textarea> <br><br/>
<div>
<button ng-click="addDiv();">Add Another Item</button>
</div>
</div>
</div>
<input type="submit" value="submit"/>
</form>
</body>
</html>
page2.html
<div ng-controller="myCtrl">
<div> item: {{item}} </div>
<div> remarks: {{remarks}}</div>
</div>
If you want use one controller in two page use ui-router .
You can see here for more infomation
https://github.com/angular-ui/ui-router/wiki
But i recommend you dont do that using a single controller for multiple views (pages, as you say) is a very poor design for an angular app
On click of submit button in Page1.html store the required data in a service/factory. Retrieve the data from the service/factory in page2.html

How to get value from <div> tag when input change in angular js?

I'm using WMD library to create an editor. When I input data into text area, my preview change data such as preview content from the input.
My question: Can I get content from the content of div preview? .How to do that?
<textarea id="wmd-input" ng-model="params.content" class="wmd-panel"></textarea>
<div id="wmd-preview" class="wmd-preview" ></div>
You can do this using angular.element delegates to Angular's built-in subset of jQuery,
$scope.content= angular.element(document.querySelector('#wmd-preview'));
alert($scope.content);
You can output your textarea value with $scope using ng-bind-html-unsafe inside your code HTML element. It does work like in this -> Fiddle:
View
<div ng-controller="MyCtrl">
<textarea id="wmd-input" ng-model="params.content" class="wmd-panel"></textarea>
<div id="wmd-preview" class="wmd-preview">
<pre>
<code ng-bind="params.content"></code>
</pre>
</div>
</div>
App & Controller
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.params = {
content: "<h1>Hello World</h1>"
}
}
Output
> <html>
> <head></head>
> <body>
> <h1>Hello World</h1>
> <body>
> </html>

AngularJS ng-show 2 way binding not working

I am new to AngularJS and I have seen others asking similar questions, but the answers are not working for me. Rather than hijacking those questions, I thought I would open one for myself.
I am creating a demo app -- it lists "sites" which can be added to or deleted. I am using the ng-show attribute to display the required html div while hiding the others.
Here is the back-end javascript--
var SiteMaintenanceModule = angular.module("SitesMaintenance", []);
SiteMaintenanceModule.controller("siteCtrl", diveSiteCtrlfn);
function diveSiteCtrlfn($scope) {
// initializing the sites array
$scope.sites = sites;
//initializing the Divs array
$scope.allowedDivs = ["listSiteDiv","addSiteDiv", "editSiteDiv","deleteSiteDiv"];
// setting the first div as selected. This should show the div which lists the sites
$scope.selectedDiv = $scope.allowedDivs[0];
// function to be called with the selected div is to be changed
$scope.setSelectedDiv = function ($divSelectedByUser) {
$scope.selectedDiv = $divSelectedByUser;
}
};
And here is the html
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="SitesMaintenance">
<head>
<title>List of Dive Sites</title>
<link rel="Stylesheet" href="./../zHelpers/bootstrap/css/bootstrap.css" />
<script src="./../zHelpers/angular.min.js"></script>
<script src="./sites.js"></script>
<script src="./SiteMaintenance.js"></script>
</head>
<body ng-controller="siteCtrl">
<!-- Display the list of sites based on the selectedDiv variable-->
<div id="SiteList" ng-show="{{selectedDiv == 'listSiteDiv'}}">
<h3>List of Sites</h3>
<ul ng-repeat="site in sites" ng-model="sites">
<li>{{site.site}} in {{site.location}}</li>
</ul>
</div>
<!-- Display the add site Div based on the selectedDiv variable-->
<div id="AddSite" ng-show="{{selectedDiv == 'addSiteDiv'}}">
<h3>Add New Site</h3>
<div style="display:block; margin:10px">Site: <input id="inputAddSiteName" /></div>
<div style="display:block; margin:10px">Location: <input id="inputAddSiteLocation" /></div>
</div>
<!-- Display the edit site Div based on the selectedDiv variable -->
<div id="EditSites" ng-show="{{selectedDiv == 'editSiteDiv'}}" style="display:block;margin:20px">
Site Name:<input id="InputEditSiteName" />
Site Location:<input id="InputEditSiteLocation" />
</div>
<div id="controls">
<button id="AddNewSiteButton" ng-click="setSelectedDiv('addSiteDiv')">Add Site</button>
<button id="DeleteSiteButton" ng-click="setSelectedDiv('deleteSiteDiv')">Delete Site</button>
<button id="EditSiteButton" ng-click="setSelectedDiv('editSiteDiv')">Edit Site</button>
</div>
</body>
I can set the visible div to whatever I want at the start, by changing the index in the statement "$scope.selectedDiv = $scope.allowedDivs[0];" in the JavaScript.
I change the value of $scope.selectedDiv when any of the buttons on the page are clicked, so as to change the visibility of the divs.
However, the visibility of the divs doesn't change, no matter what the value of $scope.selectedDiv is. In fact, when debugging in chrome, I see that the attribute value of ng-show for each of my divs updates dynamically to "true" or "false" and expected, but the div is still displayed -- the initially invisible divs seems to have a class="ng-hide" attribute, which never changes.
I have tried $scope.$apply() in the JavaScript but that gives errors. Any help would be greatly appreciated.
You don't need to use {{}} interpolation inside ng-show directive directive, it evaluates the expression inside a $scope of your controller directly.
ng-show="selectedDiv == 'addSiteDiv'"
ng-show="selectedDiv == 'listSiteDiv'"
ng-show="selectedDiv == 'editSiteDiv'"

angular material design md-switch doesnt work within a tab

when placing a switch ( md-switch directive) within a tab, an aria error is thrown
ARIA: Attribute " aria-label ", required for accessibility, is missing on node: ​…​​
this happens regardless on whether an aria label is present or not. If the switch is moved outside of the tab, it works as expected.
plunker showing the issue
http://plnkr.co/edit/FmZAyLBpzhURbdZuuhQK?p=preview
<div ng-app="app" ng-controller="ctrl" >
<md-tabs md-selected="selectedIndex">
<md-tab id="tab1">Item One</md-tab>
</md-tabs>
<ng-switch on="selectedIndex" class="tabpanel-container">
<div role="tabpanel" id="tab1-content" ng-switch-when="0">
<div>
<md-switch aria-label="toggle" ng-model="data.switch">Switch : {{ toggle }}</md-switch>
</div>
</div>
</ng-switch>
</div>
<script>
var app = angular.module('app', ['ngMaterial']);
app.controller("ctrl", function ($scope) {
$scope.toggle = false;
$scope.selectedIndex = 0;
});
</script>
That was strange..
This issue seems to be fixed with the most current build of angular material (version 0.6.1-master-0767813).
Here's the plunker: http://plnkr.co/edit/chEaf9i50mIiThp0Jloq?p=preview
I just changed the scripts to the most current build:
<link rel="stylesheet" href="//rawgit.com/angular/bower-material/master/angular-material.css">
<script src="//rawgit.com/angular/bower-material/master/angular-material.min.js"></script>
Also you needed to change the ng-model to the toggle value. So instead of using
ng-model="data.switch"
You needed to use
ng-model="toggle"
pointing to $scope.toggle.

Resources