Renderer having image and hyperlink together in extjs - extjs

I have a form which has a displayfield.The value of the form is set as a hyperlink.Now I also need an image to appear along with the hyperlink.How can this be done?Below is my code to add hyperlink:
xtype:'displayField',
fieldLabel: 'Name',
value: 'abc',
renderer:function(value){
return ''+value+'' //need to add an image with this
}

I usually go for one of these approaches, mostly equivalent:
Add a css class to my a element, with background-image and some padding-left.
Enclose the anchor element in a div with a similar css class.
Add a span before the anchor. Additionally use display: inline-block and give it a width and a height since it has no text content.
You could just precede it with an img, but for some reason I never do that. It's ugly if the image doesn't get loaded.
Examples:
CSS
.myimgclass: {
background-image: url(...);
background-position: 0;
background-repeat: no-repeat;
}
span.myimgclass {
width: 16px;
height: 16px;
display: inline-block;
}
So in your renderer you can the following:
Inline the anchor:
renderer:function(value){
return '<a class="myimgclass" href="#">'+value+'</a>';
}
Enclosed in a div
renderer:function(value){
return '<div class="myimgclass">'+value+'</div>';
}
Prepended as a span:
renderer:function(value){
return '<span class="myimgclass"></span>'+value+'';
}
Prepended as an img:
renderer:function(value){
return '<img src="../your/img/path/here.png." />'+value+'';
}
I would also like to add that all these approaches are based on you wanting to add the image as html, through your renderer. Another approach is to set your component's html: configuration. Then use ctrl.update('...'); if you ever want to update it. The html content should be identical to the examples above, but value won't be available. So renderer is more for dynamic content or generic during initialization, while html is controlled mostly from code (e.g. events).

Related

How to get height of a div in Ionic

I'm working to develop a mobile app using Ionic.
A bit of background first as to what I am trying to achieve.
I've got a challenging bit of design I am coding in. I am placing an image of fixed height, in the bottom right hand corner of a div which has a flexible height. The text within the div then needs to wrap around the image.
Like this:
What the end result should be like
The HTML and CSS side of things
I've got the CSS and HTML sussed (at least I think!). The HTML is:
//this line is in the head
<style ng-bind-html="myStyles"></style>
//the rest is in the body of the HTML
<div class="score_block">
<div class="description">
<div class="image_container">
<img src="img/emotional_man.png">
</div>
<p>{{area.levelling.description}}</p>
<div class="habits_button">
<button ng-click="$state.go('app.planner')" class="button button-stable button-icon button-block">Plan habits</button>
</div>
</div>
</div>
And the CSS (written using SASS) is like this:
.score_block {
text-align: center;
position: relative;
.description {
text-align: left;
margin: 10px 0;
}
.image_container {
clear: both;
float: right;
width: 100px;
height: 100px;
img {
height: 100px;
width: 100px;
}
}
}
.score_block:before {
content: "";
float: right;
height: 200px;
width: 0;
}
If I change the height of the 'score_block:before' class I can reposition the image just I need.
The Javascript so far
So with the Javascript side of things I'm hoping that if I can figure out the height of the .description div, I can subtract the height of the image from it and tell the CSS how to position the image. I need some AngularJS to do this - I think that's what I need as JQuery doesn't work in Ionic as far as I know.
So far I have JS code that does this:
.controller('emotionalCtrl', function ($scope, $state, AreasService, _) {
//these commented out lines are to show things I have tried but don't work
//var blockH = $(".description").height();
//var descriptionHeight = angular.element('description');
//var number = descriptionHeight('offsetHeight');
var number = 0;
$scope.myStyles = "#habit_area_homepage .score_block:before { height:" + number + "px; }";
})
I'm looking to do a calculation on the variable number and pass that back in. I can manually change the value of number of it works fine so I know everything else is good. I've read some stuff about doing directives etc but all the examples I've seen confuse me. Maybe I need to put a directive in here or something to help me get the height of the .description element but I just can't figure out to do this. I've spent nearly two days getting this far!
I'm pretty new to AngularJS and Ionic so any help would be really appreciated. Thanks!
There are multiple ways to accomplish dynamic styles.
According to your provided code. I recommend you add styles to head.
Run below codes in your controller or "run":
angular.module("app",[]).run(function(){
var stylesTpl="<style>#habit_area_homepage .score_block:before { height:" + number + "px; } </style>";
angular.element(document).find("head").append(stylesTpl);
})
Check this post for built-in directives of angular to achieve dynamic styles:
How do I conditionally apply CSS styles in AngularJS?
If you want to get the height of a specific div, you have two ways:
Assign an id to the div, and use
var element = document.getElementById("id");
console.log(element.offsetHeight);
Use querySelectors, this returns the first and only one element:
var element = document.querySelector(".description");
console.log(element.offsetHeight);
Using directive is also a good way, check:
Get HTML Element Height without JQuery in AngularJS

How to use font awesome in an Ext.panel.Tool

I need to customize an Ext.panel.Tool to display the icon 'fa fa-file-excel-o' from font awesome in the header of a grid. Following what I found online I have declared the tool:
header: {
itemPosition: 1, // after title before collapse tool
items: [{
xtype: 'tool',
type: 'export',
cls:'component-tool-export',
handler: 'doExportData'
}]
},
And the css:
.component-tool-export .x-tool-export{
background-image:none !important;
content: "\f1c3" !important;
}
The tool is there and I can click on it, but the icon is not displayed. Can anyone give me some hint to fix this?
You are not adding content to the :before pseudo element, which is required to have the content displayed. You could use the following CSS:
.component-tool-export .x-tool-export{
background-image:none !important;
font: 16px/1 FontAwesome;
}
.component-tool-export .x-tool-export:before{
content: "\f1c3" !important;
}
But if you already use Sencha CMD, I would recommend to conform with Sencha's own SASS files and make use of the full feature set of Sencha Fashion:
$tool-export-glyph: dynamic($fa-var-file-excel-o $tool-glyph-font-size $font-icon-font-family);
.#{$prefix}tool-export {
#include font-icon($tool-export-glyph);
background: none;
}

ExtJS FontAwesome change Glyph Color

I just added FontAwesome to my ExtJS application.
I added a Glyph to my tab:
items: [
{
title: 'Dashboard',
glyph: 0xf009,
padding: '5',
I would like to change the Glyph color, is that possible?
This should work:
.x-panel-header .x-panel-header-glyph {
opacity: 1;
color: red;
}
You can see it in action here: http://extjs.eu/examples/#complex-data-binding
I tried the Saki way
.x-panel-header .x-panel-header-glyph {
opacity: 1;
color: red; }
but then you don't have the control to change attributes for specific glyph and if I want to set it for individual glyph I will need to work harder.
I use a simple way:
Step 1: add a link to the css file
link rel="stylesheet"
href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"
Step: 2:
use iconCls
iconCls: "fa fa-lg fa-futbol-o glyph"
here I used the awesome classes "fa fa-lg-fa-futbol-o" but I added "glyph" so it will looks better than without.
Step 3:
define "glyph" in your css file.
.glyph { margin-top: 3px; }
Step 4:
define any css you can apply to the glyph like color.
The result:
in css file:
.glyph { margin-top: 3px; }
.youname { color: #15498B; }
in js ( every where you have config iconCls )
iconCls: "fa fa-lg fa-futbol-o glyph youname"
I know this is a little late but for anyone else in the future who wants change Glyph icons when using custom fonts with Exts.
I used the reference to the button in my controller passed in during the event. I then got the buttons ID then target the button using the get method and concatenating "-btnIconEl" to the the button ID as any glyph/icon will have that CSS.
'button[action=displayGrids]' : {
click: function(button) {
Ext.get(button.id + '-btnIconEl').setStyle('color', '#ffffff');
}
}

Can I use the !important css keyword with Angularjs ng-style directive?

I'm having an issue with boostrap3 and it's default background: transparent !important; print setting.
I have the need to show a heatmap in my webapp and have these printable.
I'm using an ng-style directive for that to dynamically calculate the needed background-color.
In short, this is the html part
<div class="heatmap" ng-style="scalecolor(10)">lorem ipsum</div>
and this is the controller part
$scope.scalecolor = function(perc) {
return { backgroundColor: plnkUtils.scaleColorInt('#EE0000', '#88FF00', perc) }
};
However, because bootstrap3 sets all backgrounds to transparent with the !important keyword, I can't print these.
This is the part of bootstrap 3.1.0 css causing the issue with missing background-color:
#media print {
* {
color: #000 !important;
text-shadow: none !important;
background: transparent !important;
box-shadow: none !important;
}
}
Since the inverse of background: transparent !important; is background: color hex code !important;
(see here )
I'm trying to set that using the ng-style, but then the exclamantion mark causes Angularjs to flip when I try this:
$scope.scalecolor = function(perc) {
return { backgroundColor: plnkUtils.scaleColorInt('#EE0000', '#88FF00', perc) !important }
};
or alternatively when I try this in the html template
ng-style="scalecolor(10) !important"
Anyone out there that knows how I can use the !important css keyword with the Angularjs ng-style directive to override the bootstrap3 wildcard?
For those who want to see this with their own eyes, here's a plunker showing the issue
Apparently you can't and it's a known issue but there is some workaround that can be found here:
https://github.com/angular/angular.js/issues/5379
The solution below has been copied from the site just in case the link breaks, or get changed.
You're not able to use the !important directive in the DOM style property in either Chrome nor FF (probably others too). The style attribute gets parsed as CSS, but the HTMLElement.style property doesn't. Unfortunately you're not able to set a property's priority here (in Gecko/Blink/Webkit, at least).
So, there are some workarounds here:
Workaround #1
<ANY data-ng-attr-style="{{ blue && 'background-color: blue!important' || '' }}">
</ANY>
This would be your best way to go in terms of browser-support, because the CSS property priority will get parsed correctly here.
Workaround #2
Alternatively, you can also do the following in javascript:
$scope.$watch(conditionalStyle);
function conditionalStyle() {
if ($scope.blue) {
$element[0].style.setProprety('background-color', 'blue', 'important');
} else {
$element[0].style.backgroundColor = '';
}
}
Where $element is a jQuery/jqLite object referencing an HTMLElement.
Note: caveats are not supported in IE < 9 so workaround #1 is probably your best bet for this behavior where you depend on property priority...
Using the tips for #Wawy I updated my code to get it to work.
For anyone landing on this page, for clarification I made an updated Plunker that can be found here
In short, this is now the html part
<div class="heatmap" ng-attr-style="{{ngAttrScaleColor(10)}}">YES, ng-attr-style works !</div>
and this is the controller part
$scope.ngAttrScaleColor = function(perc) {
return 'background-color: ' + plnkUtils.scaleColorInt('#EE0000', '#88FF00', perc) + '!important';
};

Word-wrap grid cells in Ext JS

(This is not a question per se, I'm documenting a solution I found using Ext JS 3.1.0. But, feel free to answer if you know of a better solution!)
The Column config for an Ext JS Grid object does not have a native way to allow word-wrapped text, but there is a css property to override the inline CSS of the TD elements created by the grid.
Unfortunately, the TD elements contain a DIV element wrapping the content, and that DIV is set to white-space:nowrap by Ext JS's stylesheet, so overriding the TD CSS does no good.
I added the following to my main CSS file, a simple fix that appears to not break any grid functionality, but allows any white-space setting I apply to the TD to pass through to the DIV.
.x-grid3-cell {
/* TD is defaulted to word-wrap. Turn it off so
it can be turned on for specific columns. */
white-space:nowrap;
}
.x-grid3-cell-inner {
/* Inherit DIV's white-space from TD parent, since
DIV's inline style is not accessible in the column
definition. */
white-space:inherit;
}
YMMV, but it works for me, wanted to get it out there as a solution since I couldn't find a working solution by searching the Interwebs.
If you only want to apply the wrapping to one column, you can add a custom renderer.
Here is the function to add:
function columnWrap(val){
return '<div style="white-space:normal !important;">'+ val +'</div>';
}
Then add the renderer: columnWrap to each column you want to wrap
new Ext.grid.GridPanel({
[...],
columns:[{
id: 'someID',
header: "someHeader",
dataIndex: 'someID',
hidden: false,
sortable: true,
renderer: columnWrap
}]
Not a "better solution", but a similar one. I recently needed to allow ALL cells in every grid to wrap. I used a similar CSS-based fix (this was for Ext JS 2.2.1):
.x-grid3-cell-inner, .x-grid3-hd-inner {
white-space: normal; /* changed from nowrap */
}
I didn't bother with setting a style on the td, I just went right for the cell class.
If you only want to wrap text in certain columns and are using ExtJS 4, you can specify a CSS class for the cells in a column:
{
text: 'My Column',
dataIndex: 'data',
tdCls: 'wrap'
}
And in your CSS file:
.wrap .x-grid-cell-inner {
white-space: normal;
}
Other solution is that:
columns : [
{
header: 'Header',
dataIndex : 'text',
renderer: function(value, metaData, record, rowIndex, colIndex, view) {
metaData.style = "white-space: normal;";
return value;
}
}
]
The best way to do is by setting the cellWrap to true as below.
cellWrap: true
Its working well in EXTJS 5.0.
use
cellWrap: true
If you still want to use css always try to work with ui's, variables, etc. within themes, or set the style with the style property.

Resources