I am new to AngularJS, building an application using AngularJS and RequireJS.
In one of the modules having a controller, I created a modal dialogue using $modal service. The modal dialogue has Angular Schema Form with Datepicker Addon.
Datepicker requires some script files to work. When I add those script files in index.html (main page) in the head section, it works within a dialogue box. But I can't change the main page, so I tried loading the dependencies in module file as shown in module.js but it does not work.
module.js
define(
[ angular, .../path to datepicker dependencies ],
function(angular) {
return angular.module("mainctrl", [])
.controller("test", function($scope,$modal) {
$scope.formOperation=function() {
$modal.open({
templateurl:../schema-form.html,
controller: modelCtrl
});
}
})
});
Below is the body section of the main page wherein if I add those script dependencies in head tag, datepicker works.
index.html
<body>
<div data-ng-view="" id="ng-view"></div>
<script src="bower_components/requirejs/require.js" data-main="../scripts/main"></script>
</body>
schema-form.html
<div class="modal-content h-widget-action-form">
<style>
#import url('/addons/h/widgets/h-action/h-action.css');
</style>
<div class="modal-body">
<!-- <i class="glyphicon glyphicon-remove pull-right" data-ng-click="cancel()"></i><br/>
<div data-ng-if="message" class="alert" data-ng-class="message.type">{{message.text}}</div> -->
<form novalidate name="formCtrl" sf-schema="definition" sf-form="form" sf-model="model"></form>
</div>
</div>
I checked the script tags appended by requirejs in index.html in head and it does contain all my datepicker dependencies in correct order (configured using shim), but still datepicker does not work until I specify those dependencies explicitly in the index.html head tag.
Could anyone tell me where I am going wrong?
My first thought was the datepicker component is not a module so define may not load it properly, have you tried wrapping it as a JavaScript module, it may be enough, it attaches itself to angular via
angular.module('schemaForm').directive('pickADate', function() { so it would need to be able to access angular in whatever scope it gets loaded obviously.
I assume you probably solved this already given the age of the issue.
Related
If I put this:
<button type="button" class="btn btn-info" data-toggle="tooltip" data-placement="top" title="Tooltip on top">
Tooltip on top
</button>
Inside the index.html file, just between the <body> tags, it works -
I got the tooltip shown as it should be.
But If i put the same thing in a directive of ng-view - like this:
<div ng-view></div>
The button is shown but the tooltip is not get fired.
The ng-view contains another html template file, using the ngRoute module which contains the <button> tag as specified above.
It seems like jQuery cannot select elements that are located inside the AngularJS ng-view directive.
How could this be solved?
jQuery can and does select the button. However, AngularJS's digest loop is likely removing the tooltip content from the DOM. Outside of the element that hosts the AngularJS application, this does not apply (no pun intended). Furthermore tooltips popovers are added asynchronously.
To make AngularJS recognize the change
import $ from 'jquery';
import 'bootstrap';
import angular from 'angular';
run.$inject = ["$scope"];
function run($scope) {
const tooltippedElements = $('[data-toggle="tooltip"]');
tooltippedElements.on('hidden.bs.tooltip', onShownOrHidden);
tooltippedElements.on('shown.bs.tooltip', onShownOrHidden);
function onShownOrHidden() {
if (!$scope.$phase()) {
$scope.$apply();
}
}
}
angular
.module('app', [])
.run(run);
But instead of going through all of thirs trouble, use
angular-ui-bootstrap or something similar.
I have found the answer:
jQuery selectors, like $('[data-toggle="tooltip"]').tooltip(); are getting actioned before ng-view is getting actioned.
Therefore tooltip selector is trying to select an element which is not already been loaded to the DOM.
The solution for this problem, is simple:
Include jQuery before AngularJS scripts in the index.html file (at the end of the body tag).
Add ng-if directive to each jQuery script that has selectors (but not to the main jQuery file), like this:
<script src="assets/js/scripts.rtl.js" ng-if="initSrc"></script>
Set $rootScope.initSrc=true after any directive/component is loaded.
All of the jQuery functions will be working properly.
I am finding problem in adding the external js file to Ionic 3. Here is what I did, I have created a hamburg.js file in src/js/hamburg.js, and called the script file in index.html at app/index.html. And I have added the html code in testpage.hmtl and css in testpage.scss. Also declared in app.component.ts. Here is my code
app.component.ts
declare var wrapperMenu;
hamburg.js
var wrapperMenu = document.querySelector('.wrapper-menu');
wrapperMenu.addEventListener('click', function(){
wrapperMenu.classList.toggle('open');
})
index.html
<script src="assets/js/hamburg.js"></script>
testpage.html
<div class="wrapper-menu">
<div class="line-menu half start"></div>
<div class="line-menu"></div>
<div class="line-menu half end"></div>
Can somebody guide me please?
There is no need to external js file, this plugin play mostly with CSS.
this snippet
var wrapperMenu = document.querySelector('.wrapper-menu');
wrapperMenu.addEventListener('click', function(){
wrapperMenu.classList.toggle('open');
})
can be putted on app.component.ts file. or if you have separate component for the header will be better to put the code in its ts file specifically on ngOnInit() hook.
Edit the best hook in component life-cycle is to put this code into ngAfterViewInit() hook.
Edit 2: Another good practice is to used the predefined class menu-content-open that is added automatically when the menu is opened and you can change the selector in your CSS code from .open to menu-content-open
check my forked example from your original one here.
Note the code will work perfect when you add it into the ionic app.
Situation: I have a view where I'm including a fragment with ng-include. The fragment loads perfectly and works as expected when inside view where controller is defined.
My problem is, that when I want to include external component inside the "ng-include" fragment "myView.html", it doesn't show up. When including it inside the main view where the controller is, it shows up and works as expected.
Main view:
<div ng-controller="MyController">
<div data-ng-include src="'views/myView.html'"></div>
<!-- When loaded here, the component shows up -->
<!-- <div id="componentDiv"></div> -->
</div>
Fragment "myView.html":
<div>
<div id="componentDiv"></div>
</div>
The component is loaded inside the "MyController", where "componentDiv" is the "id" of "div" where the component is placed:
var testObj = new TestObj({"container": "componentDiv"});
Trying to do this to be able to use this fragment with full functionality in several places.
Any ideas or suggestions what to look up or try?
IMHO I think that by saying "...to be able to use this fragment with full functionality in several places" you just answered your question. What you need is to build a custom directive and use it in any place you like.
see directive samples e.g. Angular documentation on directives
I am working on an application that utilizes both Jquery and AngularJS includes, however Angular does not seem to execute after Jquery has included a file that has AngularJS markup. Jquery is including the "top_nav.html" template and inside this template there lives a angluar ng-include calling cart.html". I need to figure out how to get the angular code to execute after being included by jQuery.
<div id="topNav"></div>
<script>
//outside the document ready statment
$('#topNav').load('includes/top_nav.html');
<script>
top_nav.html:
<div>
...
<div ng-controller="shoppingCart"
class="shopping-cart"ng-include="'includes/cart.html'"></div>
</div>
The jquery load does an ajax request. When the ajax is resolved, the angular have already been bootstrapped (assuming you use ng-app directive), so the html chunk that have been dynamically loaded was not bootstrapped by angular.
So, I guess that on the callback of the jquery load, you need to manually bootstrap angular passing <div id="topNav"></div> as the context. Something like this:
var topNav = $( "#topNav" );
topNav.load( "includes/top_nav.html", function() {
angular.bootstrap(topNav.find("> div")[0], ['topNavAngularModule']);
});
Note: I'm not sure, sorry, I haven't tested it, but I think it might only work if #topNav is located outside ng-app.
I'm looking for a way to load a module (js, css and html) with just one directive anytime during the app life.
<my-module id="contacts"></my-module>
And the template of this directive generates
<my-module id="contacts">
<link type="stylesheet" href="modules/contacts/contacts.css">
<script type="text/javascript" src="modules/contacts/contacts.js"></script>
<ng-include src="modules/contacts/contacts.html"></ng-include>
</my-module>
And the .js file creates a new angular module
// modules/contacts/contacts.js
angular.module('my-contacts', [])
.controller(ContactsCtrl, function($scope) { ... });
And the '.html' uses a controller in this module
// modules/contacts/contacts.html
<ul ng-controller="ContactsCtrl">
<li ng-repeat="contact in contacts">{{ contact.name }}</li>
</ul>
It wont work because the page's module <html ng-app="my-app"> does not depends on my-contacts module. So I would like every module to inject itself as a my-app dependency.
I've found every module (object returned by angular.module) contains a requires array with it's dependencies. I've injected my-contacts into that array and this works:
// modules/contacts/contacts.js
angular.module('my-app').requires.push('my-contacts');
angular.module('my-contacts', [])
.controller(ContactsCtrl, function($scope) { ... });
But I can't find this property on the documentation. Is it standard or it can change anytime? anyone knows?
Update
To be clear, this is not to load a single module with a single component, this is meant to load a entire application, imagine it like a launcher (like MacOS dockbar or Ubuntu's unity sidebar) with dynamically added icons and when one of this icons are clicked it should run the module. But I don't know at the webpage start which apps this launcher should be able to launch and I need to add more applications dynamically. As each app can has it's own directives and services I use angular modules as apps.
<body ng-app="my-app">
<ul>
<li ng-repeat="module in modules">
<button ng-click="selectedApp = module.id">{{ module.name }}</button>
</li>
</ul>
<my-module id="{{ selectedApp }}"></my-module>
</body>
I'm not sure you're trying to abstract the code so much.
What you should be able to do:
Make a module
Put a directive in the module with your contacts list
Inject the module into your page. And use the contact list.
Dependencies are usually the second argument of a module definition. i.e:
angular.module('my-app', ['my-contacts']);
Is this what you were referring to? The dependencies and how to inject them correctly?