This question already has answers here:
Toggle between two stylesheets
(7 answers)
Closed 3 years ago.
Trying various answers on "toggle theme with button", I have code, but it is not working
from bootstrap 4, bootswatch themes 'flatly' and 'darkly' have been selected, since I want to offer user of my web page option to select his/her favorite theme
I have put complete 'flatly.min.css' and 'darkly.min.css' into my static files folder (django project), and renamed them to 'light.css' and 'dark.css'
I tried various answers from stack exchange, and currently I use this one:
create switch for changing theme intead of browser page style html
My base.html:
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no">
...
{% include 'base/css.html' %}
{% block base_head %}
{% endblock %}
</head>
<body>
...
{% include 'base/js.html' %}
{% block javascript %}
{% endblock %}
</body>
My css.html:
<!-- custom styling -->
<link rel="stylesheet"
href="{% static 'css/base.css' %}">
<!-- light styling -->
<link rel="stylesheet alternate"
id="theme"
href="{% static 'css/light.css' %}">
<!-- dark styling -->
<link rel="stylesheet alternate"
id="theme"
href="{% static 'css/dark.css' %}">
When I use only 'css/dark.css' (no 'css/light.css' link is declared), I get my page to render dark; if I change to 'css/light.css' (no 'css/dark.css' is declared), page renders light theme.
My js.html:
...
<script src="{% static 'js/ecommerce.sales.js' %}"></script>
<!-- toggle theme js -->
<script src="{% static 'js/toggle_theme.js' %}"></script>
toggle_theme.js says:
console.log('now what') // works at django runserver first run
document.getElementById('toggle-theme').onClick = function() {
console.log('js works'); // not working, js is not run on click
if (document.getElementById('theme').href == "{% static 'css/dark.css' %}") {
document.getElementById('theme').href = "{% static 'css/light.css' %}";
} else {
document.getElementById('theme').href = "{% static 'css/dark.css' %}";
}
}
The button I want to use in the navbar:
<!-- todo: toggle theme -->
<div class="nav-item mx-auto my-auto">
<!-- href="#" -->
<!-- <a class="nav-link dark-theme" -->
<a class="nav-link"
id="toggle-theme"
title="toggle theme">
<!-- id="toggle-theme" -->
<i class="fas fa-lg fa-square"
aria-hidden="true">
<!-- <script src="{% static 'js/toggle_theme.js' %}"></script> -->
</i> </a>
</div>
I did usual django stuff, 'python manage.py collectstatic' and Ctrl-F5 to refresh the development browser. What am I missing here?
Thank you for your help
EDIT:
Although above link to "Toggle between two stylesheets" did solved my issue, it is not complete, because on refresh the theme is set back to default theme. My complete solution is (dark is my default theme):
if (document.getElementById('theme')) {
if (localStorage) {
// console.log('storidge');
if (!localStorage.getItem('theme')) {
localStorage.setItem('theme', 'dark');
} else {
if (localStorage.getItem('theme') == 'dark') {
$("link[id='theme']").attr('href', '/static/css/dark.css');
} else if (localStorage.getItem('theme') == 'light') {
$("link[id='theme']").attr('href', '/static/css/light.css');
}
}
}
}
$('#toggle-theme').click(function() {
if ($("link[id='theme']").attr('href') == '/static/css/dark.css') {
$("link[id='theme']").attr('href', '/static/css/light.css');
localStorage.setItem('theme', 'light');
console.log('changed to light.css');
} else {
$("link[id='theme']").attr('href', '/static/css/dark.css');
localStorage.setItem('theme', 'dark');
console.log('changed to dark.css');
}
});
I do experience some page twinkling at refresh (F5), if light theme is set, but I will have to live with this for now. Dark theme works without twinkling.
Best regards,
Simon
S love nia
Have you tried changing document.getElementById('toggle-theme').onClick = function() { to document.getElementById('toggle-theme').onclick = function() {?
No guarantee that's the only issue, but onclick should be all lower case, and if the initial click isn't being recognized that might be your problem.
Ok, when I refresh my page, and view page source, I get:
<!-- light styling -->
<link rel="stylesheet"
id="theme"
href="/static/css/light.css">
<!-- dark styling -->
<link rel="stylesheet"
id="theme"
href="/static/css/dark.css">
If I inspect elements, I get the same code. Then I click my toggle-button, and view page source, the code stays the same, but when I inspect elements, I get:
<!-- light styling -->
<link rel="stylesheet"
id="theme"
href="/static/css/dark.css">
<!-- dark styling -->
<link rel="stylesheet"
id="theme"
href="/static/css/dark.css">
Both href are "/static/css/dark.css".
So, the code works, but not as expected. This tells me this is not a code to use. Will continue my search.
Related
I want to do an update on a current web app I developed with Django. The current version has multiple uploading fields:
And I changed it to this:
Now I don't know how to update the code to do exactly the same thing, I made some changes, but I can't seem to get the files from the dropzone using request.FILES.getlist('files')
Here is my old code:
HTML:
<h5>Documents de base</h5>
{{ formset.management_form }}
{% for form in formset %}
{{ form|crispy }}
{% endfor %}
View:
...................
if request.method == "POST":
dossierForm = DossierForm(request.POST)
formset = DocumentFormSet(
request.POST, request.FILES, queryset=DocumentdeBase.objects.none()
)
formset2 = PhotoAvantFormSet(
request.POST, request.FILES, queryset=PhotoAvant.objects.none()
)
if dossierForm.is_valid() and formset.is_valid() and formset2.is_valid():
...................
for form in formset.cleaned_data:
# this helps to not crash if the user
# do not upload all the photos
if form:
image = form["documentdebase_image"]
photo = DocumentdeBase(
dossier=dossier_form, documentdebase_image=image
)
photo.save()
for form2 in formset2.cleaned_data:
# this helps to not crash if the user
# do not upload all the photos
if form2:
image2 = form2["photoavant_image"]
photo2 = PhotoAvant(dossier=dossier_form, photoavant_image=image2)
photo2.save()
....................
else:
dossierForm = DossierForm()
formset = DocumentFormSet(queryset=DocumentdeBase.objects.none())
formset2 = PhotoAvantFormSet(queryset=PhotoAvant.objects.none())
Form:
class DocumentdebaseForm(forms.ModelForm):
documentdebase_image = forms.ImageField(label="")
class Meta:
model = DocumentdeBase
fields = ("documentdebase_image",)
And this is the update I made:
HTML:
Documents de Base:
<div class="form-group mb-0">
<input id="input-b1" name="input-b1[]" type="file" class="file" data-browse-on-zone-click="true" multiple>
</div>
Photos avant:
<div class="form-group mb-0">
<input id="input-b2" name="input-b2[]" type="file" class="file" data-browse-on-zone-click="true" multiple>
</div>
And these are the libraries and JS I used:
<!--NEW DRAG DROP COMP-->
<!-- bootstrap 5.x or 4.x is supported. You can also use the bootstrap css 3.3.x versions -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" crossorigin="anonymous">
<!-- default icons used in the plugin are from Bootstrap 5.x icon library (which can be enabled by loading CSS below) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.5.0/font/bootstrap-icons.min.css" crossorigin="anonymous">
<!-- alternatively you can use the font awesome icon library if using with `fas` theme (or Bootstrap 4.x) by uncommenting below. -->
<!-- link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.3/css/all.css" crossorigin="anonymous" -->
<!-- the fileinput plugin styling CSS file -->
<link href="https://cdn.jsdelivr.net/gh/kartik-v/bootstrap-fileinput#5.2.5/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" />
<!-- if using RTL (Right-To-Left) orientation, load the RTL CSS file after fileinput.css by uncommenting below -->
<!-- link href="https://cdn.jsdelivr.net/gh/kartik-v/bootstrap-fileinput#5.2.5/css/fileinput-rtl.min.css" media="all" rel="stylesheet" type="text/css" /-->
<!-- the jQuery Library -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" crossorigin="anonymous"></script>
<!-- piexif.min.js is needed for auto orienting image files OR when restoring exif data in resized images and when you wish to resize images before upload. This must be loaded before fileinput.min.js -->
<script src="https://cdn.jsdelivr.net/gh/kartik-v/bootstrap-fileinput#5.2.5/js/plugins/piexif.min.js" type="text/javascript"></script>
<!-- sortable.min.js is only needed if you wish to sort / rearrange files in initial preview.
This must be loaded before fileinput.min.js -->
<script src="https://cdn.jsdelivr.net/gh/kartik-v/bootstrap-fileinput#5.2.5/js/plugins/sortable.min.js" type="text/javascript"></script>
<!-- bootstrap.bundle.min.js below is needed if you wish to zoom and preview file content in a detail modal dialog. bootstrap 5.x or 4.x is supported. You can also use the bootstrap js 3.3.x versions. -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<!-- the main fileinput plugin script JS file -->
<script src="https://cdn.jsdelivr.net/gh/kartik-v/bootstrap-fileinput#5.2.5/js/fileinput.min.js"></script>
<!-- following theme script is needed to use the Font Awesome 5.x theme (`fas`). Uncomment if needed. -->
<!-- script src="https://cdn.jsdelivr.net/gh/kartik-v/bootstrap-fileinput#5.2.5/themes/fas/theme.min.js"></script -->
<!-- optionally if you need translation for your language then include the locale file as mentioned below (replace LANG.js with your language locale) -->
<script src="https://cdn.jsdelivr.net/gh/kartik-v/bootstrap-fileinput#5.2.5/js/locales/FR.js"></script>
View:
if request.method == "POST":
dossierForm = DossierForm(request.POST)
c = 1
for f1 in request.FILES.getlist("input-b1"):
print(f1)
print(c)
DocumentdeBase.objects.create(
dossier__id=dossierForm.id, documentdebase_image=f1
)
PhotoAvant.objects.create(
dossier__id=dossierForm.id, hotoavant_image=f2
)
c += 1
x = 1
for f2 in request.FILES.getlist("input-b2"):
print(f2)
print(x)
DocumentdeBase.objects.create(
dossier__id=dossierForm.id, documentdebase_image=f1
)
PhotoAvant.objects.create(
dossier__id=dossierForm.id, hotoavant_image=f2
)
x += 1
Don't mind the c and x variables, they are just for debugging.
This is the code I put to see what do I get from the HTML:
print("Documents de base:", request.FILES.getlist("input-b1"))
print("Photos avant:", request.FILES.getlist("input-b2"))
This is the error I receive in the console:
Documents de base: []
Photos avant: []
What am I doing wrong? I suspect the HTML but I'm not sure!
I'm trying to create a form in which the user choices an instance of model object (Invoice) already saved in the database and submits. I've tried to initialize the JS, but have little experience working with JS in html so I'm not totally sure I'm doing it right.
Right now the below code does not render anything besides the submit button in the form. I have tried adding a random input field (worked) and tried unpacking and rendering the "invoices" context as raw text on the same page (also worked) so I think I've narrowed the issue down to it being the form choices.
header.html
<head>
{% load static %}
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Compiled and minified CSS -->
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel = "stylesheet"
href = "https://fonts.googleapis.com/icon?family=Material+Icons">
<script type = "text/javascript"
src = "https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(document).ready(function(){
$('select').formSelect();
});
</script>
</head>
<body>
<nav>
<div class="nav-wrapper">
Elb
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li>Invoice Upload</li>
<li>Inventory Upload</li>
</ul>
</div>
</nav>
{% block content %}
{% endblock %}
</body>
form.html
{% extends 'main/header.html' %}
<body>
{% block content %}
<br>
<br>
<form method="POST">
{% csrf_token %}
<label for="invoice">Invoice</label>
<select id="invoice" name="invoice">
<option class=browser-default value="" disabled selected>Choose invoice</option>
{% for invoice in invoices %}
<option class=browser-default value="{{ invoice }}">{{ invoice }}</option>
{% endfor %}
</select>
<br><br>
<input type="submit" value="Save" />
</form>
{% endblock content %}
</body>
views.py
def inventory_upload(request):
if request.user.username == 'admin': # Check that user is authorized
if request.method == 'POST': # Render HTML of results page returned to user
...do something and return to user...
else: # Initial html display to user
invoices = Invoice.objects.all()
inventory = get_inventory_from_sheet()
form = BulkInventoryUpload
return render(request=request,
template_name='form.html',
context={'invoices': invoices, 'inventory': inventory, 'form': form})
else: # Bounce user back to homepage if not authorized
return redirect('main:homepage')
forms.py
from django import forms
from django.forms import formset_factory
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Invoice
class BulkInventoryUpload(forms.Form):
invoice = forms.CharField(label='invoice', max_length=150)
def get_invoice(self, commit=True):
invoice = self.cleaned_data['invoice']
return invoice
For anyone else running into the same issue (credit to Sean Doherty in comments above for the answer):
JQuery needs to be loaded before CSS (and from my testing it looks like before the JS as well)
The below order got it working for me:
<head>
{% load static %}
<!-- Compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
$(document).ready(function(){
$('select').formSelect();
});
</script>
<!-- Compiled and minified CSS -->
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel = "stylesheet"
href = "https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
I'm trying to display a sidebar that can be toggled on and off, I have a navbar at the top that contains a tag with the id="toggle" for which I added an eventListener (which waits for the HTML to be loaded before running the javascript code) and a corresponding function that should collapse/expand the side menu. However when I try to run the code nothing happens. Any help would be great!
Here is my HTML:
<html>
<head>
<title>Home</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}"/>
<script type="text/javascript" src="{{ url_for('static', filename='index.js') }}"></script>
</head>
<body>
<!-- navbar -->
<div id="navbar">
☰ Menu
Forget me
</div>
<!-- sidebar -->
<div id="mySidenav" class="sidenav">
About
{% for room in chatroom %}
{{ room }}
{% endfor %}
</div>
<body>
</html>
And the js file, which is in the 'static' folder:
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("toggle").onclick = function() {
var sidebar = document.getElementById("mySidenav");
if (sidebar.style.width === "250px") {
sidebar.style.width = "0";
} else {
sidebar.style.width = "250px";
}
};
});
I see two issues without testing any code:
Your closing body tag needs to be </body>, and;
The toggle link will navigate away from the page, and you will need to prevent this. You can do so by changing the toggle element to a button type="button", or adding preventDefault() into your click handler Javascript.
I've inherited a project and am very green regarding UI. This project uses Bootstrap, nvd3, and flot on Chrome. There is a layout view in which jQuery is referenced, and then partial views for each page are rendered in the layout body. On a dashboard page, the graphs don't show up unless jQuery is again referenced in the scripts, but that reference causes the sidebar to cease working. Referencing easing can be duplicated in the dashboard scripts to get both the graphs to appear and the sidebar to function, but one graph still doesn't work properly. This leads me to believe that jQuery and its libraries are being referenced multiple times on the layout and partial views, wiping out the references that display graphs, activate the sidebar, render graphs correctly, etc.
If that's correct, is there a way to trace each jQuery reference? I've tried deleting multiple references in the source code by sight, moving layout references into the HTML body, testing what's being hit through Chrome Developer Tools, re-calling references as described above as a band-aid, and searching here for similar questions, but nothing seems to achieve both the correct visual and functionality. Also, can a duplicated jQuery reference on a different partial view that shares the same parent layout nullify references in any other partial view? Please opine if there's another possible solution not considered here, because I'm ultimately trying to get the sidebar and graphs working properly. Thanks in advance for looking at this.
Here's the layout with references:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>#ViewBag.Title</title>
<meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="shortcut icon" href="/favicon.ico" />
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/icons")
#Scripts.Render("~/bundles/modernizr")
#RenderSection("headcontent", required: false)
<!-- page specific stylesheets -->
<!-- nvd3 charts -->
<link rel="stylesheet" href="/Content/lib/novus-nvd3/nv.d3.min.css">
<!-- owl carousel -->
<link rel="stylesheet" href="/Content/lib/owl-carousel/owl.carousel.css">
<!-- google webfonts -->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400&subset=latin-ext,latin' rel='stylesheet' type='text/css'>
<!-- datepicker -->
<link rel="stylesheet" href="/Content/lib/bootstrap-datepicker/css/datepicker3.css">
<!-- date range picker -->
<link rel="stylesheet" href="/Content/lib/bootstrap-daterangepicker/daterangepicker-bs3.css">
<!-- timepicker -->
<link rel="stylesheet" href="/Content/lib/bootstrap-timepicker/css/bootstrap-timepicker.min.css">
<!-- ion.rangeSlider -->
<link rel="stylesheet" href="/Content/lib/ion.rangeSlider/css/ion.rangeSlider.css">
<!-- bootstrap switches -->
<link href="/Content/lib/bootstrap-switch/build/css/bootstrap3/bootstrap-switch.css" rel="stylesheet">
<!-- 2col multiselect -->
<link href="/Content/lib/multi-select/css/multi-select.css" rel="stylesheet">
<!-- multiselect, tagging -->
<link rel="stylesheet" href="/Content/lib/select2/select2.css">
<!-- main stylesheet -->
<link href="/Content/css/style.css" rel="stylesheet" media="screen">
<!-- moment.js (date library) -->
<script src="/Content/lib/moment-js/moment.min.js"></script>
[styles omitted...]
</head>
<body>
[header omitted...]
<!-- main content -->
<div id="main_wrapper">
[messages omitted...]
#RenderBody()
</div>
<!-- side navigation -->
<nav id="side_nav">
#Html.Partial("~/Views/Shared/_SidebarLeft.cshtml")
</nav>
<!-- jQuery -->
<script src="/Content/js/jquery.min.js"></script>
<!-- easing -->
<script src="/Content/js/jquery.easing.1.3.min.js"></script>
<!-- bootstrap js plugins -->
<script src="/Content/bootstrap/js/bootstrap.min.js"></script>
<!-- top dropdown navigation -->
<script src="/Content/js/tinynav.js"></script>
<!-- perfect scrollbar -->
<script src="/Content/lib/perfect-scrollbar/min/perfect-scrollbar-0.4.8.with-mousewheel.min.js"></script>
<!-- common functions -->
<script src="/Content/js/tisa_common.js"></script>
#RenderSection("Scripts", required: false)
</body>
</html>
And here's the dashboard HTML:
#using Project.Models
#model DashboardViewModel
#{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="heading_b">Prices Chart</div>
<div class="panel-body">
<div id="nvd3_cumulativeLine" style="width: 100%; height: 300px">
<svg></svg>
</div>
</div>
</div>
</div>
</div>
</div>
Finally, here are the dashboard scripts, with removal of jQuery causing the chart to disappear, removal of easing causing the sidebar to cease pop-outs, and removal of both causing the chart to disappear but leaving sidebar functionality intact.
#section Scripts{
<!-- page specific plugins -->
<!-- jQuery DUPLICATE -->
<script src="/Content/js/jquery.min.js"></script>
<!-- easing DUPLICATE -->
<script src="/Content/js/jquery.easing.1.3.min.js"></script>
<!-- nvd3 charts -->
<script src="/Content/lib/d3/d3.min.js"></script>
<script src="/Content/lib/novus-nvd3/nv.d3.min.js"></script>
<!-- flot charts-->
<script src="/Content/lib/flot/jquery.flot.min.js"></script>
<script src="/Content/lib/flot/jquery.flot.pie.min.js"></script>
<script src="/Content/lib/flot/jquery.flot.resize.min.js"></script>
<script src="/Content/lib/flot/jquery.flot.tooltip.min.js"></script>
<!-- clndr -->
<script src="/Content/lib/underscore-js/underscore-min.js"></script>
<script src="/Content/lib/CLNDR/src/clndr.js"></script>
<!-- easy pie chart -->
<script src="/Content/lib/easy-pie-chart/dist/jquery.easypiechart.min.js"></script>
<!-- owl carousel -->
<script src="/Content/lib/owl-carousel/owl.carousel.min.js"></script>
<!-- dashboard graph functions -->
<script src="/Content/js/apps/tisa_dashboard.js"></script>
<script type="text/javascript">
function cumulativeTestData() {
var closes = JSON.parse('#Html.Raw(Json.Encode(Model.Coordinates))')
return [
{
key: "Prices",
values: closes
},
];
}
</script>
}
You are correct in thinking that there is a conflict when loading the same script multiple times. Only load each script one time.
I can see why trying to remove those scripts from the partial view caused your partial views to fail. You are not loading the scripts until after the partial view. They do not exist until after everything in your partial view has been loaded and executed.
In your layout, move the scripts to the header (preferred) or at least to a point before you pull in the partial view. Then in your partial view, make sure there are no references to scripts which have already been loaded.
In partial views I often use a script wrangler to load in scripts which may or may not have been dynamically loaded. Here is something you can use to attempt to load scripts. It checks to see if a script by the same name has already been loaded on the page (specifically in the header tag) and if it has, it does not attempt to load it again. It's not the prettiest, but it gets the job done.
mycode = function()
{
//Put all your custom javascript here.
//This will run when the scripts below have successfully been processed.
}
var headTag = document.getElementsByTagName("head")[0];
var initialScripts = ["/scripts/jquery-2.1.4.min.js",
"/scripts/jquery-ui.min.js",
"/scripts/jquery.timepicker.min.js"];
var neededScripts = [];
for (var z = 0; z < initialScripts.length; z++) {
if (!isScriptLoaded(initialScripts[z]))
neededScripts.push(initialScripts[z]);
}
if(neededScripts.length)
addScripts(neededScripts, headTag, function () { mycode(); delete mycode; }, 0);
else {
mycode(); delete mycode;
}
function addScripts(scriptsToLoad, loadTag, callback, i) {
if (i >= scriptsToLoad.length)
return;
var script = scriptsToLoad[i];
var scriptTag = document.createElement('script');
scriptTag.setAttribute('type', 'text/javascript');
scriptTag.setAttribute('src', script);
if (i >= (scriptsToLoad.length - 1)) {
scriptTag.onload = callback;
}
else {
scriptTag.onload = function () {
console.log("Added script file " + script);
addScripts(scriptsToLoad, loadTag, callback, i + 1);
}
}
loadTag.appendChild(scriptTag);
}
function isScriptLoaded(url) {
var tags = document.getElementsByTagName('script');
for (var i = tags.length; i--;) {
var existingName = tags[i].src.split('/');
existingName = existingName[existingName.length-1];
var newName = url.split('/');
newName = newName[newName.length-1];
if (existingName == newName) return true;
}
return false;
}
I am using AngularJS to display results of my API (my first attempt at AngularJS), and want to use Jquery to add some effects to the page.
The problem is, Jquery seems to load before Angular has time to add images and other elements to the page. This prevents the JQuery effects from working I have been through numerous answers and tutorials, which center around the following solutions, none of which have worked for me.
Another approach suggested was to put the JQuery into "directives", but how would I put the contents of 3 large javascript libraries into an AngularJS directive? Sorry, I'm new in Javascript!
Here are the unsuccessful attempts:
$(window).load(function() {
// load JQuery plugins
$.getScript("./js/plugins.all.min.js");
});
<!-- after Angular is loaded !-->
angular.element(document).ready(function () {
// load JQuery plugins
$.getScript("./js/plugins.all.min.js");
});
<!-- after Jquery-main is loaded !-->
$(document).ready(function() {
// load JQuery plugins
$.getScript("./js/plugins.all.min.js");
});
Here are the relevant extracts of my code:
index.html
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>MyWebpage</title>
<!-- Template includes !-->
<link media="all" rel="stylesheet" href="./css/slider-revolution.css">
<link media="all" rel="stylesheet" href="./css/all.css">
<link media="all" rel="stylesheet" href="./css/style.css" class="color">
</head>
<body ng-app=“myApp">
<div ui-view></div>
</body>
<!-- Application Dependencies -->
<script src="node_modules/angular/angular.js"></script>
<script src="node_modules/angular-ui-router/build/angular-ui-router.js"></script>
<!-- Template scripts !-->
<!-- Application Scripts -->
<script src="scripts/app.js"></script>
<script src="scripts/indexController.js"></script>
app.js :
...
state('index', {
url: '/',
templateUrl: '../views/indexView.html',
controller: 'IndexController as user'
...
indexView.js
...
<!— JQuery plugin gallery -->
<div class="gallery responsive">
<div class="mask" ng-if=“myStuff.banner">
<ul class="slideset">
<ul style="margin:0px; padding:0px">
<li class="slide" data-transition="slidedown" data-slotamount="10" data-masterspeed="300" data-thumb="" ng-repeat="banner in user.banner" width="300">
<! -- load a big ol’ picture !—>
<img ng-src="../../storage/img/{{banner.image.image_url}}">
<div class="caption text-box lfl lfl" data-x="-91" data-y="140" data-speed="300" data-start="800" data-easing="easeOutExpo">
<h1><span>{{banner.banner_title}}</span></h1>
<a class="more" href="{{banner.banner_link}}">READ MORE</a>
<div style="" class="tp-leftarrow tparrows default"></div>
<div style="" class="tp-rightarrow tparrows default"></div>
</div>
</li>
</ul>
</div>
</div>
...
indexController.js:
...
// gets all the data from my API, including image src
vm.getMyStuff = function() {
$http.get('http://localhost:8888/api/public/myapistuff).success(function(myStuff) {
vm.myStuff = myStuff;
}).error(function(error) {
vm.error = error;
});
}
}
})();
$(window).load(function() {
// load JQuery plugins
$.getScript("./js/plugins.all.min.js");
});