I want to reload the background image for a div with the same url inside directive. When my view load, I used this directive to show the image as a background to a div
app.directive('backImg', function () {
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
attrs.$observe('backImg',function(n,o){
if(!n) return;
element.css({
'background-image': 'url(' + n + ')',
'background-size': 'cover'
});
},true);
}
});
My html element looks like this
<div data-ng-if="vm.user.user_id!==undefined" data-back-img="{{vm.serviceUrl}}/image/user/{{vm.user.user_id}}"
class="user-img-div" style="width:100%; height:100%;"></div>
It works fine, but what happens I give a user to re-upload his profile image, so after it uploads, I want to refresh the background image with the same url. How can I make it happen? The above code not seems to be working.
Your issue most possibly is because of spaces in the random string (due to (new Date()).toString()) that you are appending to get the refreshed image from the browser. Spaces mean that you generate a bad image url, so you probably want to wrap url in quotes or use ticks.
Try changing it to:-
element.css({
'background-image': 'url("' + n + '")', //Wrap url in quotes
'background-size': 'cover'
});
Or just get the ticks and append it.
var random = new Date().getTime();
Related
Sorry if this is a bit of a newby question. I'm trying to create a login page that has a background image, while the rest of my pages do not. I've used ng-style but I can't get the property to update on page changes.
in my index.html:
<body ng-app="myApp" ng-style="bodyStyle" ng-controller="bodyController">
//content
</body
bodycontroller:
var image="http://momentumbooks.com.au/wp-content/uploads/2013/06/space.jpg";
if ($location.path() === '/login') {
$scope.bodyStyle = {background: "url(" + image + ") no-repeat center center fixed"};
} else{
$scope.bodyStyle={background: ""}
}
Obviously this doesn't work because the function is only called once. I've tried using rootScope, but I can't seem to use rootScope properties in ng-style (and everywhere i look, people are advising against using rootScope for this purpose). How do I create a dynamic background? Also i'd prefer not to use a controller on my body tag, if possible.
update
The main problem i'm having is that the background image does not update when changing paths. The image is set in bodycontroller, and when logging in and changing paths it is not changed.
Per suggestion I could write a service, I've used them before but only through getters and setters, so I assume i can create a service that sends a call to a controller? Looking something like this:
<body ng-app="myApp" ng-style="bodyStyle" ng-controller="bodyController">
//content
</body
bodycontroller
var image=??;
$scope.bodyStyle = {background: "url(" + image + ") no-repeat center
some service
.service('backgroundService', function (image) {
var backgroundImage = image
// somhow set bodycontroller image?
});
and then somehow call the service when route is changed? I haven't found a way to inject services into my router config, which is what I think i would need for that.
So i figured out an easy way to do this with some help.
in app.js add this:
.run(function ($rootScope, $location) {
$rootScope.$on( "$routeChangeStart", function(event, next, current) {
$rootScope.bodyClass = $location.path().replace('/', '') + '-page';
});
});
and change index to:
<body ng-app="myApp" ng-class="bodyClass">
and Css:
.login-page {
background: url("someImage") no-repeat center center fixed;
}
IMO it would be easier to just toggle an ng-class based on location. So you could do something like -
if ($location.path() === '/login') {
$scope.isLogin = true;
} else{
$scope.isLogin = false;
}
then on the html
<body ng-app="myApp" ng-class="{'customBgClass' : isLogin }" ng-controller="bodyController">
Then just set everything you want on that css class
.customBgClass {
background: url("http://momentumbooks.com.au/wp-content/uploads/2013/06/space.jpg") no-repeat ce;ter center fixed;
}
I have a directive that I am currently making that is an input field of type text. Now I would like this field's width to grow dynamically if the text gets too big for the input field. Below is my directive:
.directive('dynamicInput', function () {
return {
restrict: 'E',
template: '<input type="text" style="display: inherit;" class="form-control" required />',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
console.log('ATTRS: ', attrs);
console.log('ELEMENT: ', element);
if(attrs.width){
console.log('WiDTH: ', attrs);
}
}
}
});
Here is the plunker:
Change Width Dynamically.
I know you can change the CSS class youre using on your element object, however, I dont just want to change the class I want to basically dynamically change the width as the text increases inside the box. So the question is: How can I change the CSS on every fire of the 'onchange' event to the length of the text being entered? Also, I would like to keep this contained within a directive, so that I am not relying on anything within the parent scope in which its declared in.
You can get your input element, and then do whatever you want with it using vanilla javascript or angular object element.
Like this (link function):
var inputEl = angular.element(element.children()[0]);
inputEl.on('keydown', function() {
inputEl.attr('size', inputEl.val().length);
});
This does not do exactly what you want I think, but you get the idea.
You have access to the element inside the directive, so this kind of logic is very easy to implement without depending on anything else but itself.
Modified plunker.
I'm looking to set the background-image (or even render an image via the pseudo elements :after or :before) to the value, which will be a URL, of a rel attribute, but only in certain cases (this is a cloud file listing). For example:
HTML:
<div class="icon ${fileExtension}" rel="${fileURL}"></div>
It would be great if I could do something like this:
CSS:
.icon.png,
.icon.jpg,
.icon.jpeg,
.icon.bmp,
.icon.gif { background-image: attr(rel,url); }
... but obviously that doesn't work as, if I'm not mistaken, the attr() CSS function only works inside pseudo element blocks.
I know there are ways of doing this using conditional JSP or even jQuery logic, but I'd like to figure out a neat way of doing it via CSS3, since I'm only concerned with modern browsers at the moment anyway.
Also, I don't want to explicitly set the background image to the URL or create an <img> element, because by default if the file is not a supported image, I'd rather display a predetermined set of icons.
Using
.icon:after{ content: ""attr(rel)""; }
displays the rel value as text.
A jQuery solution is to add the background-image (taken from the rel value) as inline CSS:
jQuery(function($) {
$('.icon').each(function() {
var $this = $(this);
$this.css('background-image', 'url(' + $this.attr('rel') + ')');
});
});
I've tried to do something using jQuery but i don't exactly understand what you want so i can't go on with my code. So far i've done only this.
EDITED I hope it's exactly what you need
$(function(){
var terms = new Array('png','jpg','jpeg','bmp','gif');
$('.icon').each(function(){
var t = $(this),
rel = t.attr('rel'),
cls = t.attr('class');
cls = cls.split(' ');
for (var i=0; i < terms.length; i++) {
if (terms[i] == cls[1]) {
t.css('background-image','url('+rel+')');
}
}
});
});
if you can give me a better example, to undestand exactly what you want, i hope somebody from here will be able to solve your problem.
Regards,
Stefan
I've decided to go the jQuery route, and used a combination of #ryanve and #stefanz answers. Thanks guys
$(document).ready(function() {
$(".png,.jpg,.jpeg,.bmp,.gif,.tiff").each(function(n) {
var bg = 'url(' + $(this).attr("rel") + ')';
$(this).css('background-image', bg);
});
});
I think this is relatively neat/concise and works well for my needs. Feel free to comment on efficiency, methodology, etc.
I am using SimpleModal and i am opening an Iframe (using ff)
it seems to work ok in ie9 but in ff it is calling the iframe src twice
Thanks for any help
the code i am calling looks like
function addNew(){
var src = "/php/ftp/parsehome.php?dir="+userDir+"&idx=new";
$.modal('<iframe src="' + src + '" height="445" width="800" style="border:0">', {
containerCss:{
backgroundColor:"#E1EFF7",
borderColor:"#00A99D",
height:450,
padding:0,
width:840
},
modal: true
});
}
I ran into the same problem. Looking at the plugin code...
// add styling and attributes to the data
// append to body to get correct dimensions, then move to wrap
s.d.data = data
.attr('id', data.attr('id') || s.o.dataId)
.addClass('simplemodal-data')
.css($.extend(s.o.dataCss, {
display: 'none'
}))
.appendTo('body');
data = null;
You can see the data is added to the page body with the line .appendTo('body'); to calculate the correct dimensions for the modal. If you comment out this line, it will prevent the iframe being called twice.
// add styling and attributes to the data
// append to body to get correct dimensions, then move to wrap
s.d.data = data
.attr('id', data.attr('id') || s.o.dataId)
.addClass('simplemodal-data')
.css($.extend(s.o.dataCss, {
display: 'none'
}));
data = null;
Not sure if this modification will cause your modal size to have the wrong dimensions, but my iframe was set to width=100% and height=100% so didn't affect me.
This one is driving me nuts. It's (yet) another IE6/7 idiosyncrasy, but one of my web pages needs to be loaded using https. In IE6/7 I get the dreaded "contains secure and nonsecure items" message which is causing users to panic. I've gone through the code top to bottom and isolated the problem (as IE sees it) to background images in my CSS. However, these use absolute paths...
background: url(/images/imagename.jpg);
Looks like this is tripping up IE and causing the nonsecure message on https. Anybody got any ideas how to get around this? Any help much appreciated.
That shouldn't be causing you any troubles, as long as the CSS file itself is also coming from HTTPS. Absolute paths without an explicit protocol (i.e. /path/to/file instead of http://example.com/path/to/file) inherit the protocol of the file calling them, be it HTML or CSS.
Can we see your page? It's possible there's something else on the page you're overlooking.
You are correct, relative url paths in background style will cause this message to appear in IE6/7.
The only method I have used successfully, is to either build the absolute path from available browser data, or to hard code the absolute path. Here is an example of how you can build the absolute path with JavaScript:
Using a top level style definition like this:
<style type="text/css">
.fixBgImage {
background: url(/images/imagename.jpg);
}
</style>
You can use a JavaScript function that looks up that rule, and changes the backgroundImage style for that rule. (Keep in mind that this example assumes you've defined the rule on sheet[0])
// this function needs to be run after the page has loaded
// (body.onload, window.onload or something similar)
function fixBackgroundImages() {
// using sheet 0 defined first on this page
var rule = getRule('.fixBgImage', document.styleSheets[0]);
if (rule != null) {
var bgUrl = rule.style.backgroundImage.replace(/^url|[\(\)]/g, '');
bgUrl = fixHttpsBgUrl(bgUrl);
rule.style.backgroundImage = 'url("' + bgUrl + '")';
}
}
function getRule(name, sheet){
var rules = (sheet.rules) ? sheet.rules : sheet.cssRules;
for (var i = 0; i < rules.length; i++) {
if (rules[i] && rules[i].selectorText == name) {
return rules[i];
}
}
return null;
}
// This function returns an absolute path if https is used
function fixHttpsBgUrl(imgUrl){
if (document.location.protocol.indexOf('https') >= 0){
var basepath = document.URL.substring(0, document.URL.lastIndexOf('/') + 1);
var pcol = document.location.protocol + '//';
var host = document.location.hostname;
var port = (document.location.port) ? ':' + document.location.port : '';
if (imgUrl.indexOf('/') == 0){ // server root path
imgUrl = pcol + host + port + imgUrl;
}
else{ // app root
imgUrl = basepath + imgUrl;
}
}
}
Try with:
background: url(//images/imagename.jpg);
According to this answer that should work. Try using it for the stylsheet as well, eg:
<link rel="stylesheet" type="text/css" src="//style/style.css" />
IE should have absolutely no problem with relative-pathed images so long as they're relative to a secure root. The problem you're hitting quite likely is caused elsewhere.
http://blogs.msdn.com/ieinternals/archive/2009/06/22/HTTPS-Mixed-Content-in-IE8.aspx