How to drag particular div on ng repeat in angularjs - angularjs

I am preparing charts on repeat.
I have applied drag properties to <div>, I am able to drag the div element but if multiple charts are added to that div on ng-repeat it is misbehaving, with only the first div dragging if I drag any other chart.
This is my code (I am using Dev Extreme to prepare charts using Angularjs)
<div style="background-color:white;" id="myElement" dx-dragenter="dragEnter($event)" dx-dragleave="dragLeave($event)" >
<div ng-repeat="chart in FinalPieData" id="innerElement" dx-drag="dragged($event)" dx-dragstart="dragStarted($event)" dx-dragend="dragStopped($event)">
<div class="col-lg-6" ng-repeat="pie in chart" ng-mouseleave="HideTitlePieOnLeave()">
<div id="ibtMulPie" class="ibox float-e-margins">
<div ng-mouseover="ShowTitlePie(pie)">
<div class="demo-container">
<div id="pie" dx-pie-chart="pie"></div>
</div>
</div>
</div>
</div>
</div>
</div>
drag code JS
//pie
$scope.dragStarted = function () {
$("#innerElement").css("background-color", draggedColor);
initialTop = parseInt($("#innerElement").css("top"));
initialLeft = parseInt($("#innerElement").css("left"));
initialPointerY = arguments[0].clientY;
initialPointerX = arguments[0].clientX;
};
$scope.dragged = function () {
$("#innerElement").css("top", initialTop + arguments[0].clientY - initialPointerY);
$("#innerElement").css("left", initialLeft + arguments[0].clientX - initialPointerX);
};
$scope.dragStopped = function () {
$("#innerElement").css("background-color", "green");
};
$scope.dragEnter = function () {
draggedColor = "red";
$("#innerElement").css("background-color", draggedColor);
};
$scope.dragLeave = function () {
draggedColor = "yellow";
$("#innerElement").css("background-color", draggedColor);
};

The repeated divs all have the same id.
You can make all id's unique like so:
ng-repeat="chart in FinalPieData track by $index" id="innerElement{{$index}}"
Now you can fetch the element using the event that you pass into the drag functions, or pass the id in as well and use that in your selector like so:
In html
dx-dragstart="dragStarted($event, $index)"
And in controller
$scope.dragStarted = function (event, index) {
var elementid = "#innerElement" + index;
$(elementid).css("background-color", draggedColor);
initialTop = parseInt($(elementid).css("top"));
initialLeft = parseInt($(elementid).css("left"));
initialPointerY = arguments[0].clientY;
initialPointerX = arguments[0].clientX;
};

Related

Show and Hide a <div> inside an ng-repeat with 'dirPagination' (AngularJS)

In this very site I've seen this question many times, but none of them works for me because of two things: I need the div to toggle when clicking the "options" button, but also to hide when clicking outside of the div; and I need it to work with dirPagination.
I saw this answer, it works fine but with one problem I just can't solve: it shows ALL the hidden divs at the same time, instead of only showing the one I clicked.
Here's my code:
<body ng-controller="MainCtrl">
<!-- pagination -->
<dir-pagination-controls
max-size="7"
direction-links="true"
boundary-links="true">
</dir-pagination-controls>
<ul>
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="dp">
<p>These are some options</p>
</div>
</li>
</ul>
</body>
And the JS to show the options:
//options div
$scope.showOptions = function(event){
if($scope.dp === false || $scope.dp === undefined) {
$scope.dp = true;
event.stopPropagation();
} else {
$scope.dp = false;
}
};
window.onclick = function(){
if($scope.dp){
$scope.dp = false;
$scope.$apply();
}
};
I've made a Plunker in case you wanna se it in action: my Plunker link
Can somebody help me with this issue? :(
Add a new boolean property on your reports array , for example show
var reports = [
{
"ID":1,
"Title":"Report 1",
"Show":false
},
{
"ID":2,
"Title":"Report 2",
"Show":false
}
]
Apply the property in to ng-show and also pass the current report scope object in to showOptions method to write the logic for hide and show.
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="report.Show">
<p>These are some options</p>
</div>
</li>
$scope.showOptions = function(event,report){
report.Show=!report.Show;
/*you can iterate through each reports and change show to false if the clicked report id not equal to report id , Angular JS will automatically update the scope in to the view*/
reports.forEach(function(item, index) {
if (item.ID !== report.ID) {
item.Show = false;
}
});
if($scope.dp === false || $scope.dp === undefined) {
$scope.dp = true;
event.stopPropagation();
} else {
$scope.dp = false;
}
};
https://next.plnkr.co/edit/hnhWMrgR3GMtVcES
You need to use a separate variable for each div you want to show. You could add the dp attribute to the report. There is no need to loop over the reports to hide them. You can just keep track of the currently visible report and hide it when another one is toggled.
Here is the relevant HTML:
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="report.dp">
<p>These are some options</p>
</div>
</li>
and JavaScript
var visibleReport;
$scope.showOptions = function(event, report){
if (report == visibleReport) {
report.dp = !report.dp;
}
else {
if (visibleReport) visibleReport.dp = false;
report.dp = true;
}
visibleReport = report
event.stopPropagation();
};
window.onclick = function(){
if (visibleReport) visibleReport.dp = false;
visibleReport = null;
$scope.$apply();
};
Here is a working plunker https://next.plnkr.co/edit/sWLxBGlF8D22nvYp?preview

Issue with implementing horizontal group menu in Angularjs

I am new to angularjs and was implementing a menu framework which would be both vertical & horizontal depending on a button toggle.The menu being implemented is with custom directives which looks like below.
<my-menu>
<my-menu-item></my-menu-item>
<my-menu-group label="Fruits">
<my-menu-item label="Apple"></my-menu-item>
<my-menu-item label="Orange"></my-menu-item>
</my-menu-group>
<my-menu-group label="Vegetables">
<my-menu-item label="Tomato"></my-menu-item>
<my-menu-item label="Beans"></my-menu-item>
</my-menu-group>
<my-menu>
The template for the <my-menu-group> is:
<li class="my-selectable-item" ng-click="clickedMenuGroupItem()" ng-class="{'my-item-horizontal': !isVertical()}">
<div class="acc-noselect">
<i class="fa {{icon}} my-menu-icon"></i>
{{label}}
<i ng-if="isVertical()"
class="fa fa-angle-right my-group-indicator-left" ng-class="{'fa-rotate-90':isOpen}"></i>
<i ng-if="!isVertical()" style="margin-left:5px;"
class="fa fa-angle-down" ng-class="{'fa-rotate-180':isOpen}"></i>
</div>
The link function has the code snippet as :
link: function(scope,el,attr,ctrl) {
scope.isOpen = false;
scope.closeMenu = function () {
scope.isOpen = false;
};
scope.clickedMenuGroupItem = function () {
scope.isOpen = !scope.isOpen;
if (el.parents('.my-subitem-section').length === 0)
scope.setSubmenuPosition();
ctrl.setOpenMenuScope(scope);
};
scope.isVertical = function() {
return ctrl.isVertical() || el.parents('.my-subitem-section').length > 0;
};
scope.setSubmenuPosition = function(){
var pos = el.offset();
$('.my-subitem-section').css({'left':pos.left + 20, 'top' : 40});
};
}
Vertical menu works just fine.However when the menu is horizontal if I click on 'Fruits' I get the respective list values and then when i click on vegetables both the list gets rendered.What I'm expecting is a toggle functionality.The bottom line here is that I m not able to control the scope of previously clicked element in the link function.
I've tried my best to be as descriptive as possible here.Please help ?

ng-click anywhere on document?

I have this login menu and its show on click but whenever i click its still open. Now i need to implement when user click anywhere on page that $scope.loginOpened = false...(to close that div with login menu)how i can do that? Any suggestion ?
This is an example of login menu:
$scope.toggleLoggedIn = function () {
$scope.loggedInOpened = !$scope.loggedInOpened;
$scope.languagesOpened = false;
$scope.loginOpened = false;
};
EDIT:
<div class="fade-show-hide" ng-show="loggedInOpened" ng-cloak>
#Html.Partial("~/Views/Shared/_LoggedInPartial.cshtml")
</div>
you can use blur()
example
<input type="text" ng-enter="doBlur($event)">
script
$scope.doBlur = function($event){
var target = $event.target;
if (!$scope.loginOpened){
// do more here, like blur or other things
$(target).blur(function() {
//do what you want here
});
}
}
If you want to hide the div you can follow the below process.
<div class="fade-show-hide" ng-hide="loggedInOpened" ng-cloak>
#Html.Partial("~/Views/Shared/_LoggedInPartial.cshtml")
</div>
<button type="button" id="btn" ng-click="toggleLoggedIn()">Hide div</button>
$scope.toggleLoggedIn = function () {
$scope.loggedInOpened = !$scope.loggedInOpened;
$scope.languagesOpened = false;
$scope.loginOpened = true;
};

How can I update a particular variable in an ng-repeat

I have an ng-repeat that contains items, each of which has an ng-click.
<div ng-repeat="item in items">
<div ng-click="clickMe()">Show Item</div>
<div ng-show="show_item" ng-init="show_item = false>Item 1: {{item.name}}</div>
</div>
$scope.clickMe = function () {
$scope.show_item = !$scope.show_item
};
The problem is that I end up with a list of items that all have the show_item variable. For example, if I end up with a list of 10 items, and I click on the second item in the list, then how can I get angular to know that I want to show the 2nd item, and not one of the other items in the list?
All your items are sharing the scope variable show_item. you have to create this variable for each item
Change your ng-show and ng-init to ng-show="item.show_item" and ng-init="item.show_item = false". Also ng-click="clickMe(item)"
$scope.clickMe = function (item) {
item.show_item = !item.show_item
};

Creating a 'More posts...' button in Angular.js

I am currently trying to make a 'show posts' button, for my Angular.js app. I am having trouble in setting the limitTo dynamically from an external script. So far I have:
<body ng-controller="FeedCtrl">
<h1>Feeds</h1>
<div ng-repeat="feed in (feedLoader = (feeds | limitTo:5))">
<p>{{feed.content}}</p>
</div>
<button ng-click="showPosts()">Show more...</button>
</body>
The approach I have taken is this:
$scope.showMorePosts = function () {
$scope.feedLoader = (feeds | limitTo:feedLimit);
}
...then replaced limitTo:5 with limitTo:feedLimit in the inline part of the view.
I have set up a Plunker with the basic setup so far here: http://plnkr.co/edit/OFqkGFKVUHKi2A20c4t3
Any help would be great!
Thanks,
JP
Seems like you were on the right track, but you just needed to define showPosts():
$scope.showMore = function() {
$scope.feedLimit += 1;
}
Full example:
http://plnkr.co/edit/pE49Wt0rvDjWhsKD0WiD?p=preview
HTML
<div ng-repeat="feed in (feedLoader = (feeds | limitTo:feedLimit))">
<p>{{feed.content}}</p>
</div>
<button ng-click="feedLimit = feedLimit + 1">Show more...</button>
JavaScript:
app.controller('FeedCtrl', function($scope) {
$scope.feedLimit = 3;
// ...
});

Resources