This question already has answers here:
With ng-bind-html-unsafe removed, how do I inject HTML?
(10 answers)
Closed 4 years ago.
I have an ngController which contains, amongst other things, an array of questions and answers:
$scope.faqs = [
{
question: "QUESTION 1",
answer: "ANSWER 1"
},
{
question: "What is the dress code?",
answer: "See here."
},
{
question: "QUESTION 3",
answer: "ANSWER 3"
}
];
In my HTML I then cycle through these to display them:
<div>
<div ng-controller="FAQController" class="FAQ_container">
<div ng-repeat="faq in faqs">
<button class="collapsible">{{ faq.question }}</button>
<div class="content">
<p>{{ faq.answer }}</p>
</div>
</div>
</div>
<div>
However, for the middle question in my array, it prints the whole item as a string. I can understand why this is the case, however I would like for it to have the link clickable.
I have tried the suggestion from How to parse HTML in ng-repeat in angular.js by changing my
<p>{{ faq.answer }}</p>
to
<p ng-bind-html-unsafe="faq.answer"></p>
but that has just served to stop anything printing. Can anyone help with an alternative suggestion or fix please?
Please note: I am just starting out with angularjs and web development so please try to keep your answers simple and bear with me if I have to ask for clarification.
You could use ngSanitize and make your answers to be trusted has html like this:
angular.forEach($scope.faqs, function(faq) {
faq.answer = $sce.trustAsHtml(faq.answer);
});
For this you will need to use the $sce service.
And then bind them like this: <p ng-bind-html="faq.answer"></p>
See below working full sample:
angular.module('app', ['ngSanitize']).controller('FAQController', function($scope, $sce) {
$scope.faqs = [{
question: "QUESTION 1",
answer: "ANSWER 1"
},
{
question: "What is the dress code?",
answer: "See here."
},
{
question: "QUESTION 3",
answer: "ANSWER 3"
}
];
angular.forEach($scope.faqs, function(faq) {
faq.answer = $sce.trustAsHtml(faq.answer);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.14/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.14/angular-sanitize.js"></script>
<div ng-app="app">
<div ng-controller="FAQController" class="FAQ_container">
<div ng-repeat="faq in faqs">
<button class="collapsible">{{ faq.question }}</button>
<div class="content">
<p ng-bind-html="faq.answer"></p>
</div>
</div>
</div>
<div>
Related
Currently using OctoberCMS and Twig to get dynamic data and translations on the front end that come from JSON files. For example:
<div class="wrapper items">
<div class="items">
{% for suggestion in 'form.suggestions'|trans %}
<div class="item" data-subject="{{ suggestion(KEYS) }}">
{{ suggestion}}
</div>
{% endfor %}
</div>
</div>
"form":{
"suggestions": {
"suggestion1": "This is suggestion 1",
"suggestion2": "This is suggestion 2",
"suggestion3": "This is suggestion 3",
"suggestion4": "This is suggestion 4",
"suggestion5": "This is suggestion 5",
"suggestion6": "This is suggestion 6",
"suggestion7": "This is suggestion 7",
"suggestion8": "This is suggestion 8",
"suggestion9": "This is suggestion 9",
"suggestion10": "This is suggestion 10",
"suggestion11": "This is suggestion 11",
"suggestion12": "This is suggestion 12",
"suggestion13": "This is suggestion 13",
"suggestion14": "This is suggestion 14",
"suggestion15": "This is suggestion 15"
},
}
I've currently got a for each loop and need both the keys and values from the JSON file. At the moment, I can only access the value but not the keys, and I can't seem to figure out how to access them. Is this possible at all with Twig and if it is, how could I get this to work?
As suggested by #DarkBee, I simply changed the word "key" for "subject" instead, and this works fine. No idea why "key" didn't work the same way, but this seemed to have solved the issue for me. Appreciate the assistance!
So if my JSON array object returns this:
"Tools": [
{
"name": "Submit a Claim",
"position": 1,
"isOn": true,
"alert": null
},
{
"name": "My Recurring Claims",
"position": 2,
"isOn": true,
"alert": null
},
{
"name": "Online Enrollment",
"position": 3,
"isOn": false,
"alert": "Online enrollment is available for the upcoming plan year. Click here to enroll!"
},
And my ng-show html has this:
<div class="toolTile col-md-3" ng-show="Tools.name = 'Online Enrollment' && Tools.isOn==true ">
<a href="#/claimEnter">
<img class="toolIcon" src="ppt/assets/toolIcons/oe.svg">
<p>Online Enrollment</p>
</a>
</div>
<div class="toolTile col-md-3" ng-show="Tools.name = 'Submit a Claim' && Tools.isOn==true ">
<a ng-click="transId()" ng-href="{{ ppt.Globals.hasDebitCard ? '#/claimEnter' : '#/claimSub' }}" >
<img src="ppt/assets/toolIcons/submitclaim.svg" >
<p>Submit a Claim</p>
</a>
</div>
Why does it keep evaluationing to false? I have tried quite a few variations and the "Online Enrollments" should hide while the "Submit a Claim" should show.
Any ideas of what I may be doing wrong here?
Thanks much.
Hi Man You could not Post Code with Out Head and Tail. There were Some
Syntax Errors Which caused the trouble .
You Need to Provide a Plunker with Buggy Code at least for some help :-) .
When you got an array in object you need to iterate over it.
I have provided you a running Plunker :-
<div ng-repeat="tool in data.Tools">
<div ng-show="tool.name == 'Online Enrollment' && tool.isOn==false ">
Online Enrollment
</div>
<div ng-show="tool.name == 'Submit a Claim' && tool.isOn == true ">
Submit a Claim
</div>
</div>
Plunker :-
http://plnkr.co/edit/B01pKWLsUtA2JlTAPOd5?p=preview
Good Luck !! Let me Know Your Queries if any !!
I wanted to make simple quiz app.
In my JSON file I have question with answers and points for an answer.
I want to list questions, gives text inputs for user to fulfill and a button to check answers. After clicking button I will show result and mark with green or red questions which were answered correct or incorrect.
I am able to list questions but I do not know how after clicking button I could go through all inputs and do all operations: (check them with corresponding answers from JSON file, add points, mark fields).
My JSON file is:
[
{
"id": 1,
"question": "How much is it: 2+2",
"answer": ["4", "four"],
"points": 2
},
{
"id": 2,
"question": "How much is it: 2*2",
"answer": ["4", "four"],
"points": 3
},
{
"id": 3,
"question": "How much is it: 2+2*2",
"answer": ["6", "six"],
"points": 4
}]
HTML:
<div class="col-sm-4">
<h3>What are Your answers? </h3>
<form>
<div class="form-group" ng-repeat="item in answers">
<label>Question (Id: {{item.id}}): {{item.question}}</label><br>
<input type="text" name="{{item.id}}" id="{{item.id}}">
</div>
<button type="submit" class="btn btn-default" ng-click="calculatePoints()">Check</button>
</form>
</div>
<div class="col-sm-4">
<h3>Number of points which You have:</h3>
<span>{{e}}</span>
</div>
Controller:
$scope.calculatePoints = function() {
};
first you need to give ng-model to input
secondly you can pass answer element and answer to the calculatepionts function
<input type="text" ng-model="item.currentAnswer"
name="{{item.id}}" id="{{item.id}}">
sending the question object and answer to the calculate function
<button type="submit" class="btn btn-default"
ng-click="calculatePoints(item,item.currentAnswer)">Check</button>
Now you can compare the answer with the orignal one in calculatePoints()
I've got the whole questions that I have in my JSON file, but I need only one until the user will click the right answer and go to the next one
HTML template:
<div ng-controller="quizController">
<ul>
<li ng-repeat="q in allData">
<h1 id="question">{{q.question}}</h1>
</li>
</ul>
<div class="answers">
<a class="btn btn-primary"><p>New York</p></a>
<a class="btn btn-warning"><p>Miami</p></a>
<a class="btn btn-success"><p>Washington</p></a>
<a class="btn btn-danger"><p>LA</p></a>
</div>
JS:
app.controller("quizController", function($scope, $http){
$http.get("questions.json")
.then(function(response){
$scope.allData = response.data;
});
});
JSON file:
[
{
"question": "Which is the largest country in the world by population?",
"options": ["India", "USA", "China", "Russia"],
"answer": 2
},
{
"question": "When did the second world war end?",
"options": ["1945", "1939", "1944", "1942"],
"answer": 0
},
{
"question": "Which was the first country to issue paper currency?",
"options": ["USA", "France", "Italy", "China"],
"answer": 3
},
{
"question": "Which city hosted the 1996 Summer Olympics?",
"options": ["Atlanta", "Sydney", "Athens", "Beijing"],
"answer": 0
}
]
You should not use ng-repeat then, since this will just loop through your questions and show them all at once in the UI.
Instead, store your questions array in another variable and then bind your UI to a specific index of that variable.
app.controller("quizController", function($scope, $http){
$scope.allData = [];
//Initially set to first element (question), then you will need to increment in further logic elsewhere probably on a button click handler if the answer is correct
$scope.currentQuestion = $scope.allData[0];
$http.get("questions.json")
.then(function(response){
$scope.allData = response.data;
});
});
This is similar to mindparses approach but goes a little deeper. You can navigate back and forth. It's not full proof but should help you on your way.
HTML
<div ng-app="app" ng-controller="quizController">
<div ng-app="app" ng-controller="quizController">
<p>
<h1 id="question">{{currentQ.question}}</h1>
<div class="answers">
<ul ng-repeat="option in currentQ.options">
<li>{{option}}</li>
</ul>
</div>
</p>
<button ng-click="move(-1)">Previous</button>
<button ng-click="move(1)">Next</button>
</div>
</div>
JS/CONTROLLER
var app = angular.module('app', []);
app.controller("quizController", function ($scope) {
$scope.move = function (direction) {
// you're gonna need an IF block here to stop it from going out of range.
var position = $scope.allData.indexOf($scope.currentQ);
$scope.currentQ = $scope.allData[position + direction];
}
$http.get("questions.json").then(function(response){
$scope.allData = response.data;
$scope.currentQ = $scope.allData[0];
});
});
JSFIDDLE
I have json data having anchor tag .
task.json
{
"data": [{
"id": 1,
"title": "Launch an EC2 Instance",
"desc": "Needed an <a href='#'>EC2</a> instance to deploy the ccr code",
"status": "done",
"percentage_finished": 100
}]
}
I am using angularjs to render this data to my html page . But anchor tag is not working.
It prints as it is as Text.
<div class="task-pn panel panel-primary">
<div class="panel-heading"><b>Description : Task-{{task_detail.id}}</b></div>
<div class="panel-body">
<div onclick="this.contentEditable='true';">{{task_detail.desc}}</div>
</div>
</div>
Output img.
I need a simple link to EC2 word .How to deal with this isuue?
You need something like this:
In your controller:
scope.trustedHtml = sce.trustAsHtml(json.desc);
And to use it in your partial:
<p class="org-desc" ng-bind-html="trustedHtml"> </p>
user2720708 :Thanks for sharing your ideas.
eRIZ gave this link .There I used the idea of Luke Madera.
Current working html page .
<div class="task-pn panel panel-primary">
<div class="panel-heading"><b>Description : Task-{{task_detail.id}}</b></div>
<div class="panel-body">
<div contentEditable" ng-bind-html="task_detail.desc"></div>
</div>
</div>
and Then I follow only two steps :
1.include the angular-sanitize.min.js resource, i.e.:
2.In a js file (controller or usually app.js), include ngSanitize, i.e.:
angular.module('myApp', ['myApp.filters', 'myApp.services',
'myApp.directives', 'ngSanitize']) ---------from answer given by Luke Madera
Its working now ...:)