I know that I can format a cell to parse content as a link in ng-repeat:
<a ng-href="{{::domainname}}/{{::row.sector}}/{{::row.cname}}/ipo-{{::row.tickerbb}}.html">{{::row.cname}}</a>
Here is the fiddle.
How do I make it dynamic, so that if row.tickerbb is null - show a different URL?
I tried to do it in the controller, looping through the data:
var i = 0;
$.each(data, function () {
if (data[i].tickerbb != null) {
data[i].cname = '<a title="' + data[i].cname + '"' + ' ng-href="' + domainname + '/' + data[i].sector + '/' + data[i].shortcname + '/ipo-' + data[i].tickerbb + '.html">' + data[i].cname + '</a>';
}
else {
data[i].cname = '<a title="' + data[i].cname + '" href="Holdings">' + data[i].cname + '</a>';
}
i += 1;
})
But the results show up as raw html tags:
How do I do conditional formatting of the smart-table cell? Or is there a way to sanitize cells in smart-tables?
Resolved it by constructing my link in the controller:
var i = 0;
$.each(data, function () {
data[i].weight = (data[i].weight * 100).toFixed(2) + '%';
if (data[i].shortcname != null) {
var cname = data[i].cname;
var sector = data[i].sector;
var shortcname = data[i].shortcname;
var tic = data[i].tickerbb;
var url = '<a title="' + cname + '" href="' + $scope.domainname + '/' + sector + '/' + shortcname + '/ipo-' + tic + '.html">' + cname + '</a>';
data[i].cname = url;
}
else
{
data[i].cname = '<a title="' + data[i].cname + '" href="Holdings">' + data[i].cname + '</a>';
}
i += 1;
})
And then sanitizing it inside ng-repeat:
<td ng-bind-html="row.cname"></td>
Related
I'm using this slightly modified treeview directive (https://github.com/eu81273/angular.treeview, jFiddle Example) in my app. I can get it to save the node that has been selected, but I can't seem to figure out how to display the treeview with a node already selected, if the user edits previously saved form.
Treeview Directive:
angular.module('App').directive('treeModel', ['$compile', function ($compile) {
return {
restrict: 'A',
controller: treeviewController,
link: function (scope, element, attrs) {
//tree id
var treeId = attrs.treeId;
//tree model
var treeModel = attrs.treeModel;
//node id
var nodeId = attrs.nodeId || 'id';
//node label
var nodeLabel = attrs.nodeLabel || 'label';
//children
var nodeChildren = attrs.nodeChildren || 'children';
//tree template
var template =
'<ul>' +
'<li data-ng-repeat="node in ' + treeModel + '">' +
'<i class="collapsed" data-ng-show="node.' + nodeChildren + '.length && node.collapsed" data-ng-click="' + treeId + '.selectNodeHead(node)"></i>' +
'<i class="expanded" data-ng-show="node.' + nodeChildren + '.length && !node.collapsed" data-ng-click="' + treeId + '.selectNodeHead(node)"></i>' +
'<i class="normal" data-ng-hide="node.' + nodeChildren + '.length" data-ng-class="node.selected" data-ng-click="' + treeId + '.selectNodeLabel(node)"></i> ' +
'<span data-ng-hide="node.' + nodeChildren + '.length" class="tree-item" data-ng-class="node.selected" data-ng-click="' + treeId + '.selectNodeLabel(node)">{{node.' + nodeLabel + '}}</span>' +
'<span data-ng-show="node.' + nodeChildren + '.length" class="tree-node" data-ng-class="node.selected" data-ng-click="' + treeId + '.selectNodeLabel(node)">{{node.' + nodeLabel + '}}</span>' +
'<div data-ng-hide="node.collapsed" data-tree-id="' + treeId + '" data-tree-model="node.' + nodeChildren + '" data-node-id=' + nodeId + ' data-node-label=' + nodeLabel + ' data-node-children=' + nodeChildren + '></div>' +
'</li>' +
'</ul>';
//check tree id, tree model
if (treeId && treeModel) {
//root node
if (attrs.angularTreeview) {
//create tree object if not exists
scope[treeId] = scope[treeId] || {};
//if node head clicks,
scope[treeId].selectNodeHead = scope[treeId].selectNodeHead || function (selectedNode) {
//Collapse or Expand
selectedNode.collapsed = !selectedNode.collapsed;
};
// my attempt at pre-loading a selected node
if (scope.savedNode != undefined) {
scope[treeId].currentNode = scope.savedNode;
//scope.savedNode comes from the controller, and looks like this...
/*{
"children": [],
"collapsed": false,
"selected": "selected",
"treeNodeName": "Node name here",
"treeNodeId": "eY40Ik"
}*/
}
//if node label clicks,
scope[treeId].selectNodeLabel = scope[treeId].selectNodeLabel || function (selectedNode) {
// only allow to select nodes that are not expandable
if (!selectedNode.children.length) {
//remove highlight from previous node
if (scope[treeId].currentNode && scope[treeId].currentNode.selected) {
scope[treeId].currentNode.selected = undefined;
}
//toggle currentNode
if (scope[treeId].currentNode == selectedNode) {
scope[treeId].currentNode = {};
selectedNode = {};
scope.currentSelectedNode = {
name: "",
id: ""
};
} else {
scope[treeId].currentNode = selectedNode;
selectedNode.selected = 'selected';
scope.currentSelectedNode = {
name: selectedNode.sourceName,
id: selectedNode.sourceId
}
}
}
};
}
//Rendering template.
element.html('').append($compile(template)(scope));
}
}
};
}]);
HTML:
<div data-angular-treeview="true"
data-tree-id="treeId"
data-tree-model="treeData"
data-node-id="treeNodeId"
data-node-label="treeNodeName"
data-node-children="children">
</div>
Only the selected node is being saved, not the entire tree-model.
How would I load up a tree with a node already selected?
I want to integrate facebook Widget for getting facebook group's timeline / posts. I have searched & got this https://developers.facebook.com/docs/plugins/page-plugin but this gives user's & page's timeline. I wanted Group's timeline. I didn't found perfect answer on Fb Developer portal & didn't get anything on web.
Any help on this is appreciated.
Thanks in Advance.
After lots of search, no plugin kind of thing i got for this. But yes got one blog in php where the developer made custom widget manually, I modified it with JavaScript & jQuery.
<div style="height: 375px; background: #f6f7f9;">
<div id="fb-root"></div>
<p class="text-center media-body social-link" style="background: white">
<img src="~/Content/Images/Link-Red.png" />
Facebook Group
</p>
<div id="fix-div"></div>
<div id="facebook-group" style="overflow-y: scroll; height: 375px; margin-top: 55px;"></div>
</div>
Facebook JavaScript API as follows-
<script>
var access_token = '<!-- Valid fb access token -->';
var groupId = 'valid facebook group id';
window.fbAsyncInit = function () {
FB.init({
appId: 'valid facebook app id',
cookie: true,
xfbml: true,
version: 'v2.8'
});
FB.api("" + groupId + "?fields=cover,icon,name,privacy",
'get',
{ access_token: access_token },
function (groupResponse) {
if (groupResponse && !groupResponse.error) {
$("#fix-div").html('');
$("#facebook-group").html('');
var fixDivHtml =
"<div style='z-index: 10;position: absolute;border: 1px solid #e9ebee;max-width: 470px;background: white;min-height: 50px;'><div class='media' style='border: 0'><div class='media-left media-middle' style='vertical-align: bottom'><a href='https://www.facebook.com/groups/" + groupResponse.id + "' target='_blank'><img class='media-object' src='/Content/Images/Facebook-group.png' style='min-height: 50px;padding: 5px 10px;width: 64px;'></a></div><div class='media-body media-middle'><a href='https://www.facebook.com/groups/" + groupResponse.id + "' target='_blank'><h4 class='media-heading' style='font-size: 14px;font-weight: bold;'>" + groupResponse.name + "</h4></a></div></div></div>";
$("#fix-div").append(fixDivHtml);
FB.api("/" +
groupId +
"/feed?fields=id,message,link,attachments{media,description},created_time,from,object_id,parent_id&limit=1000",
'get',
{ access_token: access_token },
function (response) {
if (response && !response.error) {
for (var i = 0; i < response.data.length; i++) {
var picture = undefined;
var description = undefined;
var date = formatDate(response.data[i].created_time);
if (response.data[i].attachments !== undefined) {
if (response.data[i].attachments.data.length > 0) {
if (
response.data[i].attachments.data[0].media !==
undefined) {
if (
response.data[i].attachments.data[0].media
.image !==
undefined)
picture = response.data[i].attachments
.data[0].media.image.src;
if (
response.data[i].attachments.data[0].media
.image.description !==
undefined)
description = response.data[i].attachments
.data[0].media.image.description;
} else {
if (
response.data[i].attachments.data[0]
.description !==
undefined)
description = response.data[i].attachments
.data[0].description;
}
}
}
var message = response.data[i].message;
var
append =
"<div class='border'><div class='media'><div class='media-left media-middle'><a href='https://www.facebook.com/" + response.data[i].from.id + "' target='_blank'><img class='media-object' src='http://graph.facebook.com/" + response.data[i].from.id + "/picture?type=square'></a></div><div class='media-body' style='vertical-align: bottom'><a href='https://www.facebook.com/" + response.data[i].from.id + "' target='_blank'><h4 class='media-heading'>" + response.data[i].from.name + ".<br /><small>" + date + "</small></h4></a></div>";
if (message !== undefined) {
if (ValidURL(message) === 1) {
append +=
"<a class='ellipsis' href='" +
message +
"' target='_blank'>" +
message +
"</a>";
} else {
append += "<a class='ellipsis'>" + message + "</a>";
}
}
if (picture !== undefined)
append +=
"<a href='" +
response.data[i].link +
"' target='_blank'><img class='img-responsive' src='" +
picture +
"'/></a>";
if (description !== undefined)
append += "<p>" + description + "</p>";
append += '<hr///>' +
"<div class='btn-group btn-group-justified' role='group' aria-label='Justified button group'>" +
"<a href=" +
response.data[i].link +
" class='btn btn-default' role='button' target='_blank'><i class='fa fa-thumbs-up' aria-hidden='true'></i> Like</a>" +
"<a href=" +
response.data[i].link +
" class='btn btn-default' role='button' target='_blank'><i class='fa fa-comment' aria-hidden='true'></i> Comment</a></div></div></div>";
$("#facebook-group").append(append);
}
}
});
}
});
};
(function () {
var e = document.createElement('script');
e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
var formatDate = function (input) {
var d = new Date(Date.parse(input));
input = d.toString();
d = new Date(Date.parse(input.replace(/-/g, "/")));
var month = [
'january', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December'
];
var date = d.getDay().toString() +
" " +
month[d.getMonth().toString()] +
", " +
d.getFullYear().toString();
return (date);
};
function ValidURL(str) {
if (
/^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test(str))
return 1;
else
return -1;
}
</script>
Here formatDate & ValidURL are helper functions used for some cosmetic operations.
I have an issue on showing icomoon glyph on grid action columns using sencha architect in extjs 5.0 application. I am using group grid here. Glyphs are showing nicely on any ext button btw.
I have made an overwrite class for Ext.grid.column.Action like shown in following link as
Ext.define('MyApp.override.grid.column.Action', {
override: 'Ext.grid.column.Action',
// overridden to implement
defaultRenderer: function(v, cellValues, record, rowIdx, colIdx, store, view) {
var me = this,
prefix = Ext.baseCSSPrefix,
scope = me.origScope || me,
items = me.items,
len = items.length,
i = 0,
item, ret, disabled, tooltip,glyph, glyphParts, glyphFontFamily;
// Allow a configured renderer to create initial value (And set the other values in the "metadata" argument!)
// Assign a new variable here, since if we modify "v" it will also modify the arguments collection, meaning
// we will pass an incorrect value to getClass/getTip
ret = Ext.isFunction(me.origRenderer) ? me.origRenderer.apply(scope, arguments) || '' : '';
cellValues.tdCls += ' ' + Ext.baseCSSPrefix + 'action-col-cell';
for (; i < len; i++) {
item = items[i];
disabled = item.disabled || (item.isDisabled ? item.isDisabled.call(item.scope || scope, view, rowIdx, colIdx, item, record) : false);
tooltip = disabled ? null : (item.tooltip || (item.getTip ? item.getTip.apply(item.scope || scope, arguments) : null));
if(Ext.isFunction(item.getGlyph)){
glyph = item.getGlyph.apply(item.scope || scope, arguments);
}else{
glyph = item.glyph;
}
// Only process the item action setup once.
if (!item.hasActionConfiguration) {
// Apply our documented default to all items
item.stopSelection = me.stopSelection;
item.disable = Ext.Function.bind(me.disableAction, me, [i], 0);
item.enable = Ext.Function.bind(me.enableAction, me, [i], 0);
item.hasActionConfiguration = true;
}
if (glyph ) {
if (typeof glyph === 'string') {
glyphParts = glyph.split('#');
glyph = glyphParts[0];
glyphFontFamily = glyphParts[1];
} else {
glyphFontFamily = Ext._glyphFontFamily;
}
ret += '<span role="button" title="' + (item.altText || me.altText) + '" class="' + prefix + 'action-col-icon ' + prefix + 'action-col-glyph ' + prefix + 'action-col-' + String(i) + ' ' + (disabled ? prefix + 'item-disabled' : ' ') +
' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope || scope, arguments) : (item.iconCls || me.iconCls || '')) + '"' +
' style="font-family:' + glyphFontFamily + '"' +
(tooltip ? ' data-qtip="' + tooltip + '"' : '') + '>&#' + glyph + ';</span>';
} else {
ret += '<img role="button" alt="' + (item.altText || me.altText) + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
'" class="' + me.actionIconCls + ' ' + prefix + 'action-col-' + String(i) + ' ' + (disabled ? prefix + 'item-disabled' : ' ') +
(Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope || scope, arguments) : (item.iconCls || me.iconCls || '')) + '"' +
(tooltip ? ' data-qtip="' + tooltip + '"' : '') + ' />';
}
}
return ret;
}
});
and also applied getGlyph function like:
getGlyph: function(v, meta, rec) {
return 'xe600#icomoon';
}
But still not showing any icon or glyp at the column.
I found the following output from the override class as
<span role="button" title="" class="x-action-col-icon x-action-col-glyph x-action-col-0 xe600#icomoon" style="font-family:icomoon"></span>
Which seems fine to me. Not sure what is wrong here, can any one help me?
Its my bad I could not check in the link i mentioned in my question:
I have to add the css line in my css file for showing the glyphs in action columns:
.x-action-col-glyph {font-size:16px; line-height:16px; color:#9BC8E9; width:20px}
After this glyphs are shown.
I'm using the code below, to set the css class for an action column.
But even if the result is null, some elements are inserted by extjs.
getClass: function(v, meta, data) {
if (data.myDate < new Date())
return null;
else
return 'insert';
}
Generated html for return null:
<img alt="" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
class="x-action-col-icon x-action-col-1 null">
The major problem is that cursor is changed to a hand pointer when moving this "blank" space.
There is a way to not generate elements when no icon is to be shown?
I don't see any way to do it without extending action column. IMO easiest way is to provide custom renderer function. Example:
Ext.define('Ext.grid.column.MyAction', {
extend: 'Ext.grid.column.Action',
constructor: function(config) {
var me = this,
cfg = Ext.apply({}, config),
items = cfg.items || [me],
l = items.length,
i,
item,
cls;
me.callParent(arguments);
me.renderer = function(v, meta) {
v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';
meta.tdCls += ' ' + Ext.baseCSSPrefix + 'action-col-cell';
for (i = 0; i < l; i++) {
item = items[i];
item.disable = Ext.Function.bind(me.disableAction, me, [i]);
item.enable = Ext.Function.bind(me.enableAction, me, [i]);
cls = (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||me.scope||me, arguments) : (me.iconCls || ''));
if (cls !== null) {
v += '<img alt="' + (item.altText || me.altText) + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
'" class="' + Ext.baseCSSPrefix + 'action-col-icon ' + Ext.baseCSSPrefix + 'action-col-' + String(i) + ' ' + (item.disabled ? Ext.baseCSSPrefix + 'item-disabled' : ' ') + (item.iconCls || '') +
' ' + cls + '"' +
((item.tooltip) ? ' data-qtip="' + item.tooltip + '"' : '') + ' />';
}
}
return v;
};
}
});
// Calling the video function with JSON
$.getJSON("videos.php", function(data){
// first check if there is a member available to display,
//if not then show error message
if(data == '') {
$('#tabs-4').html("<div class='errorMember'>Sorry, there is currently no member available videos</div>");
}
// if there is a member, then loop through each data available
else {
$.each(data, function(i,name){
content = '<div class="left"><img src="' + name.pic + '"/>';
content += '<p>' + name.name + '</p>';
content += 'Video link';
content += '</div><br/><hr>';
$("#tabs-4").html(content);
});
}
});
The problem is that it only gives me one result instead of list of results from the array but if I appendTo(content) .. it adds the full list of results under the current which is not what I want because I need to refresh that content with updated data.
Any ideas to what I'm doing wrong?
Probably so far only the last Element is getting Displayed .
// Calling the video function with JSON
$.getJSON("videos.php", function(data){
// first check if there is a member available to display, if not then show error message
if(data == '') {
$('#tabs-4').html("<div class='errorMember'>Sorry, there is currently no member available videos</div>");
}
// if there is a member, then loop through each data available
else {
//If you want to Clear the Container html
$("#tabs-4").html('');
$.each(data, function(i,name){
content = '<div class="left"><img src="' + name.pic + '"/>';
content += '<p>' + name.name + '</p>';
content += 'Video link';
content += '</div><br/><hr>';
$("#tabs-4").append(content);
});
}
});
Empty the element before filling it:
$('#tabs-4').empty();
$.each(data, function(i,name){
var content =
'<div class="left"><img src="' + name.pic + '"/>' +
'<p>' + name.name + '</p>' +
'Video link' +
'</div><br/><hr>';
$("#tabs-4").append(content);
});
Or put all the elements in the string before putting it in the element:
var content = '';
$.each(data, function(i,name){
content +=
'<div class="left"><img src="' + name.pic + '"/>' +
'<p>' + name.name + '</p>' +
'Video link' +
'</div><br/><hr>';
});
$("#tabs-4").html(content);
If I well understood, probably you may want do something like this
...
else {
$("#tabs-4").empty(); // remove previous data (if any)
$.each(data, function(i,name){
content = '<div class="left"><img src="' + name.pic + '"/>';
content += '<p>' + name.name + '</p>';
content += 'Video link';
content += '</div><br/><hr>';
$("#tabs-4").append(content); // append new data
});
}