Basically, I have the following markup:
<script>
$(function() {
$('.box').on('mousedown', function(e) {
console.log(e);
});
});
</script>
<body ng-controller="MainCtrl">
<ul ui-sortable="sortableOptions" ng-model="list">
<li draggable ng-repeat="item in list">Item: {{item}}</li>
</ul>
<div class="boxes">
Drop to external area: <br/><br/>
<div class="box" style="background: red;"></div>
<div class="box" style="background: yellow;"></div>
<div class="box" style="background: orange;"></div>
</div>
</body>
Fiddle: http://plnkr.co/edit/xKw6sSbymA5M8R2v4OGF?p=preview
Now, I want to be able to drag and drop items from the list to that "external" container.
When user "drops" item to any of colored areas, I want to know that event just happend and which element is affected, as well
Already tried to listen for mousedown/mouseup events on each .box element, but it doesn't work as expected.
The library you are using is sorting library. You need to use drag-drop library for this.
For example, you can use https://github.com/codef0rmer/angular-dragdrop
Refer the docs for all available event callbacks.
Copying the example code snippet directly (for reference check here),
HTML:
<ul class="thumbnails">
<li style='margin-left:10px;' ng-repeat="item in list1">
<div class="btn"
data-drop="true"
ng-model='list1'
jqyoui-droppable="{index: {{$index}}}">
<div class="btn btn-info"
ng-show="item.title"
data-drag="{{item.drag}}"
data-jqyoui-options="{revert: 'invalid'}"
ng-model="list1"
jqyoui-draggable="{index: {{$index}},placeholder:true,animate:true}">
{{item.title}}
</div>
</div>
</li>
</ul>
<div class="container form-inline" style="text-align: center;">
<div class="btn"
ng-repeat="item in list2 | orderBy : 'title'"
data-drop="true"
ng-model='list2'
jqyoui-droppable="{index: {{$index}}, applyFilter: 'filterIt'}">
<div class="btn btn-info"
data-drag="{{item.drag}}"
data-jqyoui-options="{revert: 'invalid'}"
ng-model="list2"
jqyoui-draggable="{index: {{$index}},animate:true, applyFilter: 'filterIt'}"
ng-hide="!item.title">
{{item.title}}
</div>
</div>
</div>
Controller:
App.controller('YourCtrl', function($scope, $filter) {
$scope.filterIt = function() {
return $filter('orderBy')($scope.list2, 'title');
};
$scope.list1 = [];
$scope.list2 = [
{ 'title': 'Item 3', 'drag': true },
{ 'title': 'Item 2', 'drag': true },
{ 'title': 'Item 1', 'drag': true },
{ 'title': 'Item 4', 'drag': true }
];
angular.forEach($scope.list2, function(val, key) {
$scope.list1.push({});
});
});
Hope this solves your problem.
Try replace the 'mousedown' with 'drop'.
Related
Here is my fiddle : SORTABLE-DEMO
"Widgets" is from where I can pull clones and "Group1" that has id="B" is where I can drop the clones into.
I am creating clones on click of "+", attaching the id="B" attribute to be able to drop into these clones. However, dropping is not possible. (Maybe because of duplicate ids)
Is there any other way to solve this?
Any help would be much appreciated. Thank you..
new Sortable(document.getElementById('B'), {
group: {
name: 'letters',
put: true
},
onAdd: function(event) {
console.log(event.item);
}
});
$('#addRow').on('click', function(e) {
var len = $('.child-border').length;
$('.parent-border').clone().attr('id','B')
.toggleClass('parent-border child-border').hide()
.appendTo('#container').slideDown('slow');
});
I've never used RubaXa... so had to fiddle through it.
Example: https://jsfiddle.net/Twisty/jsnvxsev/1/
HTML
<ul id="widgets-1">
<h5>Widgets</h5>
<br>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<br>
<ul id="widgets-2">
<h5>Group 1</h5>
<br>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<br>
<ul class="parent-border">
<div class="form-group">
<div class="col-sm-12">
<button type="button" id="deleteRow" class="btn btn-danger btn-circle btn-lg pull-right"><i class="glyphicon glyphicon glyphicon-trash"></i></button>
</div>
</div>
</ul>
<div id="container"></div>
<div class="form-group">
<div class="col-sm-12">
<button type="button" id="addRow" class="btn btn-success btn-circle btn-lg center-block"><i class="glyphicon glyphicon-plus"></i></button>
</div>
</div>
JavaScript
new Sortable($('#widgets-1')[0], {
group: {
name: 'letters',
put: false,
pull: 'clone',
},
setData: function(dataTransfer, element) {
dataTransfer.setData('text', element.textContent);
},
sort: false
});
new Sortable($('#widgets-2')[0], {
group: {
name: 'letters',
put: true
},
onAdd: function(event) {
console.log(event.item);
}
});
$('#addRow').on('click', function(e) {
var len = $('.child-border').length;
var widgCount = $("[id|='widgets']").length;
$('.parent-border').clone().attr('id', 'widgets-' + ++widgCount)
.toggleClass('parent-border child-border').hide()
.appendTo('#container').slideDown('slow');
new Sortable($("#widgets-" + widgCount)[0], {
group: {
name: 'letters',
put: true
},
onAdd: function(event) {
console.log(event.item);
}
});
});
$('#container').on('click', '[id=deleteRow]', function(e) {
$(this).closest('.child-border, .parent-border').remove();
});
After adding the cloned structure, I suspected you needed to initialize the structure for Sorting. This seems to do the trick.
<div ng-app="appPage" ng-controller="appController">
<div class="nav">
<h1 class="logo">Todlio</h1>
<i class="icon setting" style="color:#fff;font-size:1.8em;;position:absolute;top:11px;right:12px;"/></i>
</div>
<div class="todo">
<div class="todo_column">
<div style="font-weight700;text-align:center; margin:20px;">
<a href="#/add" ng-click="addTodo()" class="ui basic button">
<i class="add square icon"></i>
Add
</a>
</div>
<ul>
<a href="#/"><li ng-href="#/" ng-click="detail($index)" ng-repeat="todo in todos">
<h3 ng-model="title">{{ todo.title }}</h3>
<h6>{{ todo.note_date }}</h6>
</li></a>
</ul>
</div>
<div class="todo_full">
<div class="todo_title" ng-scope="todo in todos">
<span><h1>{{ title }}</h1></span>
<span class="check">
<i style="font-size:2em;" class="square outline icon"></i>
<i class="write icon" style="font-size:1.8em;"></i>
</span>
</div>
<h4>Note:</h4>
<p class="todo_note">{{ note }}
</p>
</div>
</div>
</div>
Controller
app.controller("appController", function ($scope) {
$scope.todos = [
{title: "Call Vaibhav", note: "", note_date: ""},
{title: "Grocery", note: "Lemons, Apple and Coffee", note_date: ""},
{title: "Website design for Stallioners", note: "UI/UX on xyz#mail.com", note_date: ""},
{title: "Fill MCA form", note: "First search for all the colleges", note_date: "" }
];
$scope.detail = function(x){
$scope.todos.title = $scope.title;
$scope.todos.note = $scope.note;
};
I want to get the clicked list item title and the note attached to it to the different div below
Can anybody please help. Its a todo app the left half has the list to todos and the right half has a note attached to it or anything checked or not.
There are a few ways to do this. One easy way is as follows:
Define a $scope variable with a name like $scope.currentTodo.
In the repeat loop, the ng-click would set $scope.currentTodo=todo
This current variable will hold the todo object so you can use {{ $scope.currentTodo.title }} in place of {{title}}
Ditch the ng-scope
I have been using Angular ui-bootstrap. In here oneAtATime is not working even though the value is set to true. Here is my code.
<div ng-repeat="group in groups track by group.key">
<uib-accordion close-others="oneAtATime">
<uib-accordion-group>
<uib-accordion-heading >
<div>
{{ group.title }}
<i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</div>
</uib-accordion-heading>
</uib-accordion-group>
</uib-accordion>
</div>
plnkr link.
Your HTML structure is wrong. There should be only single uib-accordion element and multiple uib-accordion-group element. So simply change your code like this:
<uib-accordion close-others="oneAtATime">
<uib-accordion-group ng-repeat="group in groups track by group.key">
<uib-accordion-heading>
<div>
{{ group.title }}
<i class="pull-right glyphicon"
ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</div>
</uib-accordion-heading>
</uib-accordion-group>
</uib-accordion>
What I did is simply moved your ng-repeat expression in uib-accordion-group element.
See the working example below:
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function($scope) {
$scope.oneAtATime = true;
$scope.groups = [{
title: 'Dynamic Group Header - 1',
content: 'Dynamic Group Body - 1',
key: 1
}, {
title: 'Dynamic Group Header - 2',
content: 'Dynamic Group Body - 2',
key: 2
}];
$scope.items = ['Item 1', 'Item 2', 'Item 3'];
$scope.addItem = function() {
var newItemNo = $scope.items.length + 1;
$scope.items.push('Item ' + newItemNo);
};
$scope.status = {
isCustomHeaderOpen: false,
isFirstOpen: true,
open: true,
isFirstDisabled: false
};
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>
<script src="script.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="AccordionDemoCtrl">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="oneAtATime">Open only one at a time
</label>
</div>
<uib-accordion close-others="oneAtATime">
<uib-accordion-group ng-repeat="group in groups track by group.key">
<uib-accordion-heading>
<div>
{{ group.title }}
<i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</div>
</uib-accordion-heading>
</uib-accordion-group>
</uib-accordion>
</div>
</body>
</html>
I have an application that has two forms that are lists of buttons and a form with a list of labels. I choose a person, choose a phone, and on the third form I show a list of phones and their associated people (location). Is it possible to set a variable with ng-click inside an ng-repeat block? I tried settings a variable _person to be equal to the the button text, which would be {{person}}, but _person doesn't seem to be set to anything when I print it on the next form. I'm also not sure if I used ng-init correctly in the first <div>, and should I be using ng-model at all?
<div ng-init="showSelectUser=true; _person=''">
<div class="selectUser" ng-show="showSelectUser">
<h2>Who are you?</h1>
<ul ng-click="showSelectUser=false; showDeviceForm=true;">
<li ng-repeat="person in people">
{{person}}
</li>
</ul>
</div>
<div class="selectDevice" ng-show="showDeviceForm" ng-click="showDeviceForm=false; showDeviceList=true">
<p>person: {{_person}}</p>
<h2>Which phone?</h2>
<ul>
<li ng-repeat="device in devices">
<a class="btn btn-default" href="#" role="button" ng-click="device.location=_person">{{device.name}}</a>
</li>
</ul>
</div>
<div class="devicesView" ng-show="showDeviceList">
<ul>
<li ng-repeat="device in devices">
<h3>{{device.name}}</h3>
<h4 class="deviceLocation">{{device.location}}</h4>
</li>
</ul>
</div>
</div>
angular.module('devicesApp')
.controller('MainCtrl', function ($scope) {
$scope.devices = [
{name: 'iPhone 4', location: 'Desk'},
{name: 'iPhone 5', location: 'Desk'},
{name: 'iPhone 6', location: 'Desk'},
];
$scope.people = [
'John',
'Scott',
'Adam'
];
});
The ngRepeat directive creates a new scope, so if you have ng-click="device.location=_person" the device model will be created in that scope if it not exists. So make sure that device already exists in a parent scope, for example by setting $scope.device = {} in your controller.
_person is undefined, because it is defined in the inner scope of the ng-repeat="person in people". Currently your ng-click sets every device location to undefined.
In general you will have a lot of scope inheritance issues when using expressions in ngClicks instead of doing something like ng-click="setPerson()" and have $scope.setPerson = function () { ... } in your controller.
Please clarify what you want to do in more high level terms and I will update my answer.
Edit
Something like this looks more logical for me. However, I think you will have a lot of UX issues because the user is not able to change its choice after clicking one of the list items.
Note that if you put business logic in JS files instead of templates, it is easier to test.
<div ng-app="devicesApp" ng-controller="MainCtrl">
<div class="selectUser" ng-show="step === 'step1'">
<h2>Who are you?</h2>
<ul>
<li ng-repeat="person in people">
{{person}}
</li>
</ul>
</div>
<div class="selectDevice" ng-show="step === 'step2'">
<p>person: {{selected.person}}</p>
<h2>Which phone?</h2>
<ul>
<li ng-repeat="device in devices"> <a class="btn btn-default" href="#" role="button" ng-click="selectDevice(device)">{{device.name}}</a>
</li>
</ul>
</div>
<div class="devicesView" ng-show="step === 'step3'">
<ul>
<li ng-repeat="device in devices">
<h3>{{device.name}}</h3>
<h4 class="deviceLocation">{{device.location}}</h4>
</li>
</ul>
</div>
</div>
In JS file:
angular.module('devicesApp', []).controller('MainCtrl', function ($scope) {
$scope.devices = [{
name: 'iPhone 4',
location: 'Desk'
}, {
name: 'iPhone 5',
location: 'Desk'
}, {
name: 'iPhone 6',
location: 'Desk'
}, ];
$scope.people = [
'John',
'Scott',
'Adam'];
$scope.selected = {};
$scope.step = 'step1';
$scope.selectPerson = function (person) {
$scope.selected.person = person;
$scope.step = 'step2';
};
$scope.selectDevice = function (device) {
device.location = $scope.selected.person;
$scope.step = 'step3';
}
});
See this JSFiddle.
I have a simple loop with ng-repeat like this:
<li ng-repeat='task in tasks'>
<p> {{task.name}}
<button ng-click="removeTask({{task.id}})">remove</button>
</li>
There is a function in the controller $scope.removeTask(taskID).
As far as I know Angular will first render the view and replace interpolated {{task.id}} with a number, and then, on click event, will evaluate ng-click string.
In this case ng-click gets totally what is expected, ie: ng-click="removeTask(5)". However... it's not doing anything.
Of course I can write a code to get task.id from the $tasks array or even the DOM, but this does not seem like the Angular way.
So, how can one add dynamic content to ng-click directive inside a ng-repeat loop?
Instead of
<button ng-click="removeTask({{task.id}})">remove</button>
do this:
<button ng-click="removeTask(task.id)">remove</button>
Please see this fiddle:
http://jsfiddle.net/JSWorld/Hp4W7/34/
One thing that really hung me up, was when I inspected this html in the browser, instead of seeing it expanded to something like:
<button ng-click="removeTask(1234)">remove</button>
I saw:
<button ng-click="removeTask(task.id)">remove</button>
However, the latter works!
This is because you are in the "Angular World", when inside ng-click="" Angular all ready knows about task.id as you are inside it's model. There is no need to use Data binding, as in {{}}.
Further, if you wanted to pass the task object itself, you can like:
<button ng-click="removeTask(task)">remove</button>
Also worth noting, for people who find this in their searches, is this...
<div ng-repeat="button in buttons" class="bb-button" ng-click="goTo(button.path)">
<div class="bb-button-label">{{ button.label }}</div>
<div class="bb-button-description">{{ button.description }}</div>
</div>
Note the value of ng-click. The parameter passed to goTo() is a string from a property of the binding object (the button), but it is not wrapped in quotes. Looks like AngularJS handles that for us. I got hung up on that for a few minutes.
this works. thanks. I am injecting custom html and compile it using angular in the controller.
var tableContent= '<div>Search: <input ng-model="searchText"></div>'
+'<div class="table-heading">'
+ '<div class="table-col">Customer ID</div>'
+ ' <div class="table-col" ng-click="vm.openDialog(c.CustomerId)">{{c.CustomerId}}</div>';
$timeout(function () {
var linkingFunction = $compile(tableContent);
var elem = linkingFunction($scope);
// You can then use the DOM element like normal.
jQuery(tablePanel).append(elem);
console.log("timeout");
},100);
Above answers are excellent. You can look at the following full code example so that you could exactly know how to use
var app = angular.module('hyperCrudApp', []);
app.controller('usersCtrl', function($scope, $http) {
$http.get("https://jsonplaceholder.typicode.com/users").then(function (response) {
console.log(response.data)
$scope.users = response.data;
$scope.setKey = function (userId){
alert(userId)
if(localStorage){
localStorage.setItem("userId", userId)
} else {
alert("No support of localStorage")
return
}
}//function closed
});
});
#header{
color: green;
font-weight: bold;
}
<!DOCTYPE html>
<html>
<head>
<title>HyperCrud</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body>
<!-- NAVBAR STARTS -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">HyperCrud</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
<li class="dropdown">
Apps<span class="caret"></span>
<ul class="dropdown-menu">
<li>qAlarm »</li>
<li>YtEdit »</li>
<li>GWeather »</li>
<li role="separator" class="divider"></li>
<li>WadStore »</li>
<li>chatsAll</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>Login</li>
<li>Register</li>
<li>Services<span class="sr-only">(current)</span></li>
</ul>
</div>
</div>
</nav>
<!--NAVBAR ENDS-->
<br>
<br>
<div ng-app="hyperCrudApp" ng-controller="usersCtrl" class="container">
<div class="row">
<div class="col-sm-12 col-md-12">
<center>
<h1 id="header"> Users </h1>
</center>
</div>
</div>
<div class="row" >
<!--ITERATING USERS LIST-->
<div class="col-sm-6 col-md-4" ng-repeat="user in users">
<div class="thumbnail">
<center>
<img src="https://cdn2.iconfinder.com/data/icons/users-2/512/User_1-512.png" alt="Image - {{user.name}}" class="img-responsive img-circle" style="width: 100px">
<hr>
</center>
<div class="caption">
<center>
<h3>{{user.name}}</h3>
<p>{{user.email}}</p>
<p>+91 {{user.phone}}</p>
<p>{{user.address.city}}</p>
</center>
</div>
<div class="caption">
DELETE
UPDATE
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<a href="/regiser/">
<img src="http://img.bhs4.com/b7/b/b7b76402439268b532e3429b3f1d1db0b28651d5_large.jpg" alt="Register Image" class="img-responsive img-circle" style="width: 100%">
</a>
</div>
</div>
</div>
<!--ROW ENDS-->
</div>
</body>
</html>
HTML:
<div ng-repeat="scannedDevice in ScanResult">
<!--GridStarts-->
<div >
<img ng-src={{'./assets/img/PlaceHolder/Test.png'}}
<!--Pass Param-->
ng-click="connectDevice(scannedDevice.id)"
altSrc="{{'./assets/img/PlaceHolder/user_place_holder.png'}}"
onerror="this.src = $(this).attr('altSrc')">
</div>
</div>
Java Script:
//Global Variables
var ANGULAR_APP = angular.module('TestApp',[]);
ANGULAR_APP .controller('TestCtrl',['$scope', function($scope) {
//Variables
$scope.ScanResult = [];
//Pass Parameter
$scope.connectDevice = function(deviceID) {
alert("Connecting : "+deviceID );
};
}]);
Here is the ng repeat with ng click function and to append with slider
<script>
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope) {
$scope.employees = [
{ 'id': '001', 'name': 'Alpha', 'joinDate': '05/17/2015', 'age': 37 },
{ 'id': '002', 'name': 'Bravo', 'joinDate': '03/25/2016', 'age': 27 },
{ 'id': '003', 'name': 'Charlie', 'joinDate': '09/11/2015', 'age': 29 },
{ 'id': '004', 'name': 'Delta', 'joinDate': '09/11/2015', 'age': 19 },
{ 'id': '005', 'name': 'Echo', 'joinDate': '03/09/2014', 'age': 32 }
]
//This will hide the DIV by default.
$scope.IsVisible = false;
$scope.ShowHide = function () {
//If DIV is visible it will be hidden and vice versa.
$scope.IsVisible = $scope.IsVisible ? false : true;
}
});
</script>
</head>
<body>
<div class="container" ng-app="MyApp" ng-controller="MyController">
<input type="checkbox" value="checkbox1" ng-click="ShowHide()" /> checkbox1
<div id="mixedSlider">
<div class="MS-content">
<div class="item" ng-repeat="emps in employees" ng-show = "IsVisible">
<div class="subitem">
<p>{{emps.id}}</p>
<p>{{emps.name}}</p>
<p>{{emps.age}}</p>
</div>
</div>
</div>
<div class="MS-controls">
<button class="MS-left"><i class="fa fa-angle-left" aria-hidden="true"></i></button>
<button class="MS-right"><i class="fa fa-angle-right" aria-hidden="true"></i></button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="js/multislider.js"></script>
<script>
$('#mixedSlider').multislider({
duration: 750,
interval: false
});
</script>