Directives in angular js not working properly - javascript

I have two directives in my first22 module mycustomer1 and mycustomer. Problem is mycustomer directive is not called ? Can anyone explain me what i am doing wrong here?
Below is my html
<!DOCTYPE html>
<html ng-app="first22">
<head>
<link rel="icon" type="image/png" href="globe/images/correct.png"/>
<link rel="stylesheet" type="text/css" href="globe/css/style.css"/>
<script type="text/javascript" src="globe/script/jquery.js"></script>
<script type="text/javascript" src="globe/script/angular.js"></script>
<script type="text/javascript" src="globe/script/mainscope.js"></script>
<script type="text/javascript" src="globe/script/angular-route.js"></script>
</head>
<body >
<div id="maincontainer" ng-controller="nameListCtrl">
<div id="header">
<div id="headtext">HTML5 SAMPLE</div>
<mycustomer/>
<mycustomer1/>
</div>
<div id="sidebar" >
<first-directive></first-directive>
<ul id="mainmenu" style="">
<li ng-repeat="item1 in content"><a style="color:grey;" id="{{item1.title }}" class="asa" ng-click="show=!show" ng-model="checked" ng-href="#/{{item1.title }}">{{item1.title }}</a>
<ul ng-show="show " ng-if="item1.subitems" style="text-align:left;margin-left:25px;">
<li ng-repeat="category in item1.subitems" >
{{ category.title }}
</li>
</ul>
</li>
</ul>
</div>
<div id="content">
<div id="content_flow" ng-view="">
</div>
</div>
<div id="Interactive_content">
<div id="Interactive_content_flow">
<div id="close">
</div>
</div>
</div>
</div>
</body>
</html>
And my angular directive declaration below
var first2 = angular.module('first22', []);
first2.directive('mycustomer1',function()
{
return{
restrict:'E',
replace: 'true',
template:'<h1>aaaaaaaaaaaaaaaaaaaaaa</h1>',
link: function()
{
alert("I'm working");
}
}
})
first2.directive('mycustomer', function()
{
return {
restrict: "E",
replace: 'true',
template: '<h3>Hello World!!</h3>',
link: function()
{
alert("I'm working 1");
}
}
});

Directive names, when being declared should be in camelCase
first2.directive('myCustomer', function() { ... }
When using them in HTML elements, you must use hyphenated-lower-case
<my-customer></my-customer>
Working jsFiddle Demo

As Rene pointed out above, it is only a convention and it works without the camel case too. Raghav code works because he used empty closing tags like this "" and not ""
The issue is that "mycustomer" directive has replace clause in definitation and self-closing tags work only for a few some kinds of tags, browser doesn't close the "mycustomer" tag at all until the point it's parent, div in this case, closes so "mycustomer1" shows up inside the "mycustomer" tag so when "mycustomer" directive runs, it replaces it content which is now "mycustomer1" and hence "mycustomer1" doesn't actually run at all.
In essence, the code by OP really looks like below so when "mycustomer" runs, it removes "mycustomer1" from the HTML because of the "replace" in mycustomer's directive definition.
<div>
<mycustomer>
<mycustomer1></mycustomer>
</mycustomer>
<div>
The reason Seminda's solution works is again that the individual "mycustomer" and "mycustomer1" are included in parent divs so they close right before the div close themselves.
For directives inside directive, checkout "transclude" property working with replace.

Place your directive in the code like below. then it will work.
<div>
<mycustomer />
</div>
<div>
<mycustomer1 />
</div>
Working demo

Related

AngularJS - nginclude sidebar will dont have the function for the dropdown

i have build one web which include sidebar and the main content. I included the sidebar with ng-include , but the sidebar is not able to function.
<html>
<head>
<link href="lepwww/css/maincss.css" rel="stylesheet">
</head>
<body ng-app="myapp" ng-controller="dataController">
<div class="main-container">
<div ng-include="templates"></div>
</div>
<!-- Angular JS Scripts -->
<script src="lepwww/css/angular-1.6.1/angular.js"></script>
<script src="lepwww/css/angular-1.6.1/angular-animate.min.js"></script>
<script src="lepwww/css/angular-1.6.1/angular-aria.min.js"></script>
<script src="lepwww/css/angular-1.6.1/angular-messages.min.js"></script>
<script src="lepwww/vendors/svg-assets-cache/svg-assets-cache.js"></script>
<script src="lepwww/vendors/angular-material/angular-material.js"></script>
<script>
var app = angular.module("myapp", ['ngMaterial', 'ngMessages', 'material.svgAssetsCache']);
app.filter('startFrom', function () {
return (input, start) => {
start = +start; //parse to int
return input.slice(start);
}
});
app.controller("dataController", ["$scope", "$http", "$element",
function ($scope, $http, $element) {
$scope.templates = 'view/layout/sidebar.html';
}
]);
</script>
<script src="lepwww/vendors/jquery/dist/jquery.min.js"></script>
<script src="lepwww/js/dialog/zebra_dialog.js"></script>
<!-- Bootstrap -->
<script src="lepwww/vendors/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="lepwww/js/test.js"></script>
<script src="lepwww/js/utils.js"></script>
</body>
</html>
If i copy direct the code to replace the nginclude, but able to function.
This is my sidebar code:
<div class="col-md-3 left_col">
<div class="left_col scroll-view">
<div class="navbar nav_title" style="border: 0;">
<a href="console.html" class="site_title">
<div class="profile_pic">
<img src="lepwww/images/lep_icon.png" alt="..." width="50" height="50">
</div>
<span>LEP-DMS</span>
</a>
</div>
<div class="clearfix"></div>
<!-- sidebar menu -->
<div id="sidebar-menu" class="main_menu_side main_menu" style=" margin-top:12px">
<div class="menu_section">
<h3>General</h3>
<ul class="nav side-menu">
<li>
<a>
<i class="fa fa-home"></i>Home
<span class="fa fa-chevron-down"></span>
</a>
<ul class="nav child_menu">
<li>
Dashboard
</li>
</ul>
</li>
<li>
<a>
<i class="fa fa-tv"></i> Inventory
<span class="fa fa-chevron-down"></span>
</a>
<ul class="nav child_menu">
<li id="li_hardware">
Hardware
</li>
<li id="li_software" class="">
Software
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
I tried to include the javascript file inside also, still not working.
Tried the method to switch the jquery file and angularjs file(The position of javascript file changed, still not able to work).
Any idea how does this problem occur? Since i check the console also not found any error for this.
Thanks.
If you couldn't find any error in console, that's mean either the code doesn't being trigger or the code being trigger but selector select nothing(it also could be selector undefined but well handle in your code snippet, that probably why it doesn't output undefined exception)
Next if it get trigger, check whether or not your sidebar javascript call before ng-include, simply use break point to verify.
If it is trigger before, you can simply a <script>... <your js code to make sidebar work> ...</script> under the end of your ng-include file. Manually call the function again, at this point, it should work since your html component appear in DOM.

How to make angular load jquery inside ng-include?

I am trying to apply some jquery in my code, but it's not working because i am using with ng-include, how can i solve this?
html:
<html lang="" ng-app="">
<head></head>
<body>
<div class="menu">
<nav class="sidebar">
<nav class="sidebar">
<div ng-include="'app/client.html'"></div>
</nav>
</nav>
</div>
<script type="text/javascript">
$(function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
});
</script>
</body>
</html>
client.html
<div class="client">
<div class="client-open">
<ul class="sidebar-nav">
<li>link1</li>
<li>link</li>
</ul>
</div>
</div>
js:
$(function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
});
Code to alter the DOM directly should go into directive.
Create a directive and attach it to the element you are trying to modify.
Plunkr - https://plnkr.co/edit/AIRb3egGSMkWfd2gpekL?p=preview
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular.js"></script>
<script data-require="jquery#3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script>
angular.module('app', [])
.directive('attachJquery', function() {
return {
restrict: 'A',
link: function (scope, element) {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
}
};
})
</script>
<style>
.tech {
color: red;
}
</style>
</head>
<body>
<div class="menu">
<nav class="sidebar">
<nav class="sidebar">
<div ng-include="'client.html'"></div>
</nav>
</nav>
</div>
</body>
</html>
client.html
<div class="client" attach-jquery>
<div class="client-open">
<ul class="sidebar-nav">
<li>link1</li>
<li>link</li>
</ul>
</div>
</div>
First proposed solution
Make sure that Jquery is loaded in your application before AngularJs.
Move the script inside client.html
Second proposed solution
Make sure that Jquery is loaded in your application before AngularJs.
Move your script into the controller as in the following example
app.controller("myCtrl", function($scope, $rootScope,$timeout) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$rootScope.$on('$includeContentLoaded', function() {
$timeout(function(){
load();
});
});
});
And then enter your function as in the following example
var load = function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
}
You can refer to this SO question for more info.
Angular: ng-include, jQuery not working unless in HTML file
One way of solving this is by creating a custom directive and adding it to div.client , then you can add your jquery code in the compile or link function of that directive.
HTML
<div class="client" load-evt>
...
</div>
Angular Directive
app.directive("loadEvt", function(){
return {
restrict: "A",
compile: function(elem){
//write your code in compile phase
},
link: function(elem, scope){
//or write your code in link phase
}
}
})
Why would you want to use jQuery and angular together?
These are 2 libraries that help you write a webapp, but go about it a VERY different way.
If you need jQuery to modify classes, you should simply use ng-class, as #fissio suggested. But in the usecase you provided, just add class="tech" to the second li. (I presume this isn't really what you wanted to know)
<div class="client">
<div class="client-open">
<ul class="sidebar-nav">
<li>link 1</li>
<li class="tech">link 2</li>
</ul>
</div>
</div>

angularjs multiple controllers on one page

I have a page with multiple controllers, one of the controller is being used in 2 different divs within the same page. I am not sure if it is a scope issue or I just miss something in my code.
here is the plunkr
http://plnkr.co/edit/IowesXE3ag6xOYfB6KrN?p=preview
I want to hide the textbox when the user clicks on 'Savings' link, display the box when clicking on 'Cost' link.
Same controller, but declared twice. therefor - two scopes.
Normally the solution is to move the ng-controller declaration one dom level higher (in your case, to the body element. once only), and have it only once. Otherwise, look into angular services.
see updated plunkr: http://plnkr.co/edit/pWnx2mdMeOeH33LUeTGm?p=preview
Every time you use ng-controller, you make a new instance of said controller, with it's own scope. If you set subCCtrl on the body tag (or a new parent), and remove it from the two divs it is currently on, it works for me.
Other solutions you might want to look in to are by keeping "hideThisBox" on the root scope, broadcasting an event when clicking on save or by keeping it in a service.
You need to make some changes in controller and view.
var app = angular.module('plunker', []);
app.controller('subCCtrl', function($scope) {
$scope.hideThisBox = false;
$scope.update = function(label) {
if (label == 'Cost')
$scope.displaybox = true;
else
$scope.displaybox = false;
}
});
app.controller('subACtrl', function($scope) {
});
app.controller('subBCtrl', function($scope) {
});
HTML :
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script data-require="angular.js#1.0.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js" data-semver="1.0.8"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="subCCtrl" class="row-fluid">
<div class="span6">
<a href="#" ng-click='update("Cost");displaybox=true;'>Cost</a>
<br />
<a href="#" ng-click='update("Savings");displaybox=fasle;'>Savings</a>
<br />
</div>
<hr />
<div ng-controller="subACtrl">Do stuff that uses subACtrl</div>
<div ng-controller="subBCtrl">Do stuff that uses subBCtrl</div>
<hr />
<div ng-controller="subCCtrl" class="row-fluid">
<div class="span3">
<label>If click on 'Savings', hide below box: </label>
</div>
<div ng-hide="hideThisBox" class="span6">
<input type="text" ng-model="test2" ng-show="displaybox"/>
</div>
</div>
</div>
</body>
</html>
I would recommend that you read up on Javascript scope. The issue with your code was the scope of ng-controllers.
You already got your answer i guess, but for those who will come next here is some tips ^^ (hope it will hep):
ng-controller="myCtrl"
will set a new instance of the "myCtrl" controller, with i'ts own scope
The used scope will be the one of the firt div's controller it means that if you have something like:
<div id="maindiv" ng-controller="myCtrl>
<div id="subdiv1">
<div></div>
<div>
<div>some text</div>
</div>
</div>
<div id="subdiv2" ng-controller="myCtrl">
<div>
<span>-</span>
<span>so</span>
<span>this</span>
<span>is</span>
<span>a</span>
<span>subdiv</span>
<span>.</span>
</div>
</div>
</div>
</div>
Subdiv1 will have the same scope as maindiv
But Subdiv2 will have it's own instance of the myCtrl controller's scope.
In a global way, Subdiv2's scope should have erited is data from the maindiv's scope.
Thats just a few easy tips and you will find more usefull ones on SO, or google, but anyway, if it can help some of you it will be cool.

how to replace div using jquery and kendo ui

i'm doing some tests, to do that i took a template on the kendo ui' page.
i clean it a bit to get what i want and right now, i have two div header in my html page.
i remove one at the load of the page and when i click on a button, i just want to remove the current header et set another one instead.
i've tried plenty of things but nothing seems to work correctly using jquery
here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<link href="styles/kendo.common.min.css" rel="stylesheet" />
<link href="styles/kendo.default.min.css" rel="stylesheet" />
<link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
<link href="styles/index.css" rel="stylesheet" />
<script src="js/jquery.min.js"></script>
<script src="js/kendo.all.min.js"></script>
</head>
<!--
Contenu des pages chargées par le paneau left
-->
<body>
<div data-role="view" id="drawer-home" data-layout="drawer-layout" data-title="Inbox"
<p>recherche </p>
</div>
<div data-role="view" id="drawer-starred" data-layout="drawer-layout" data-title="Starred Items">
<p>recherche </p>
</div>
<div data-role="view" id="drawer-drafts" data-layout="drawer-layout" data-title="Drafts">
<p>recherche </p>
</div>
<div data-role="drawer" id="my-drawer" style="width: 270px" data-views="['/', 'drawer-home', 'drawer-starred', 'drawer-drafts']">
<ul data-role="listview" data-type="group"
<li>Menu
<ul>
<li>m1</li>
<li>m2</li>
<li>m3</li>
</ul>
</li>
</ul>
</div>
<div class="Head" data-role="layout" data-id="drawer-layout">
<header data-role="header">
<div class="" data-role="navbar">
<a data-role="button" data-rel="drawer" href="#my-drawer" data-icon="drawer-button" data-align="left"></a>
<span id="compagnyName">Demo</span>
<a data-role="button" onClick="changeHead()" data-icon="drawer-button" data-align="right"></a>
</div>
</header>
</div>
<div class="HeadSearching" data-role="layout" data-id="drawer-layout">
<header data-role="header">
<div data-role="navbar">
<a data-role="button" data-rel="drawer" href="#my-drawer" data-icon="drawer-button" data-align="left"></a>
<input type="text" id="city" name="city" class="k-textbox" placeholder="Ville" data-align="center" />
<select name="country" id="country" data-align="right">
<option>France</option>
<option>Angleterre</option>
<option>Luxembourg</option>
<option>Espagne</option>
</select>
</div>
</header>
</div>
<script>
var app = new kendo.mobile.Application(document.body);
$('.HeadSearching').remove();
</script>
<script>
function changeHead()
{
alert('header replace');
$('.head').replaceWith('.HeadSearching');
}
</script>
</body>
</html>
if someone could help me doing this correctly ..
thanks by advance ;)
Function replaceWith(newContent) as argument use HTML string. replaceWith
You can try something like:
$('.head').replaceWith($('.HeadSearching'));
For this situation maybe is better to use show/hide different div.
This works for me without the '.'
$('Head').replaceWith("HeadSearching");
For class selectors, you need to respect case. You're trying to select the element with $('.head'), but the class name is Head.
I'd suggest you always use lower-case ids and classes for simplicity.
In your case,
$('.Head').replaceWith($('.HeadSearching'));
should work, however you're removing the
element you're trying to replace $('.Head') with:
var app = new kendo.mobile.Application(document.body);
$('.HeadSearching').remove();
So if you want to replace the .Head element with the .HeadSearching element, you need to remove the second line that removes all .HeadSearching elements.
If you want to hide .HeadSearching initially, then you should use $(".HeadSearching").hide() instead, and when you want to replace it, you could simply do
$(".Head").hide()
$(".HeadSearching").show()
and vice versa.

Handlebars.js Partial Sub-Template generation

I am having issue with the Partials/Sub Template generation in the Handlebars.js.
I have used the registerPartials Method properly, but still it is giving some sort of issue in rendering. If I remove the partial template it would render the content properly.
Below is the code that I am using:
<!DOCTYPE html>
<html>
<head>
<title>Handlebars.js example</title>
</head>
<body>
<div id="placeholder">This will get replaced by handlebars.js</div>
<script type="text/javascript" src="handlebars.js"></script>
<script id="myTemplate" type="x-handlebars-template">
{{#each allShoes}}
<li>
<span> {{name}} - </span> price: {{price}}
{{> description}}
</li>
{{/each}}
</script>
<script id="shoe-description" type="x-handlebars-template">
<ul>
<li>{{color}}</li>
<li>{{size}}</li>
</ul>
</script>
<script type="text/javascript">
var source = document.getElementById("myTemplate").innerHTML;
var template = Handlebars.compile(source);
// Register the Partial
//Handlebars.registerPartial("description", $("#shoe-description").html());
var shoesData = {
allShoes:[
{name:"Nike", price:199.00,color:"black", size:10},
{name:"Loafers", price:59.00, color:"blue", size:9},
{name:"Wing Tip", price:259.00, color:"brown", size:11}
]
};
Handlebars.registerPartial("description", $("#shoe-description").html());
document.getElementById("placeholder").innerHTML = template(shoesData);
</script>
</body>
</html>
Is there any issue with the registerPartial?
Any help is appreciated.
Thanks,
Ankit Tanna
I'd guess that your rendering issues are a side effect of asking the browser to render invalid HTML. Your HTML ends up with, more or less, this structure:
<div>
<li>
<ul>...</ul>
</li>
...
</div>
But an <li> must have a <ul>, <ol>, or <menu> as its parent. I quote the specification:
Permitted parent elements
ul, ol, menu
So having a <div> as the parent of an <li> is invalid and the browser may rewrite your not-quite-HTML to make it valid HTML. That correction could be making a mess of your inner lists. Fix your HTML and try again:
<script id="myTemplate" type="x-handlebars-template">
<ul>
{{#each allShoes}}
...
{{/each}}
</ul>
</script>
Demo: http://jsfiddle.net/ambiguous/R23Ak/

Categories

Resources