how to append div into one div using angularjs - javascript

<div data-ng-controller="maincontrol">
<div class="main">
</div>
<button data-ng-click="submit()">click</button>
</div>
when i click on click button i want to append one div within main div . i want to append one new div (dynamically)for each and every click .also i want to find whether children div exist or not .
i will do like this in jquery
$('main').append();
i will pass div within append();
but how to do by using angular..js ?

Using a directive could be a solution, but it's still too close to jQuery. When you play with Angular, you have to think differently.
jQuery is procedural.
1- I am finding an element in the dom
2- I am doing some stuff
3- I am adding, removing, updating elements in the dom
angular is declarative
You define your data
You define how your data should be displayed (using ng-repeat, ng-class, etc..)
then..
when you are playing with your data, the view is automatically updating.
If you want to play correctly with angular you should maybe do something like:
Template:
<div class="main">
<div ng-repeat="stuff in stuffs"><h1>{{stuff.title}}</h1> <p>{{stuff.content}}</p></div>
</div>
Controller:
function MainCtrl() {
$scope.stuffs = [];
$scope.submit = function() {
$scope.stuffs.push({title: 'Hello', content: 'world'});
}
}

It's generally best to create a directive for DOM manipulation ( many other uses for directives also).
Within a directive you have access to the angular.element . If jQuery is installed before angular.js in page, this is a jQuery object, otherwise it is a jqLite object that has many jQUery compatible methods.
Very simple example:
<button data-ng-click="submit()" my-directive>click</button>
app.directive('myDirective',function(){
return function(scope, element, attrs){
element.click(function(){
element.parent().find('.main').append('<div>Some text</div>')
})
}
})
Read up on directives and angular.element

Related

Angularjs doesn't work for display none style

I'm trying to use AngularJS with Tippy.JS for tooltips.
Tippy's HTML template tooltip (#creating-html-templates) requires us to use style="display: none" for the template, and it handles the rest.
I want to use angularjs features in the tooltip template but failed.
Here is a fiddle which reproduces the problem. #fiddle
If you remove style="display: none" it works, but Tippy doesn't.
Is there any walkarounds for this?
Update
#Razzildinho solution works only to render the value. but it cannot communicate back to the controller. It is one-way data binding, model to tippy.
Inside Tippy:
Outside:
Fiddle
Using the element id as the html option removes all javascript bindings. To keep them use the DOM element. You should also append within the element that has your controller attached.
<!-- Add ID to the controller div -->
<div ng-controller="FrameController as vm" id="controller">
You also need to remove the display: none; from your template html. From the documentation:
If you want to clone the template's content into the tooltip, specify the template's id in the html setting. Otherwise use the DOM element itself, which allows you to keep listeners attached. If you use the DOM element choice, ensure it's not hidden with display: none;.
And then your javascript for tippy should be:
setTimeout(function() {
angular.bootstrap(document.getElementById('body'), ['app']);
tippy('.tippy', {
position: 'bottom',
animation: 'fade',
arrow: true,
interactive: true,
/* The following 2 lines are new */
html: document.getElementById('my-template-id'),
appendTo: document.getElementById('controller')
})
});
It's because the resulting html and widget is working outside angular scope. The same would happen if you try to implement boostrap widgets and add some angular behavior. That's why boostrap-ui exists, to bridge those two worlds.
The best way to workaround this is by creating directives that link your js pluging with angular. When doing the directive, you might need to recreate the plugin when the expression changes by setting a watcher on vm.message.
See this post as an example: http://bencentra.com/code/2015/09/29/jquery-plugins-angular-directives.html

Get parent element in Angular directive

I'm attempting to find the parent tr element when I use clicks a button on a datepicker calendar. Since I don't want to use jQuery in the form of a script tag (edit) in my Angular app, and this isn't possible using strictly CSS, I created the directive below. The elm.find is able to find and alter the css of the button correctly, so I know that I've found the element I'm looking for, however now I need to travel up the DOM.
I'm used to jQuery syntax, which doesn't work, and I haven't been able to find anything effective on the interwebs. Any chance someone could help me out with the syntax?
/* Linker for the directive */
var linker = function (scope, elm, attrs) {
elm.on('click', function() {
elm.find('table tbody tr button.active').parent('td').css('background-color', 'red');
});
};
EDIT
This is a directive that needs to be placed on a uib-datepicker element (Angular UI Bootstrap) in order to change alter the background-color for an entire row. The framework doesn't come with this functionality and the HTML isn't generated until the page loads.
I need to attach the directive to the element below, find the selected item and then work back up the DOM to find the parent tr.
<uib-datepicker highlightselectedrow class="well well-sm" ></uib-datepicker>
.parent will look exact the upper element only. I'd say that rather use .closest so it will search in parent till it gets td
elm.find('table tbody tr button.active')
.closest('td').css('background-color', 'red');
What about taking a more angular approach than psuedo jQuery? This is based on the ngStyle Angular doc:
<div ng-style="myStyle">Test</div>
<div ng-click="myStyle={'background-color':'red'}">Click Me</div>
You would then place the click event on whatever element you want (td). The ng-style can be moved to what you want affected (tr).

Angularjs - is there a way to programatically click on an HTML <select> element?

I've seen a javascript solution that goes a little something like this:
var select = document.getElementById('selectId')
select.click();
Is there an AngularJS approach/best practice to the same thing? (Off the top of my head, you'd wrap the above code in an ng-click)
Yes there is. Here's the angular equivalent of what you have in JavaScript
angular.element('#selectId').trigger('click');
Working example
Any DOM manipulation in angular should occur inside of a directive.
View
<div id="selectId" clickMe>content</div>
Inside of a directive the link function triggers after the view is compiled. The second parameter in the link function is the element which the directive is placed on, this gives performance benefits since there is no need to traverse the dom. It is a JQlite element which you can directly call methods on.
Directive
app.directive('click-me', function(){
return{
link(scope, el, attr){
$(el).trigger('click');
}
}
});

AngularJS use directive-name in scope as string

I have nested angular.js templates. Each template has it's own directive. Based of the data passed to the ParentTemplate, angular.js should call the matching directive.
<div class="parent-template">
<div class="{{childTemplate}}"></div>
<div class="template1"></div>
</div>
Lets say that $scope.childTemplate = template1. Both divs evaluate to the same content <div class="template1"></div> but only the second div calls the directive to show the template as expected.
I need a dynamic way to call the corresponding template directive
Here is the directive for template1
angular.module('myApp').directive('template1', function(){
return {
restrict: 'C',
templateUrl: 'templates/template1.html'
}
});
Directives for other templates directives work similar.
You try to set the class of the DOM element.
You can do this with ngClass.
Otherwise if you would like to set your directive as an attribute of the DOM element. Like this: <div template1> </div>
You can try this way:
var myEl = angular.element( document.querySelector( '#divID' ) );
myEl.attr('myattr',"attr val");
Try:
<div ng-class="childTemplate"><div>
Did you ever solve this? I have a similar challenge, which I currently solve by using ng-include, like so:
<div class="parent-template">
<div ng-include="'templates/template1'"></div>
<div class="template1"></div>
</div>
This works for your example, but gets more tricky when a directive does more than just wrapping a template, e.g. working with the DOM or adding a controller.
What you can do in that case is using the directive inside the template.
However, this feels all kinda hacky, i'd like a more direct approach
This was, for me, all sparked by an article on react plugins, in which you basically enumerate over a set of react component to get a feature set: https://nylas.com/blog/react-plugins

write custom function for navigation angularjs

So I have a navigation that I want to have a dropdrown menu with sub-menu functionality on it. I tried ng-show for showing and hiding the menus but then I would have to go back and click on item again to hide it. I want to be able to click to show, then click anywhere else to hide it.
trying to use ng-click but not sure where I should put my custom function that I want to retrieve regardless of the controller being used.
Would I put something like this in a directive? The function is not calling html or getting any content like a factory is generally for, it simply shows and hides content on different click events.
There are probably more complicated ways of doing this that might be more elegant, but I've found this to do the trick in the past. Assumes you're loading jQuery before Angular so $ is full jQuery. If you're finding yourself doing this with many different DOM elements though, it might be more effective to break this out into a factory that allows many objects to register themselves in this way with just one binding to body.
app.directive('clickOffHide',function() {
return {
...
link: function(.., elem, ..) {
$('body').click(function(evt) {
var $elem = $(elem);
var $target = $(evt.target);
if($elem.is($target) || $elem.has($target).length > 0) return;
$elem.hide();
});
}
}
});
You could try using ng-blur on the drop-down element.
<div ng-class="dropDown" ng-blur="functionToHideElement" tabindex="100">Products</div>
A div element can accept a blur event if it has a specified tabindex.
This way you can use a baked in Angular directive rather than creating your own.

Categories