I am presenting my issue in a simple manner as below
There is a index.html as below
Index.html
<script src="js/libs/jquery/jquery.js"></script> <!--JQuery library-->
<script src="js/libs/angularjs/angular.js"></script>
<script src="js/libs/angularjs/app.js"></script>
{{title}}<br>
<ng-include src="'document.html'"></ng-include><br>
newPage
My app.js is as follows
angular.module('myApp',[])
.controller('myController',function($scope){
//array to store the items
$scope.title = "This is a test message";
$scope.secondPage = "this is the second page"
});
The document.html is as follows
<div ng-controller="myController">
{{secondPage}}
</div>
I need to run the document.html in a new page, but obviously since the document.html does not have the import script of angular.js,app.js it won't render. But if i do put the script statements in document.html there will be multiple imports in the index.html. How do i solve this issue ?
Require.js would not solve this issue.
One bad way to solve the issue would be import the document.html as text and remove the importing statements.(bad bad way !!)
Create a new page for the new window opener similar to index.html
So your code will be like:
Index.html
<script src="js/libs/jquery/jquery.js"></script> <!--JQuery library-->
<script src="js/libs/angularjs/angular.js"></script>
<script src="js/libs/angularjs/app.js"></script>
{{title}}<br>
<ng-include src="'document.html'"></ng-include><br>
newPage
documentwindow.html
<script src="js/libs/jquery/jquery.js"></script> <!--JQuery library-->
<script src="js/libs/angularjs/angular.js"></script>
<script src="js/libs/angularjs/app.js"></script>
{{title}}<br>
<ng-include src="'document.html'"></ng-include><br>
Hope this works for you
Related
I'm using both AngularJS (v1.6.4) and jQuery (v2.1.4) in my web application. I included static html files using ng-include. So my index.html is like that:
<body>
<div id="wrapper" ng-controller="mainCtrl">
<div ng-include="'partials/header.html'"></div>
<div ng-include="'partials/menu.html'"></div>
<div class="content-page">
<div ng-view></div>
<div ng-include="'partials/footer.html'"></div>
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="plugins/jquery-datatables-editable/jquery.dataTables.js"></script>
<script src="plugins/datatables/dataTables.bootstrap.js"></script>
<script src="assets/js/main.js"></script>
<script>
$("#datatable-editable").DataTable();
</script>
</body>
As you see above I have 3 include files and 1 view. I used datatable in angular view. And I want to initialize it in my index.html file with $("#datatable-editable").DataTable(); But it doesn't work. When I write html elements directly to the page instead of including, it works fine. Why is this happening? How can I solve it?
I am setting up an architecture for an MVC6 app, and I'm relying heavily on ViewComponents. My goal is to let each ViewComponent have its own javascript section, but from reading here rendersection does not work with ViewComponents so I've been trying to do it in another way.
In my _Layout.cshtml
I have this part in just before the closing of the body tag:
#{Html.RenderPartial("_LayoutScriptsPartial"); }
In _LayoutScriptsPartial
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js">
</script>
<script src="~/js/app.min.js" asp-append-version="true"></script>
</environment>
Now in one of my components at /Views/Shared/Components/MyComponent/Default.cshtml I reference another partial view that has this content, it's for a carousel ViewComponent
#model MyProj.MyViewModel
#{Html.RenderPartial("_LayoutScriptsPartial"); }
#if (!string.IsNullOrEmpty(Model.ImageUrl))
{
<script type="text/javascript">
var cssClass= "#Model.cssClass";
var imageUrl = "#Model.ImageUrl";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
}
Only reason I had to do this was to have all required js files available for my view component.
As you can see, I reference _LayoutScriptsPartial multiple times. When I debug using chromes f12 and watching the network section, I do not se the same javascript files being downloaded multiple times. Still I have a bad feeling about this solution. I have looked around and have not found any good solutions for working with js files and ViewComponents that I really liked. Something like this would suit my needs.
My question: how good is this solution, whats the pros and cons and are there any better ways to work with js files and ViewComponents?
There are 3 main cases for an ideal solution to your problem:
ViewComponent is added 0 times and the corresponding JavaScript library is added 0 times
ViewComponent is added 1 time, the corresponding JavaScript library is added 1 time and the dynamically created initialization JavaScript is created once and placed after the library.
ViewComponent is added many times, the corresponding JavaScript library is added 1 time and the dynamically created initialization JavaScript is created for each ViewComponent and are all placed after the library.
So in your example, jquery and app.js are your libraries while your dynamically created initialization JavaScript is the part that references #Model in your <script type="text/javascript"> tag. Let's say we added your component to a view 3 times (I'll replace #RenderBody() with the resulting html from a view that invokes your component 3 times):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - MyProj.Web</title>
<environment names="Development,Staging,Production">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/culture-flags.css" />
</environment>
</head>
<body>
<header>#Html.Partial("~/Views/Shared/_Header.cshtml")</header>
<main>
<nav></nav>
<article>
<div class="container body-content">
<!--#RenderBody()-->
<!--#await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t1", ImageUrl="1.jpg"})-->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t1";
var imageUrl = "1.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
<!--#await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t2", ImageUrl="2.jpg"}) -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t2";
var imageUrl = "2.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
<!--#await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t3", ImageUrl="3.jpg"}) -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t3";
var imageUrl = "t3.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
</div>
</article>
<aside></aside>
</main>
<footer>#Html.Partial("~/Views/Shared/_Footer.cshtml")</footer>
<!-- These are the libraries that should only be loaded once -->
<environment names="Development,Staging,Production">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<!-- Ideally this is where the dynamically create scripts would go -->
#RenderSection("scripts", required: false)
</body>
</html>
As you can see, you would be loading the jquery library 4 times, once for your Layout and 3 times for your ViewComponents. Any good browser should only download the file once but will be loaded into memory multiple times and will just overwrite the the same global variables multiple times($ for example).
You might also be tempted to move the library to the top of the Layout and remove the references from the View Component but that is not a best practice either.
The main issue is that section doesn't work with ViewComponents and that appears to be by design. You should think of a ViewComponent as a fancy html helper. I haven't seen any great solutions to this problem but here are a couple of ideas.
Within the View, immediately after you call your component (Component.InvokeAsync("MyComponent")), add your javascript to #section scripts {...}
Create a library js that initializes this component and set data attributes from the element
$(".carousel").each(function() {
var css = $(this).data("carousel-css");
var image = $(this).data("carousel-image");
});
<input class="carousel" type=hidden data-carousel-css="#Model.cssClass" data-carousel-image="#Model.imageURL" />
I'm using Angular 2 to build my web application. When I try to put a tooltip or popover on an image or button, I get the default-looking tooltip instead of the bootstrap one.
I've tried the basic W3Schools examples and did everything as shown, yet it doesn't work.
I believe my problem lies with the correct imports of the bootstrap.js or jQuery, but other bootstrap items like buttons etc. do work properly.
(I use nodejs to install the necessary files/dependencies -> npm install npm install bootstrap npm install jquery)
index.html
<html>
<head>
<base href="/"><!--Without this tag, the browser may not be be able to load resources (images, css, scripts) when "deep linking" into the app. Bad things could happen when someone pastes an application link into the browser's address bar or clicks such a link in an email link. -->
<title>Factory</title>
<link type="text/css" rel="stylesheet" href="/css/styles.css">
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="/node_modules/angular2/bundles/http.dev.js"></script>
<!--<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">-->
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>-->
<!--<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>-->
<!--<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />-->
<!-- stackoverflow suggested settings -->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/boot')
.then(null, console.error.bind(console));
</script>
</head>
<body>
<my-app></my-app>
</body>
</html>
page-with-tooltip(.ts)
import {Component} from "angular2/core";
import ... from ...;
import ... from ...;
...
#Component({
template: `
<div *ngIf="hall" class="container">
<h2>Detail van hal <small>{{hall.name}}</small></h2>
Hover over me
<div class="container">
<div class="hall-box-single">
<div class="hall-box"
[style.width]="hall.areaWidth*4"
[style.height]="hall.areaHeight*4">
<div class="image-container">
<div *ngFor="#item of hall.items">
<a data-toggle="tooltip" title="Popover title">
<img [src]="item.image"
[style.left]="item.posX"
[style.top]="item.posY"/>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
</script>
`})
export class HallDetailComponent implements OnInit {
...
constructor(...) {
...
}
ngOnInit() {
...
(<any>$('[data-toggle="tooltip"]')).tooltip();
$('[data-toggle="tooltip"]').tooltip();
}
}
!Edit!
Added suggestions from users as well as an extract of the running webpage source.
The script tag you wrote in your template is getting ignored, run your JS code from inside the component instead, I suggest you to run it in the ngOnInit() method since you are implementing the OnInit interface.
This should work:
#Component({
selector: 'app',
template: `
Hover over me
`
})
export class AppComponent{
ngAfterViewInit(){
$('[data-toggle="tooltip"]').tooltip();
}
}
using:
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
So specific to your project:
You have three options to fix it:
One is to set a nasty timeout so it initiates the tooltips until you get a response back from the server and they have actually rendered.
The second is to find some method like the ones we try that gets executed everytime the dom changes, not just the first time.
The third and best but a bit more complicated is by implementing a method that gets executed before the page starts rendering, and if you return a promise in that method, the page will wait for the Promise to get done before rendering, so you can return a promise and resolve the promise until you get the answer from the service, that way the dom will be ready the first time the controller loads
I believe the last method is called CanActivate or something like that.
I am using Laravel-4-Bootstrap-Starter-Site. I have this issue loading javascript files: Error: Popover requires tooltip.js It seems that is not causing majors problems but I am losing functionality.
Checking source code we can see that popover is loaded first and before than tooltip file.
<!-- Javascripts -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/popover-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/tab-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/alert-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/transition-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/modal-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/scrollspy-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/carousel-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/dropdown-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/tooltip-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/collapse-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/button-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/4e833b1b206008719982ee4bd4edd6f2/affix-49fe37fdd6b1d004e71a46c3650d6e3b.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/wysihtml5/wysihtml5-0.3.0-5f4b6ad2a53f7fc45751886caf6076e2.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/wysihtml5/bootstrap-wysihtml5-5f4b6ad2a53f7fc45751886caf6076e2.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/datatables-bootstrap-5f4b6ad2a53f7fc45751886caf6076e2.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/datatables.fnReloadAjax-5f4b6ad2a53f7fc45751886caf6076e2.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/jquery.colorbox-5f4b6ad2a53f7fc45751886caf6076e2.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/prettify-5f4b6ad2a53f7fc45751886caf6076e2.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/jquery.uploadfile-88e9f41770fc597c379b2a75086bcb0f.js"></script>
<script src="http://code.dev/assets/compiled/admin/assets/js/common-75a4c5198cfe0c4468991a6000253513.js"></script>
<script type="text/javascript">
$('.wysihtml5').wysihtml5();
$(prettyPrint);
</script>
Question: is there a way to solve this issue?
I have had the same problem. The reason that happens is because basset loads the resources in order by name. and since p comes before t obviously it gets loaded afterwards coming up with the error. Hacking your way around the problem simply rename tooltip with to atolltip in vendors/twbs/bootstrap/js or instead requiring the directory to load the files in basset config you require each single js file in the order you want. The second option i did not test but should work.
I'm following the video tutorials on egghead.io but while trying to follow his example when he created a factory (see video here) I keep getting "angular is not defined" Reference Error but I have included the angular script
This is my html page:
<!DOCTYPE html>
<html>
<head>
<title>Prototype</title>
<link rel="stylesheet" type="text/css" href="foundation.min.css">
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<div data-ng-app="">
<div data-ng-controller="FirstController">
<input type="text" data-ng-model="data.message">
<h1>{{ data.message }}</h1>
</div>
<div data-ng-controller="SecondController">
<input type="text" data-ng-model="data.message">
<h1>{{ data.message }}</h1>
</div>
</div>
<script type="text/javascript" src="angular.min.js"></script>
</body>
</html>
and this is my javascript file "main.js":
//Services
// step 1 create an app
var myApp = angular.module('Data', []).
// tep 2 create factory
// Service name, function
myApp.factory('Data', function(){
return { message: "I'm Data from a Service" }
});
//Controllers
function FirstController($scope, Data){
$scope.data = Data;
}
function SecondController($scope){
}
I have read a few posts where similar happen (here) and please correct me if I'm wrong but I think it is to do with Boot strapping andI have tried manually bootstrapping using angular.bootstrap(document, ['Data']); but with no success, still get same error.
But What I want to know is, Why this works for so many examples online, like the egghead video series, but I have issues as I believe I have followed his video very closely. is it a change in angular in recent versions?
You have to put your script tag after the one that references Angular. Move it out of the head:
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="main.js"></script>
The way you've set it up now, your script runs before Angular is loaded on the page.
You have not placed the script tags for angular js
you can do so by using cdn or downloading the angularjs for your project and then referencing it
after this you have to add your own java script in your case main.js
that should do
I had the same problem as deke. I forgot to include the most important script: angular.js :)
<script type="text/javascript" src="bower_components/angular/angular.min.js"></script>