I recently needed to move to using a JST file for all my templates so I don't have a clutter of html templates everywhere.
I am building the JST file with grunt (using grunt-contrib-jst) and it creates the file "build/templates.js".
Below is an entry from there:
this["JST"] = this["JST"] || {};
this["JST"]["build/html/template-1.html"] = function(obj) {obj || (obj = {});var __t, __p = '', __e = _.escape;with (obj) {__p += ' <script type="text/template" id="template-1">\n <span id="chat_title_1">' +((__t = ( title )) == null ? '' : __t) +'</span>\n <span id="chat_symbol_1">▲</span>\n </script>';}return __p};
I updated my backbone.marionette render method as per https://github.com/marionettejs/backbone.marionette/wiki/Using-jst-templates-with-marionette, where it asks to replace the Renderer.render method. See the change below:
Marionette.Renderer = {
render: function(template, data){
if (!JST[template]) throw "Template '" + template + "' not found!";
return JST[template](data);
}
};
So I have the following in my view:
App.ChatBoxView = Backbone.Marionette.Layout.extend({
template: "build/html/template-1.html",
...
The page loads, there are no errors or anything, but there is nothing rendering on the page, no views, etc.
Is there something missing or done wrong?
Thank you.
Solved it... my template html files still had the <script ....> at the start and end. Removing that worked.
Updated entry example in "templates.js":
this["JST"] = this["JST"] || {};
this["JST"]["build/html/template-1.html"] = function(obj) {obj || (obj = {});var __t, __p = '', __e = _.escape;with (obj) {__p += '<span id="chat_title_1">' +((__t = ( title )) == null ? '' : __t) +'</span>\n <span id="chat_symbol_1">▲</span>';}return __p};
Related
i want the product pages marked as PageType = 'item' (inside only one category) to display different HTML code according to language mutation of a webpage. What i've achieved so far is that on every mutation page is the same content X times (x = object items such as "eng": "categoryname" )
var html = `
<div class="">
<a class="" href="#" target="_blank">
<img src="different images with site language mutation" alt="banner">
</a>
</div>
`;
var langcode = $('html').attr('lang');
var maincat = [];
$(".breadcrumbclass").each(function() {
var vat = $(this).text();
maincat.push(vat);
});
var mycategory = maincat[1];
$.each(langmutations, function(key, val) {
if (((PageType == 'item') || (PageType === 'category')) && (mycategory === langmutations[langcode])) {
$('.classForPastingMyHtml').after(html);
}
});
//This is what i have in JS
var langmutations0 = {
eng: 'categoryname',
de: 'kategoriename',
ru: 'categorija'
};
//or
var langmutations1 = [
["eng", "categoryname"],
["de", "kategoriename"],
["ru", "categorija"]
];
//I believe this is PHP style
var langmutations2 = ['eng' => 'categoryname', 'de' => 'kategoriename', 'ru' => 'categorija'];
//This could be multiple array in PHP style ? I want to have this in JS
var multiple = [eng => [“cat” => “categoryname”, “banner” => “link”], de => [“cat” => “kategoriename”, “banner” => “link”], ru => [“cat” => “categorija”, “banner” => “link”]];
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I think that i should use something like multiple array, but don't know if that exists in JS or how to structure it. Or maybe javascript object that would respond to that PHP style.
Here is some simple code to get you started:
var multiple = {
eng : {"cat" : "categoryname", "banner" : "link"},
de : {"cat" : "Kategoriename", "banner" : "link"},
ru : {"cat" : "categorija", "banner" : "link"}
};
var language = 'de';
var translations = multiple[language];
var cat = translations.cat;
console.log(cat);
//Show all translations
$.each(multiple, function(language,translations){
var cat = translations.cat;
console.log(cat);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
It uses objects inside objects with language as keys.
I'm sending html back from my controller with this function :
$scope.filterLocation=function(obj){
var loc = $filter('filter')( $scope.locationss, {'product_code':obj});
var htmlstring = "";
angular.forEach(loc, function(value, key) {
htmlstring = '<div ng-click="locationModal()">' + htmlstring + value.location_description + '</div>';
})
return $sce.trustAsHtml(htmlstring);
}
I then have this html to show the list of locations :
<td><span ng-bind-html="filterLocation(l.productcode)" style="cursor: pointer;"></span></td>
The issue is, as you can see in the controller im sort of injecting '<div ng-click="locationModal()">' and when i view the inspector the function is there correctly :
<span ng-bind-html="filterLocation(l.productcode)" style="cursor: pointer;" class="ng-binding"><div ng-click="locationModal()">A5AL</div></span>
But when i try to click it i get no results, is it because it is inside the ng-bind-html? it was a div but i changed it to a span to see if that changed anything.
I'm doing this fast for the moment, but hopefully you'll have the begin of an answer.
You could do some workaround like this :
$scope.htmlstrings = [];
var string = {
htmlLoc: ''
};
angular.forEach(loc, function(value, key) {
string.htmlLoc= string.htmlLoc+ value.location_description;
$scope.htmlstrings.push(string);
})
I don't understand why you do htmlstring = htmlstring + value.location_description; tho.
Then :
<span ng-init="filterLocation(l.productcode);" ng-repeat="htmlstring in htmlstrings">
<div ng-click="locationModal();" ng-bind="htmlstring.htmlLoc"></div>
</span>
You can change this to a return way with : <span ng-init="htmlstrings = filterLocation(l.productcode);" ng-repeat="htmlstring in htmlstrings">
And without using var string = {} but var string = '' html looks like that:
<span ng-init="htmlstrings = filterLocation(l.productcode);" ng-repeat="htmlstring in htmlstrings">
<div ng-click="locationModal();" ng-bind="htmlstring"></div>
</span>
I'll develop this later. Hope it works in your case.
I have a angular 2 application. Where I am using kendo grid to to bind the data to display in the table cells. In the template cell all is fine but wherever we have an apostrophe s in the names there it breaks up, it shows like this
The temple for the kendo grid component i am providing below, i am looking for the code to improve the view that shows ' instead of '. I am not able to find where I should add the code to existing code to make it work because the dataItem is holding the names and it is coming from template binding. can i add an auxiliary global JavaScript function that can be used to manipulate each data item during display.
two-dimensional-grid.html -
<template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex" >
<span *ngIf="column !== 'Percentage'">
<span style="color:#3b73af;cursor:pointer">
<span [class.twoDimGrid]="column === header">
<span (click)="rowItemClick(dataItem, column)">
{{dataItem[column]}}
</span>
</span>
</span>
</span>
two-dimensional-grid.ts
ngOnInit() {
this.columns = [];
this.gridTitle = this.twoDimensionalGridInfo.Name;
this.baseJql = this.twoDimensionalGridInfo.jql;
this.type = this.twoDimensionalGridInfo.type;
this.summary = this.twoDimensionalGridInfo.summary;
if (this.summary) {
this.fields = this.summary.split('|');
this.y = this.fields[0];
this.x = this.fields[1];
}
let dataItem = this.gridData[0];
if (dataItem) {
var keys = Object.keys(dataItem);
this.header = keys[0]
}
for (let field in dataItem) {
this.columns.push(field);
}
this.total = this.gridData.reduce((sums, obj) => Object.keys(obj).reduce((s, k) => {
k === this.header || k === 'Percentage' || (s[k] = (s[k] || 0) + +obj[k]);
return s;
}, sums), {});
this.total[this.header] = "Total";
this.total["Percentage"] = "";
}
i foud the answer , in the template binding I used instead of {{dataItem[column] }} .
The html code was enecoded in my database, so for decoding again its another method of solving, but i found this way too it worked for me.
I've seen a few posts asking the same question but I can't make it work. I'm quite new to angular so I would need help.
I'm trying to insert a new income with tags.
I get thoses tags from a service and display them like this :
<label ng-repeat="tag in tags">
<input type="checkbox" ng-model="tags_chosen" name="tags_chosen[tag]" ng-true-value="<%tag.id%>"/> <%tag.name%>
</label>
When I try to get back the checkbox values in angular, it doesn't work :
this.addIncome = function($scope) {
var data = {
'project_id':$scope.project_id,
'amount':$scope.amount,
'payment_date':$scope.payment_date,
'tags':$scope.tag_chosen,
'description':$scope.description,
'type':$scope.type
};
return $http.post(URL.BASE_API + 'income/store',data).
success(function(response) {
ServicesStatus.return = response;
}).error(function(response) {
console.log('Service error');
});
};
How could I do that ?
Thanks !
try this:
$scope.tag_chosen =[];
$scope.toggleSelection = function ( deviceId, $event ) {
var checkbox = $event.target;
var action=(checkbox.checked ? 'add':'remove');
var idx = $scope.tag_chosen.indexOf( deviceId );
// is currently selected
if (action=='remove' && idx != -1 ) {
$scope.tag_chosen .splice( idx, 1 );
}
// is newly selected
if (action=='add' && idx == -1 ) {
$scope.tag_chosen.push( deviceId );
}
and in html >>
ng-click="toggleSelection(yourcjeckbox value,$event)"
I am sure this has been asked before but I cannot find the answer.
I have an AngularJS script that is pulling from a DB and then rendering to content. Everything is working correctly except a couple of places that I am trying to concatenate some words with new lines between them.
**in the script.js**
groupedList[aIndex].CATEGORY = existingCategory+'\n'+thisCategory;
groupedList[aIndex].CATEGORY = existingCategory+'<br>'+thisCategory;
If I use the first line of the above code I don't see anything but there is not a new line in the redered html. If I use the second line the <br> get rendered as text and the output looks like this:
Instinct<br>Media
instead of
Instinct
Media
I can post the full script if that would be helpful but I am guessing there is something simple that I am just not seeing.
UPDATE
Here is the full js
function qCtrl($scope, $filter, $http, $timeout){
$scope.getCategories = function(){$http.post('quote.cfc?method=getCategories').success(function(data) { $scope.categories = data; }); }
$scope.getClassifications = function(){$http.post('quote.cfc?method=getClassifications').success(function(data) { $scope.classifications = data; }); }
$scope.getIndustries = function(){$http.post('quote.cfc?method=getIndustries').success(function(data) { $scope.industries = data; }); }
$scope.getKeywords = function(){$http.post('quote.cfc?method=getKeywords').success(function(data) { $scope.keywords = data; }); }
$scope.getSources = function(){$http.post('quote.cfc?method=getSources').success(function(data) { $scope.sources = data; }); }
$scope.getAllQuotes = function(){$http.post('quote.cfc?method=getAllQuotesJoined').success(function(data) { $scope.allQuotes = data; }); }
$scope.initScopes = function (){
$scope.getCategories();
$scope.getClassifications();
$scope.getIndustries();
$scope.getKeywords();
$scope.getSources();
$scope.getAllQuotes();
}
$scope.initScopes();
// SEARCH QUOTES
$scope.filteredQuotes = $scope.allQuotes;
$scope.search = {searchField:''};
$scope.searchQuote = function(){
var filter = $filter('filter');
var searchCrit = $scope.search;
var newlist = $scope.allQuotes;
var groupedList = [];
var idList = [];
newlist = filter(newlist,{TESTQUOTE:searchCrit.searchField});
for(i=0;i<10;i++){
aIndex = idList.contains(newlist[i].TESTIMONIALID);
if(aIndex >= 0){
thisKeyword = newlist[i].KEYWORD;
thisClassification = newlist[i].CLASSIFICATION;
thisCategory = newlist[i].CATEGORY;
existingKeyword = groupedList[aIndex].KEYWORD;
existingClassification = groupedList[aIndex].CLASSIFICATION;
existingCategory = groupedList[aIndex].CATEGORY;
if(thisKeyword != '' && existingKeyword.indexOf(thisKeyword) == -1){
groupedList[aIndex].KEYWORD = existingKeyword+' - '+thisKeyword;
}
if(thisClassification != '' && existingClassification.indexOf(thisClassification) == -1){
groupedList[aIndex].CLASSIFICATION = existingClassification+' \n '+thisClassification;
}
if(thisCategory != '' && existingCategory.indexOf(thisCategory) == -1){
groupedList[aIndex].CATEGORY = existingCategory+'<br>'+thisCategory;
}
} else {
idList.push(newlist[i].TESTIMONIALID);
groupedList.push(newlist[i]);
}
}
$scope.filteredQuotes = groupedList;
}
}
Array.prototype.contains = function ( needle ) {
for (j in this) {
if (this[j] == needle) return j;
}
return -1;
}
Here is the HTML
<div ng-repeat="q in filteredQuotes" class="well clearfix">
<h3>{{q.TITLE}}</h3>
<div class="row-fluid" style="margin-bottom:5px;">
<div class="span3 well-small whBG"><h4>Classification</h4>{{q.CLASSIFICATION}}</div>
<div class="span3 well-small whBG pipeHolder"><h4>Categories</h4>{{q.CATEGORY}}</div>
<div class="span3 well-small whBG"><h4>Key Words</h4>{{q.KEYWORD}}</div>
<div class="span3 well-small whBG"><h4>Additional</h4>Industry = {{q.INDUSTRY}}<br>Source = {{q.SOURCE}}</div>
</div>
<div class="well whBG">{{q.TESTQUOTE}}</div>
<div class="tiny">
Source comment : {{q.SOURCECOMMENT}}<br>
Additional Comment : {{q.COMMENT}}
</div>
</div>
</div>
You can use \n to concatenate words and then apply this style to container div.
style="white-space: pre;"
More info can be found at https://developer.mozilla.org/en-US/docs/Web/CSS/white-space
<p style="white-space: pre;">
This is normal text.
</p>
<p style="white-space: pre;">
This
text
contains
new lines.
</p>
I could be wrong because I've never used Angular, but I believe you are probably using ng-bind, which will create just a TextNode.
You will want to use ng-bind-html instead.
http://docs.angularjs.org/api/ngSanitize.directive:ngBindHtml
Update: It looks like you'll need to use ng-bind-html-unsafe='q.category'
http://docs.angularjs.org/api/ng.directive:ngBindHtmlUnsafe
Here's a demo:
http://jsfiddle.net/VFVMv/
You need to either use ng-bind-html-unsafe ... or you need to include the ngSanitize module and use ng-bind-html:
with ng-bind-html-unsafe
Use this if you trust the source of the HTML you're rendering it will render the raw output of whatever you put into it.
<div><h4>Categories</h4><span ng-bind-html-unsafe="q.CATEGORY"></span></div>
OR with ng-bind-html
Use this if you DON'T trust the source of the HTML (i.e. it's user input). It will sanitize the html to make sure it doesn't include things like script tags or other sources of potential security risks.
Make sure you include this:
<script src="http://code.angularjs.org/1.0.4/angular-sanitize.min.js"></script>
Then reference it in your application module:
var app = angular.module('myApp', ['ngSanitize']);
THEN use it:
<div><h4>Categories</h4><span ng-bind-html="q.CATEGORY"></span></div>
Why so complicated?
I solved my problem this way simply:
<pre>{{existingCategory+thisCategory}}</pre>
It will make <br /> automatically if the string contains '\n' that contain when I was saving data from textarea.
I've used like this
function chatSearchCtrl($scope, $http,$sce) {
// some more my code
// take this
data['message'] = $sce.trustAsHtml(data['message']);
$scope.searchresults = data;
and in html I did
<p class="clsPyType clsChatBoxPadding" ng-bind-html="searchresults.message"></p>
thats it I get my <br/> tag rendered
You can also use:
String.fromCharCode(10);
with CSS
white-space: pre-line;
Here si working example:
https://jsfiddle.net/Nxja/3xtcqdej/1/