CSS file is not being loaded dynamically via ng-href - javascript

I am trying to dynamically load different css styles into my page using ng-href, but the page is not being updated with the activated style. Code is as follows:
<html ng-app="myapp" ng-controller="myController as myctrl">
<head>
<link rel="stylesheet" ng-href="../assets/css/{{ myctrl.style }}.css">
</head>
</html>
In my controller, I do the following:
vm.style = "redStyle";
pub.subscribe('style', function(theStyle) {
vm.style = theStyle;
});
The variable in the subscribe is updated with the new style once a publish has taken place. But the respective css file is not being loaded such that the style is updated on the page. Any ideas what I am missing out on?

Here is a working demo
It's very much the same as what you have so it's something else in your code. Hard to tell unless you put up all your code.
Assuming the stylesheet actually does exist, and the style variable is getting updated then my guess is that the culprit is
pub.subscribe()
If this callback is being triggered by something outside of angular then angular wont see the updated variable. You can bring it back into angular space like so:
pub.subscribe('style', function (theStyle) {
$scope.$apply(function(){
vm.style= theStyle;
});
});

Try this:
<link rel="stylesheet" data-ng-if="myctrl.style" data-ng-href="../assets/css/{{ myctrl.style }}.css" />

I solved it differently.
In my html, I gave the link element an id:
<link id="theme" rel="stylesheet" ng-href="../assets/css/{{theme}}.css">
And in the controller I say:
var myTheme = document.getElementById("theme");
var path = "../assets/css/{{theme}}.css";
myTheme.href = path.replace("{theme}", theme.class);

Related

Setting href for .less stylesheet through JS

I'm using cookies to find out if the user is in light or dark mode onload of body. I always use the light.less as the fallback/default if a cookie can't be found. So in my <head> I have
<link rel="stylesheet" type="text/css" href="../assets/main.css">
<link rel="stylesheet/less" type="text/css" id="colorMode" href="../assets/light.less">
<script src="../assets/less.js/dist/less.min.js" type="text/javascript"></script>
and my body tag is as follows:
<body onload="checkNav(); checkCookies();" onresize="checkNav()">
The checkCookies() is the function to review the cookie and act accordingly, it is shown below.
function checkCookies() {
var style = getCookie("style");
if (style == 'dark') {
document.getElementById("colorMode").href = "../assets/dark.less";
document.getElementById("switchIcon").innerHTML = "toggle_on";
document.cookie = "style=dark; path=/~sam.walker";
}
else {
//Already set by default
}
}
The getCookie() function simply returns the relevant style cookie
The colorMode stylesheet with href = ../assets/light.less does change as expected to ../assets/dark.less as I've checked with inspector but the style itself does not physically change. I've checked cache and its nothing to do with that. Any help would be greatly appriciated.
Including the stylesheet as a .less format won't work unless you have <script src="less.js" type="text/javascript"></script> added within the <head> section of your page.
Check out the usage information from Less.js here
less.min.js will find references to LESS files and generates CSS from them when it loads.
You are creating a new reference to a LESS file after that, by which time it is too late for less.js to notice.
You need to call checkCookies(); after you have linked to the LESS stylesheet but before you load the less.js script.
Thanks for your help,
Through your info I have found the following (botch) fix:
var elem = document.getElementById('NameOfOriginalLessGeneratedStyle'); //REQUIRES CHANGE ON SERVER CHANGE
elem.parentNode.removeChild(elem);
//Deleted previous styles
less.refresh();
//Loads new style
Should run after stylesheet href change.

How to change stylesheet with Jquery and Django

Hello I've been trying to solve this problem for quite a while. Back when I was using vanilla html this code seems to work. (Changing from tile view to list view). Now that I have incorporated it in django and the hrefs contains static tags, I dont know how to refer to it in jquery and change its href. Pls help
HTML
<link rel="stylesheet" type="text/css" href="{% static "Stylesheets/tileVersion.css" %}">
I want to change it to this css href
<link rel="stylesheet" href="../Stylesheets/listVersion.css">
JQUERY
$('#listicon').click(function () {
$('link[href="static/Stylesheets/tileVersion.css"]').attr('href', 'static/Stylesheets/listVersion.css');
});
$('#tilesicon').click(function () {
$('link[href="static/Stylesheets/listVersion.css"]').attr('href', 'static/Stylesheets/tileVersion.css');
});
I want to be able to switch between them if possible. Any kind of help would be appreciated
You can do one of two things.
You can use static references to load one CSS file over another, by using a if tag in your code getting the css link value (the address/url) from a variable or from a data source. This compiles during server time. This also means that only one css is loaded at runtime. This is static for the client. For example:
Same as #1, but you can use an inline if to determine which one goes forward to the client.
Lastly, ensure both css files are held within the static process, and maintain your jquery:
$('#listicon').click(function () {
$('link[href="{% static /path/to/first/css/page %}"]').attr('href', '{% static /path/to/first/css/page %}');
});
$('#tilesicon').click(function () {
$('link[href="{% static /path/to/second/css/page %}"]').attr('href', {% static /path/to/second/css/page %});
});
I typed this out of memory, so please bear with me.
Hope this helps.
Just put an additional attribute id for the link tag. You can remove the current stylesheet from head and add another one.
<link rel="stylesheet" id="myid" href="../Stylesheets/listVersion.css">
$('#myid').remove();
$('head').append( $( '<link/>', {'rel' : 'stylesheet', 'id': 'myid', 'href':'newlink' } ));

AngularJS external javascript libraries do not run

First off I do apologize if this is already answered somewhere.
I am having an issue with AngularJS and external libs. For some reason when I attempt to have an external lib preform any sort of visual operation on an element it simply does not run.
One of such external libraries is the jscolor library which adds a really simplistic color picker (source link: http://jscolor.com)
Here is the include code in my index.html:
<link rel="stylesheet" type="text/css" href="app/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="app/css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.6/interact.min.js"></script>
<script src="app/js/lib/jscolor.min.js"></script>
<script src="app/js/lib/angular.min.js"></script>
<script src="app/js/lib/bootstrap.min.js"></script>
<script src="app/js/services/drawCanvas.js"></script>
<script src="app/js/services/colorpicker.js"></script>
<script src="app/js/app.module.js"></script>
<script src="app/js/components/drawableComponent.js"></script>
<script src="app/js/components/navigationComponent.js"></script>
<script src="app/js/components/canvasComponent.js"></script>
As you can see I do have jscolor.min.js included and I can assure you the file is there.
Here is the code in the relative component that contains the input that I am attempting to attach the JS color to.
(function(){
'use strict';
var app = angular.module('app');
app.component('drawable', {
templateUrl: 'app/js/components/drawableComponent.html',
controller: ['$rootScope','$scope', function ElementController($rootScope, $scope){
var self = this;
$scope.drawables = [];
self.$onInit = function() {
//$scope.drawables.push("test");
}
$scope.addDrawable = function(type, css) {
$scope.drawables.push({type:type,css:css});
console.log($scope.drawables);
}
$rootScope.$on("pushDrawable", function(event, args){
$scope.addDrawable(args.type,args.css);
});
self.animateTooltip = function(e) {
$(e.target).find(".draggableTooltip").toggle("slow").css("transform", "translateY(-60%)");
}
}
]
});
})();
Here is the template that is included in this controller (what angular calls when the component is included)
<div class="draggable" ng-repeat="drag in drawables track by $index" style="{{drag.css}}" ng-click="$ctrl.animateTooltip($event)">
<div class="draggableTooltip" style="display:none" >This is a tooltip <input class="jscolor" value="ab2567"></div>
<p> You can drag one element </p>
</div>
As you can see, I am attempting to include jscolor just like they explain in the examples on the jscolor documentation (honestly the implementation of this color picker should be simple and I have no doubts that I am doing it correctly, The calling and implementing that is)
What happens specifically is the input element is a simple text field much like what is shown on jscolor's site. However clicking that element and giving it focus does not launch the color picker as expected.
This is just one example of issues that I have had, another issue I have had and still do have is accordion nav menus dont animate slide down, or function at all whilst inside of a component's template. I think it has something to do with how angular injects templates, however I am wondering if someone can help me out with more experience as to show me the correct way of getting these external libraries to work.
Since the issue is a tad more complex I wasnt able to set up a jsfiddle.
Thanks for your help!
Why don't you try this:
https://ruhley.github.io/angular-color-picker/
It's fully integrated in angular without dependencies on jQuery.

initialize angular on window.onload event

In a thirth party framework, A html page can be modified by providing javascript code that will be added by the framework to the window onload. From their content can be written to the AddIn div element.
How could I inject a angular application into this div element (HTML + js).
<!DOCTYPE html>
<html>
<head>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.0-beta.4/angular.min.js"></script>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script type="text/javascript">
window.onload=function() {
//todo add js code here
}
</script>
</head>
<body>
<div id="AddIn"></div>
</body>
</html>
I can add the html
$('#AddIn').append("<div ng-app='dropboxApp' ng-controller='dropboxController as dropbox'>{{dropbox.label}}</div>");
but I am not sure where to add my angular init code, and get things working
angular.module('dropboxApp', [])
.controller('dropboxController', function () {
var dropbox = this;
dropbox.label = 'hello angular';
});
You could lazily initialize your app on the page instead of using ng-app directive on page. After you html injection you could initialize angular on your page using angular.bootstrap method basically which takes DOM & then inside array it needs module name.
While doing this you need to add your all the angular component files on the page itself after angular reference. They should be initialized before you bootstrap the app on the page.
window.onload=function() {
$('#AddIn').append("<div ng-controller='dropboxController as dropbox'>{{dropbox.label}}</div>");
//add angular html first
//then run angular on the page using angular.bootstrap.
angular.bootstrap($('#AddIn'), ['demo']);
}
Note: Load jQuery before angular to get jQuery compiled DOM instead of get jQLite compiled DOM.
In addition to the Pankaj answer, you can use the Angular $window
$window.onload = function (){}

How do I reference a javascript variable from a razor section?

I'm trying to dynamically render a CSS file to my view, but part of the location of the file is in a javascript variable.
Currently I have:
#section Styles {
#{
<link href="#Url.Content(Model.CssPath)" rel="stylesheet" type="text/css" />
}
}
But I need to include the variable in the path, like this:
#section Styles {
#{
var pathPrefix = "somePath/";
<link href="#Url.Content(pathPrefix + Model.CssPath)" rel="stylesheet" type="text/css" />
}
}
I understand the server-side code is evaluated before the javascript variable exists, so how else do I accomplish this?
First of all - why mixing client-side/server-side code?
You cannot use JS variable along with server-side generated content because - as you said - it is executed on server before client's browsers hits JS code. This is expected behavior.
If this variable value can be determined on the server-side, you should move it there.
If it has to be generated on the client side, you can generate <link> tag using document.createElement('link'); but it seems odd to me :)
Rather than trying to add the stylesheet via the razor view I would put the csspath into a javascript variable and then use jquery to combine it with the pathPrefix and append the stylesheet that way.
something like....
<script>
var cssPath = #Model.cssPath;
var pathPrefix = "www.";
$('head').append('<link rel="stylesheet" type="text/css" href="'+pathPrefix+cssPath+'">');
</script>

Categories