I'm trying to build a bouncy-arrow directive that can be positioned and rotated in markup.
angular.module('directives').directive("bouncyArrow", function ($compile) {
return {
replace: true,
restrict: 'E',
template: '<span class="ion-arrow-right-c"></span>',
scope: {
heading: '='
},
link: function (scope, element, attrs) {
element.css('transform', 'rotate('+attrs.heading+'deg)');
element.css('-webkit-transform', 'rotate('+attrs.heading+'deg)');
element.css('background-color', 'red');
}
};
});
This appears in my template:
<bouncy-arrow heading="15"></bouncy-arrow>
The arrow with red background color appears correctly. But, the transform has no effect. How can I apply the transform to the ionicon?
UPDATE: Here is the fix...
angular.module('directives').directive("bouncyArrow", function () {
return {
replace: true,
restrict: 'E',
template: '<span class="ion-arrow-right-c"></span>',
scope: {
heading: '=',
scale: '=',
positionx: '=',
positiony: '='
},
link: function (scope, element, attrs) {
var transforms = [
'translate(' + attrs.positionx+'px,'+attrs.positiony + 'px)',
'scale(' + attrs.scale + ')',
'rotate(-'+attrs.heading+'deg)',
];
var css = {
selector: '.bouncy-arrow:before',
rules: [
'transform: '+transforms.join(' '),
'-webkit-transform: '+transforms.join(' ')
]
};
var sheet = css.selector + ' {' + css.rules.join(';') + '}';
angular.element(document).find('head').prepend('<style type="text/css">' + sheet + '</style>');
element.addClass('bouncy-arrow');
}
};
});
You need to apply the transform to the :before pseudo class of the "ion-arrow-right-c"
My suggestion is you create a custom class for your element and then use css to do the transform. Much cleaner that way.
Related
I tried several ways to set an icon, in the displayfield, when an item of the combo is selected with not luck, this is the fiddle for anyone to want try to help with this. very much appreciated any light.
fiddle example
The only solution is to transform the input type combo in a div with this:
fieldSubTpl: [
'<div class="{hiddenDataCls}" role="presentation"></div>',
'<div id="{id}" type="{type}" style="background-color:white; font-size:1.1em; line-height: 2.1em;" ',
'<tpl if="size">size="{size}" </tpl>',
'<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
'class="{fieldCls} {typeCls}" autocomplete="off"></div>',
'<div id="{cmpId}-triggerWrap" class="{triggerWrapCls}" role="presentation">',
'{triggerEl}',
'<div class="{clearCls}" role="presentation"></div>',
'</div>', {
compiled: true,
disableFormats: true
}
],
Override the setRawValue method of the combo like this:
setRawValue: function (value) {
var me = this;
me.rawValue = value;
// Some Field subclasses may not render an inputEl
if (me.inputEl) {
// me.inputEl.dom.value = value;
// use innerHTML
me.inputEl.dom.innerHTML = value;
}
return value;
},
and style your fake combo div like you want.
Thats because an input on HTML can't have HTML like value inside it.
Keep attenction, the get Value method will return you the HTML inside the div, and maybe you should also override it, but thats the only one method.
You will be able to get the selected value with this method:
Ext.fly(combo.getId()+'-inputEl').dom.innerHTML.replace(/<(.|\n)*?>/gm, '');
If I were you I would like to do something like this:
combo.getMyValue();
So add this property to your combo:
getMyValue:function(){
var combo=this;
if(Ext.fly(combo.id+'-inputEl'))
return Ext.fly(combo.id+'-inputEl').dom.innerHTML.replace(/<(.|\n)*?>/gm, '');
},
Here is a working fiddle
Perhaps my solution is similar to a hack, but it works in 6.7.0 and is a bit simpler.
Tested in Chrome. Theme - Material. For another theme will require minor improvements.
Sencha Fiddle live example
Ext.application({
name: 'Fiddle',
launch: function () {
var store = new Ext.data.Store({
fields: [{
name: 'class',
convert: function (value, model) {
if (value && model) {
var name = value
.replace(/(-o-)|(-o$)/g, '-outlined-')
.replace(/-/g, ' ')
.slice(3)
.trim();
model.data.name = name.charAt(0).toUpperCase() + name.slice(1);
return value;
}
}
}, {
name: 'name'
}],
data: [{
class: 'fa-address-book'
}, {
class: 'fa-address-book-o'
}, {
class: 'fa-address-card'
}]
});
var form = Ext.create('Ext.form.Panel', {
fullscreen: true,
referenceHolder: true,
items: [{
xtype: 'combobox',
id: 'iconcombo',
queryMode: 'local',
editable: false,
width: 300,
valueField: 'class',
displayField: 'name',
store: store,
itemTpl: '<div><i class="fa {class}"></i> {name}</div>',
afterRender: () => {
var component = Ext.getCmp('iconcombo');
var element = document.createElement('div');
element.className = 'x-input-el';
element.addEventListener('click', () => component.expand());
component.inputElement.parent().dom.prepend(element);
component.inputElement.hide();
component.addListener(
'change', (me, newValue, oldValue) => {
component.updateInputValue.call(me, newValue, oldValue);
},
component
);
var method = component.updateInputValue;
component.updateInputValue = (value, oldValue) => {
method.call(component, value, oldValue);
var selection = component.getSelection();
if (selection) {
element.innerHTML =
'<div><i class="fa ' + selection.get('class') + '"></i> ' + selection.get('name') + '</div>';
}
};
}
}, {
xtype: 'button',
text: 'getValue',
margin: '30 0 0 0',
handler: function (component) {
var combo = Ext.getCmp('iconcombo');
alert(combo.getValue());
}
}]
});
form.show();
}
});
I am working with AngularJS (pretty new). I have encountered a challenge which is if the textarea value is to big I have to make it scrollable as well as the border around it and if not I have to remove the border and scrolling as well. I try adding the directive but couldn't make it work.
Let me know if there is any work around it. I appreciate your time and help.
Updated:
angular.module('myApp')
.directive('removeBorder', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
if (element[0].clientHeight < element[0].scrollHeight) {
console.log(element.clientHeight);
console.log(element.scrollHeight);
console.log('ELEMENT: ' + element[0]);
angular.element(element[0]).removeClass('scroll');
}
}
};
});
I made you an example with nativeJS and angularJS with native JS. Just check Elements clientHeight and scrollHeightattribute to make it work.
angularJS directive
angular.module('docsSimpleDirective', [])
.controller('Controller', ['$scope', function($scope) {}])
.directive('removeBorder', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
if (element[0].clientHeight >= element[0].scrollHeight) {
console.log(element[0].clientHeight);
console.log(element[0].scrollHeight);
angular.element(element[0]).addClass('no-scroll');
}
}};
});
Native JS - Plunker
function hasScrollbar(elemId) {
elem = document.getElementById(elemId);
if (elem.clientHeight < elem.scrollHeight) {
alert("The element #" + elemId + " has a vertical scrollbar!");
} else {
alert("The element #" + elemId + " doesn't have a vertical scrollbar.");
elem.style.border= "0";
}
}
Scrollable shoulb be set automatically. Or use css:
textarea { overflow-y:scroll; }
I was trying to change background image style dynamically for the following div:
Here is my component for changing it,
render: function() {
var divImage = {
backgroundImage : "url(" + this.state.song.imgSrc + "),url(" + this.state.nextImgSrc + ");"
};
return (
<li>
<div ref="image-pane" className="player" style={divImage}></div>
</li>
)
}
Thanks for the help
You haven't specified when would you like to change backgroundImage, so I've created version which changes it with onClick:
React.createClass({
getInitialState: function () {
nextImg: false,
},
handleClick: function () {
this.setState({ nextImg: !this.state.nextImg })
},
render: function() {
var imgUrl = this.state.nextImg ? this.state.nextImgSrc : this.state.song.imgSrc;
var divStyle = {
backgroundImage: 'url(' + imgUrl + ')'
}
return (
<li>
<div ref="image-pane" style={divStyle} onClick={this.handleClick} className="player"></div>
</li>
)
}
});
Notice that backgroundImage: 'url(' + imgUrl + ')' no longer must have trailing semicolon, in fact the trailing semicolon will cause React to raise and error.
This is caused by the trailing semicolon in your style. See react issues #2862.
So, here is a custom directive to resize an element and it's contents based on a screen size change. I can see that the value of 'scalify' is changing how I would like it to, but the style itself is not changing. I know that the styles work when applied with static values directly in the css file.
.directive("card", function(){
return{
restrict : "E",
controller: function($scope, $element, $attrs){
var w = this;
window.onresize = function () {
$scope.scalify = {
'-ms-zoom': window.innerHeight/675,
'-moz-transform': 'scale(' + window.innerHeight/675 + ')',
'-o-transform': 'scale(' + window.innerHeight/675 + ')',
'-webkit-transform': 'scale(' + window.innerHeight/675 + ')'
};
$scope.$apply();
}
}
};
})
And here's how I use the ng-Style in the HTML
<card ng-style="scalify">
...
</card>
Hi please see here: http://run.plnkr.co/jfeF9NcPcGroNCsg/ probably you need to work a bit on your css transformation but style is changing when you change size of window as you wanted
app.directive("card", function($window) {
return {
restrict: "E",
link: function(scope, element, attrs) {
scope.onResizeFunction = function() {
//$scope.windowHeight = $window.innerHeight;
// $scope.windowWidth = $window.innerWidth;
var scalify = {
'-ms-zoom': $window.innerHeight / 675,
'-moz-transform': 'scale(' + $window.innerHeight / 675 + ')',
'-o-transform': 'scale(' + $window.innerHeight / 675 + ')',
'-webkit-transform': 'scale(' + $window.innerHeight / 675 + ')',
'background-color': 'red'
};
element.css(scalify);
console.log(element);
};
angular.element($window).bind('resize', function() {
scope.onResizeFunction();
scope.$apply();
});
}
}
});
I'm trying to change the height of a textarea using AngularJS within a directive. I add an attribute auto-resize to my textarea and have the directive defined as:
app.directive('autoResize',function(){
return {
restrict: 'A',
//scope: {},
replace: false,
link: function(scope, element, attrs) {
element.css({
'overflow': 'hidden',
'color': 'red',
'height': '50px'
});
}
}
}
The color and overflow styles are implemented onto the textarea, however the height of the text-area does not go to 50px.
Any help is appreciated.
This directive might do what you're looking for :)
Here is a codepen showing it working: https://codepen.io/benshope/pen/xOPvpm
app.directive('expandingTextarea', function () {
return {
restrict: 'A',
controller: function ($scope, $element, $attrs, $timeout) {
$element.css('min-height', '0');
$element.css('resize', 'none');
$element.css('overflow-y', 'hidden');
setHeight(0);
$timeout(setHeightToScrollHeight);
function setHeight(height) {
$element.css('height', height + 'px');
$element.css('max-height', height + 'px');
}
function setHeightToScrollHeight() {
setHeight(0);
var scrollHeight = angular.element($element)[0]
.scrollHeight;
if (scrollHeight !== undefined) {
setHeight(scrollHeight);
}
}
$scope.$watch(function () {
return angular.element($element)[0].value;
}, setHeightToScrollHeight);
}
};
});
you should set the rows attribute on a textarea rather than changing the height through css.
app.directive('autoResize',function(){
return {
restrict: 'A',
//scope: {},
replace: false,
link: function(scope, element, attrs) {
element.css({
'overflow': 'hidden',
'color': 'red'
});
element.attr("rows", 5);
}
}
}
http://www.w3schools.com/tags/att_textarea_rows.asp
You must to use 'style' for manipulation of css attributes at the DOM level instead 'css()'. You can use the '.css()' method when you are using jQuery. Try this in your directive.
element.style.height = '50px';
element.style.overflow = 'hidden';
element.style.color = 'red';
See reference here