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.
Related
I have the following code that I need to be able to edit the template of the ckeditor widget. I have learned that templates are immutable. What I want to achieve is to be able to insert a variable in the template. Is it achievable?
( function($, Drupal, drupalSettings, CKEDITOR) {
CKEDITOR.plugins.add('tabslinks',{
requires: 'widget',
lang: 'en',
icons: 'tabslinks',
hidpi: true, // %REMOVE_LINE_CORE%
init: function(editor) {
editor.ui.addButton('tabslinks', {
label: 'Create tabs links',
command: 'tabslinks',
icon: this.path + 'icons/tabslinks.png'
});
editor.addContentsCss(this.path + 'assets/contents.css');
editor.widgets.add('tabslinks',{
allowedContent: 'a(!tabslinks), a[!href];',
requiredContent: 'a',
editables: {
title: {
selector: '.tabslinks'
}
},
template: '<a class="tabslinks" href="" >' +
'Link should be a variable such as the result of var tabtitle ' +
'</a>',
button: 'Create tab title and link',
init: function () {
var tabtitle = this.element.getAttribute('data-cke-saved-href');
if(tabtitle){
this.setData('tabtitle',tabtitle);
}
},
upcast: function(element) {
return element.name == 'a' && element.hasClass('.tabslinks');
},
dialog: 'tabslinks',
data: function() {
/* Note I can edit the attributes in the following without a problem. The problem is that I cannot manipulate the dom, I have used methhods such as editor CKEDITOR.dom.element.createFromHtml(html) but that also breaks the widget, I have also tried to use jquery with no luck */
if(this.data.tabtitle){
this.element.setAttribute('data-cke-saved-href','#' + this.data.tabtitle);
this.element.setAttribute('data-toggle','tab');
}
}
} );
CKEDITOR.dialog.add( 'tabslinks', this.path + 'dialogs/tabslinks.js' );
}
} );
} )(jQuery, Drupal, drupalSettings, CKEDITOR);
I have tried to use many methods trying to manipulating the dom but this breaks the widget. Any suggestions?
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.
I'm using the excellent package Meteor Tags to implement tags, and I'm copying an example UI with a Selectize input. I've also copied another example how to use a filter with Selectize to avoid duplicate tags, this is great and means that if there is an existing tag "mytag", and I type "Mytag" in the select, "mytag" will be added to the document.
So far so good. The problem comes when I force all tags to be lowercase for consistency. I have replaced this line from the Meteor Tags example:
Patterns.addTag(input, {_id: that.data._id});
with this:
Patterns.addTag(input.toLowerCase(), {_id: that.data._id});
Now if I type "Mytag" into the select, and hit Enter, then the text "Mytag" remains in the input, and "mytag" is not shown in the list of selected tags.
What I want to happen is for the input to be cleared and "mytag" added to the list of tags in the select, just as though I had typed "mytag" and hit Enter.
If I refresh the page, "mytag" IS displayed as a tag, so I know that the tag "mytag" is in fact being added to my document. However I can't find any way to make the selectize input update itself without refreshing the page. I've tried all the methods I can find from the API docs without success. Any ideas?
Here is my full js code:
Template.tagInput.rendered = function () {
var that = this;
this.$('.tag-input').selectize({
valueField: 'name',
labelField: 'name',
searchField: ['name'],
create: function(input, cb) {
console.log('create tag: ', input)
Patterns.addTag(input.toLowerCase(), {_id: that.data._id});
var tag = Meteor.tags.findOne({collection: 'patterns', name: input});
if (cb) {
cb(tag);
}
return tag;
},
options: Meteor.tags.find().fetch({}),
render: {
item: function(item, escape) {
return '<div>' +
(item.name ? '<span class="name">' + escape(item.name) + '</span>' : '') +
'</div>';
},
option: function(item, escape) {
var name = item.name;
var caption = item.nRefs;
return '<div>' +
'<span class="name">' + escape(name) + '</span> ' +
(caption ? '<span class="badge">(x' + escape(caption) + ')</span>' : '') +
'</div>';
}
},
onItemAdd: function(value, $item) {
console.log('add tag: ', value);
Patterns.addTag(value, {_id: that.data._id});
},
onItemRemove: function(value) {
console.log('remove tag: ', value);
Patterns.removeTag(value, {_id: that.data._id});
},
createFilter: function (value)
{
// don't differentiate on case
// https://github.com/brianreavis/selectize.js/issues/796
for (var optValue in this.options)
{
var name = this.options[optValue].name; // Property defined by labelField
if (name.toLowerCase() === value.toLowerCase() && name !== value)
{
return false;
}
}
return true;
}
});
};
I'm using the Firebase chat from the tutorial and I added an additional key pair that will keep track of the "status" of each message in the form of a boolean:
myDataRef.push({
name: name,
text: text,
status: false
});
Here is the fiddle.
I'm looking to have the text change automatically when I change the value of status in the database. So if I change it to false for one message, that message turn red instead of the default green.
Here is the bit that I am having trouble with:
var done = myDataRef.orderByChild('status').equalTo(true);
done.on('child_added', function(function(snapshot) {
var obj = snapshot.val();
if(obj.status == true) {
$('.text').attr('class', 'text red');
}
});
The code first runs through all the children looking for those that have the child "status" equal to true. Then it changes the attribute of the results by turning the text red.
However, I am not exactly sure why but I am getting a:
Uncaught SyntaxError: Unexpected token function
I hope someone can help me out here! Thanks.
You have a typo in your example above at:
done.on('child_added', function(function(snapshot) { ... }).
Note that duplicate function. Instead, this should be:
done.on('child_added', function(snapshot) { ... }).
--
Update 2015-03-17:
In your JSFiddle, there are a few errors. First, you create elements with "green" by default:
function displayChatMessage(name, text) {
$('#messagesDiv').prepend('<div class="text green"><i>' + name + '</i> ' + text + '<br>');
};
But, you're not closing the <div> tag, and you're filtering out any cases where obj.status would be false, and thus should update to red:
var done = myDataRef.orderByChild('status').equalTo(true);
done.on('child_added', function(snapshot) {
var obj = snapshot.val();
if(obj.status == true) { <-- Should be 'obj.status == false'
$('.text').attr('class', 'text red');
}
});
The next issue, is that upon color change, you're not selecting any specific child elements - you're selecting all fields with the text class:
var done = myDataRef.orderByChild('status').equalTo(true);
done.on('child_added', function(snapshot) {
var obj = snapshot.val();
if(obj.status == true) {
$('.text').attr('class', 'text red'); <-- Offending line
}
});
You'll need to give each element in the list some identifier, so that you can specifically update that element later on when the status changes. Here's an updated version, which you can test at the JSFiddle located here:
myDataRef.on('child_added', function(snapshot) {
var message = snapshot.val();
var color = (message.status) ? 'green' : 'red';
$('#messagesDiv').prepend(
$('<div />', {
'id' : message.name,
'class' : 'text ' + color,
'html' : '<i>' + message.name + '</i> ' + message.text + '<br>'
})
);
});
myDataRef.on('child_changed', function(snapshot) {
var message = snapshot.val();
var color = (message.status) ? 'green' : 'red';
$('#' + snapshot.key()).attr('class', 'text ' + color);
});
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();
});
}
}
});