Directive Parameter Not Initializing on First Load In AngularJs - angularjs

I'va made a Dropdown directive, i'm trying to assign methods on passing parameter to directive and i'll call these method from controller.
but on first load i'm not getting the assign method in controller but when i'm assigning it on second load (i.e on dropdown change event)and it's working fine.
how can i get the methods on first load of directive in the calling controller after first load.
here is the Directive:
"use strict";
myApp.directive("selectDirective", [function () {
return {
restrict: "E",
template: '<select class="form-control input-sm dropdown" data-ng-model="model.args.selectedItem" data-ng-options="item[model.args.displayField] for item in model.args.source" data-ng-change="model.itemChange(model.args.selectedItem)"><option value="">Select Any Item</option></select>',
scope: {
},
bindToController: { args: "=" },
controller: function () {
var self = this;
var initializeControl = function () {
if (self.args == undefined) {
self.args = {};
}
if (self.args.method == undefined) {
self.args.method = {};
}
if (self.args.isDisabled == undefined) {
self.args.isDisabled = false;
}
if (self.args.displayField == undefined) {
self.args.displayField = '';
//alert('Display Field is blank for dropdown control.')
}
if (self.args.valueField == undefined) {
self.args.valueField = '';
//alert('Value Field is blank for dropdown control.')
}
if (self.args.source == undefined) {
self.args.source = {};
}
if (self.args.hide == undefined) {
self.args.hide = false;
}
}
//here i'm assigning the methods in passing parameter
var assignMethod = function () {
self.args.method =
{
setEnable: function (args) {
self.args.isDisabled = !args;
},
setVisible: function (args) {
self.args.hide = !args;
},
getText: function () {
return self.args.selectedText;
},
getValue: function () {
return self.args.selectedValue;
},
setItem: function (item) {
debugger;
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
}
}
}
self.itemChange = function (item) {
debugger;
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
}
initializeControl();
assignMethod();
},
controllerAs: 'model'
}
}]);
Here is the Calling Controller Code:
"use strict";
myApp.controller("homeController", [function () {
var self = this;
var initializeControl = function () {
var myList = [{ id: 1, name: 'List1', value: 'List1' },
{ id: 2, name: 'List2', value: 'List2' }];
self.argsParam = {
displayField: 'name',
valueField: "value",
source: myList,
selectecText: '',
selectecValue: ''
};
self.clickMe = function () {
debugger;
var item = { id: 2, name: 'List2', value: 'List2' };
self.argsParam.method.setItem(item);
}
};
initializeControl();
}]);
View where i used the directive:
<div class="cold-md-12" ng-controller="homeController as model">
<h1>Home Page</h1>
<select-directive args="model.argsParam"></select-directive>
<input type="button" value="Click" ng-click="model.clickMe()" />
</div>
Scenario:
If assigned method called second time inside directive on dropdown-change event then i can get these method on passing param.
i.e
self.itemChange = function (item) {
debugger;
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
// here i'm assigning these method on change event then it's working fine after changing the value otherwise no success
assignMethod();
}
}
So, How i can i get the methods assign in the passing parameter on
First load of the directive?

I've moved the Controller Content to Link function in Directive and
it's working fine, but I still didn't get any idea how my previous code
not worked as expected.
Directive Code:
'use strict';
var testApp = angular.module('TestApp', []);
testApp.directive('sampleDirective', ['$http', function () {
return {
restrict: "E",
scope: {},
bindToController: { args: '=' },
template: '<div class="row">' +
'<select class="form-control"' +
'data-ng-model="model.args.selectedItem"' +
'data-ng-options="item[model.args.displayField] for item in model.args.source"' +
'data-ng-change="model.itemChange(model.args.selectedItem)">' +
'<option value="">Select Any Item</option>' +
'</select>' +
'</div>',
link: function (scope, element, attrs) {
var self = scope.model;
debugger;
var initializeControl = function () {
if (self.args == undefined) {
self.args = {};
}
if (self.args.method == undefined) {
self.args.method = {};
}
if (self.args.isDisabled == undefined) {
self.args.isDisabled = false;
}
if (self.args.displayField == undefined) {
self.args.displayField = '';
alert('Display Field is blank for dropdown control.')
}
if (self.args.valueField == undefined) {
self.args.valueField = '';
alert('Value Field is blank for dropdown control.')
}
if (self.args.source == undefined) {
self.args.source = {};
}
if (self.args.hide == undefined) {
self.args.hide = false;
}
}
var assignMethod = function () {
self.args.method =
{
setEnable: function (args) {
self.args.isDisabled = !args;
},
setVisible: function (args) {
self.args.hide = !args;
},
getText: function () {
return self.args.selectedText;
},
getValue: function () {
return self.args.selectedValue;
},
setItem: function (item) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
};
}
self.itemChange = function (item) {
if (item != undefined) {
var index = self.args.source.indexOf(item);
self.args.selectecText = item[self.args.displayField];
self.args.selectecValue = item[self.args.valueField];
self.args.selectedItem = item;
self.args.selectedIndex = index;
}
}
initializeControl();
assignMethod();
},
controller: function () {
},
controllerAs: 'model'
}
}]);

Related

Directive's scope value is not getting updated when outer scope value changes in angularjs

My html code is as follows.
<div class="panel-heading">
Select areas to be visited by the operator
<multiselect ng-model="selection" options="areanames" show-search="true"></multiselect>
</div>
My application's controller code is as follows. The function getArea is being called when a user inputs some details in the form (not included here).
this.getArea = function(){
$scope.areanames = [];
$http({
method: "GET",
url: "http://xx.xx.xx.xx/abc",
params:{city:$scope.city,circle:$scope.circle}
}).then(function(success){
for (i = 0; i < success.data.length; i++)
$scope.areanames.push(success.data[i].area);
},function(error){
console.log('error ' + JSON.stringify(error));
});
}
The directive multiselect is written as follows.
multiselect.directive('multiselect', ['$filter', '$document', '$log', function ($filter, $document, $log) {
return {
restrict: 'AE',
scope: {
options: '=',
displayProp: '#',
idProp: '#',
searchLimit: '=?',
selectionLimit: '=?',
showSelectAll: '=?',
showUnselectAll: '=?',
showSearch: '=?',
searchFilter: '=?',
disabled: '=?ngDisabled'
},
replace:true,
require: 'ngModel',
templateUrl: 'multiselect.html',
link: function ($scope, $element, $attrs, $ngModelCtrl) {
$scope.selectionLimit = $scope.selectionLimit || 0;
$scope.searchLimit = $scope.searchLimit || 25;
$scope.searchFilter = '';
if (typeof $scope.options !== 'function') {
$scope.resolvedOptions = $scope.options;
}
if (typeof $attrs.disabled != 'undefined') {
$scope.disabled = true;
}
$scope.toggleDropdown = function () {
console.log('toggleDown');
$scope.open = !$scope.open;
};
var closeHandler = function (event) {
console.log('closeHandler');
if (!$element[0].contains(event.target)) {
$scope.$apply(function () {
$scope.open = false;
});
}
};
$document.on('click', closeHandler);
var updateSelectionLists = function () {
console.log('updateSelectionList');
if (!$ngModelCtrl.$viewValue) {
if ($scope.selectedOptions) {
$scope.selectedOptions = [];
}
$scope.unselectedOptions = $scope.resolvedOptions.slice(); // Take a copy
} else {
$scope.selectedOptions = $scope.resolvedOptions.filter(function (el) {
var id = $scope.getId(el);
for (var i = 0; i < $ngModelCtrl.$viewValue.length; i++) {
var selectedId = $scope.getId($ngModelCtrl.$viewValue[i]);
if (id === selectedId) {
return true;
}
}
return false;
});
$scope.unselectedOptions = $scope.resolvedOptions.filter(function (el) {
return $scope.selectedOptions.indexOf(el) < 0;
});
}
};
$ngModelCtrl.$render = function () {
console.log('render called');
updateSelectionLists();
};
$ngModelCtrl.$viewChangeListeners.push(function () {
console.log('viewChangeListener');
updateSelectionLists();
});
$ngModelCtrl.$isEmpty = function (value) {
console.log('isEmpty');
if (value) {
return (value.length === 0);
} else {
return true;
}
};
var watcher = $scope.$watch('selectedOptions', function () {
$ngModelCtrl.$setViewValue(angular.copy($scope.selectedOptions));
}, true);
$scope.$on('$destroy', function () {
console.log('destroy');
$document.off('click', closeHandler);
if (watcher) {
watcher(); // Clean watcher
}
});
$scope.getButtonText = function () {
console.log('getButtonText');
if ($scope.selectedOptions && $scope.selectedOptions.length === 1) {
return $scope.getDisplay($scope.selectedOptions[0]);
}
if ($scope.selectedOptions && $scope.selectedOptions.length > 1) {
var totalSelected;
totalSelected = angular.isDefined($scope.selectedOptions) ? $scope.selectedOptions.length : 0;
if (totalSelected === 0) {
return 'Select';
} else {
return totalSelected + ' ' + 'selected';
}
} else {
return 'Select';
}
};
$scope.selectAll = function () {
console.log('selectAll');
$scope.selectedOptions = $scope.resolvedOptions;
$scope.unselectedOptions = [];
};
$scope.unselectAll = function () {
console.log('unSelectAll');
$scope.selectedOptions = [];
$scope.unselectedOptions = $scope.resolvedOptions;
};
$scope.toggleItem = function (item) {
console.log('toggleItem');
if (typeof $scope.selectedOptions === 'undefined') {
$scope.selectedOptions = [];
}
var selectedIndex = $scope.selectedOptions.indexOf(item);
var currentlySelected = (selectedIndex !== -1);
if (currentlySelected) {
$scope.unselectedOptions.push($scope.selectedOptions[selectedIndex]);
$scope.selectedOptions.splice(selectedIndex, 1);
} else if (!currentlySelected && ($scope.selectionLimit === 0 || $scope.selectedOptions.length < $scope.selectionLimit)) {
var unselectedIndex = $scope.unselectedOptions.indexOf(item);
$scope.unselectedOptions.splice(unselectedIndex, 1);
$scope.selectedOptions.push(item);
}
};
$scope.getId = function (item) {
console.log('getID');
if (angular.isString(item)) {
return item;
} else if (angular.isObject(item)) {
if ($scope.idProp) {
return multiselect.getRecursiveProperty(item, $scope.idProp);
} else {
$log.error('Multiselect: when using objects as model, a idProp value is mandatory.');
return '';
}
} else {
return item;
}
};
$scope.getDisplay = function (item) {
console.log('getDisplay');
if (angular.isString(item)) {
return item;
} else if (angular.isObject(item)) {
if ($scope.displayProp) {
return multiselect.getRecursiveProperty(item, $scope.displayProp);
} else {
$log.error('Multiselect: when using objects as model, a displayProp value is mandatory.');
return '';
}
} else {
return item;
}
};
$scope.isSelected = function (item) {
console.log('isSelected');
if (!$scope.selectedOptions) {
return false;
}
var itemId = $scope.getId(item);
for (var i = 0; i < $scope.selectedOptions.length; i++) {
var selectedElement = $scope.selectedOptions[i];
if ($scope.getId(selectedElement) === itemId) {
return true;
}
}
return false;
};
$scope.updateOptions = function () {
console.log('updateOptions');
if (typeof $scope.options === 'function') {
$scope.options().then(function (resolvedOptions) {
$scope.resolvedOptions = resolvedOptions;
updateSelectionLists();
});
}
};
// This search function is optimized to take into account the search limit.
// Using angular limitTo filter is not efficient for big lists, because it still runs the search for
// all elements, even if the limit is reached
$scope.search = function () {
console.log('search');
var counter = 0;
return function (item) {
if (counter > $scope.searchLimit) {
return false;
}
var displayName = $scope.getDisplay(item);
if (displayName) {
var result = displayName.toLowerCase().indexOf($scope.searchFilter.toLowerCase()) > -1;
if (result) {
counter++;
}
return result;
}
}
};
}
};
}]);
When areanames is getting updated asynchronously its values are not getting displayed in multiselect. The inner scope's options value is becoming undefined though I am using '=' with same attribute name i.e., options in the html code.

Template using in Angularjs

i'm using ng-duallist template. I got it here : https://github.com/tushariscoolster/ng-duallist
I want to use twice in the same html controller. I have created new variable for it but content is always same so how can I separate it?
I want to add vm2 to other data content but always same value added two duallist
hmtl code
directives code
var existingEntries = [];
var vm = this;
vm.property = 'controller';
activate();
function activate() {
vm.leftValue = [];
vm.rightValue = [];
vm.addValue = [];
vm.removeValue = [];
function loadMoreLeft() {
for (var i = 0; i < $scope.reasonOfLack.length; i++) {
vm.leftValue.push({
'name': $scope.reasonOfLack[i]
});
}
};
function loadMoreRight() {
}
vm.options = {
leftContainerScrollEnd: function () {
},
rightContainerScrollEnd: function () {
},
leftContainerSearch: function (text) {
console.log(text)
vm.leftValue = $filter('filter')(leftValue, {
'name': text
})
},
rightContainerSearch: function (text) {
vm.rightValue = $filter('filter')(rightValue, {
'name': text
})
},
leftContainerLabel: 'Uygunsuzluk Sebepleri',
rightContainerLabel: 'Seçilen Uyunsuzluk Sebepleri',
onMoveRight: function () {
console.log('right');
console.log(vm.addValue);
},
onMoveLeft: function () {
console.log('left');
console.log(vm.removeValue);
}
};
loadMoreLeft();
var leftValue = angular.copy(vm.leftValue)
var rightValue = angular.copy(vm.rightValue)
}

Angular service slugify scopes

I am slugify function running smoothly.
What bothers me is having to repeat the function code in all controllers.
There is the possibility of converting into a service, or otherwise I write only once this function?
Today use of this form:
<md-input-container class="md-accent">
<label >Digite o título do Produto</label>
<input ng-model="product.title" ng-change="slugify(product.title)">
</md-input-container>
<md-input-container class="md-accent">
<label>Link permanente</label>
<input ng-model="product.slug" disabled>
</md-input-container>
my slugify function:
$scope.slugify = function(slug){
var makeString = function(object) {
if (object === null) {
return '';
}
return '' + object;
};
var from = 'ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž',
to = 'aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz',
regex = new RegExp('[' + from + ']', 'g');
slug = makeString(slug).toString().toLowerCase().replace(regex, function (c){
var index = from.indexOf(c);
return to.charAt(index) || '-';
}).replace(/[^\w\-\s]+/g, '').trim().replace(/\s+/g, '-').replace(/\-\-+/g, '-');
$scope.product.slug = slug;
};
SOLUTION HERE! FACTORY:
.factory('slugify', function() {
var self = this;
self.generate = function(slug){
var makeString = function(object) {
if (object === null) {
return '';
}
return '' + object;
};
var from = 'ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž',
to = 'aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz',
regex = new RegExp('[' + from + ']', 'g');
slug = makeString(slug).toString().toLowerCase().replace(regex, function (c){
var index = from.indexOf(c);
return to.charAt(index) || '-';
}).replace(/[^\w\-\s]+/g, '').trim().replace(/\s+/g, '-').replace(/\-\-+/g, '-');
return slug;
};
return self;
});
And in controllers:
$scope.slugIt = function(title){
$scope.product.slug = slugify.generate(title);
};
And in views:
<input ng-model="product.title" ng-change="slugIt(product.title)">
You could create a directive, that uses the service to generate a slug.
.factory('slugger', function slugger() {
return {
generateSlug: generateSlug
};
function generateSlug(input) {
var from = 'ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž';
var to = 'aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz';
var regex = new RegExp('[' + from + ']', 'g');
input = makeString(input).toString().toLowerCase().replace(regex, function (c) {
var index = from.indexOf(c);
return to.charAt(index) || '-';
}).replace(/[^\w\-\s]+/g, '').trim().replace(/\s+/g, '-').replace(/\-\-+/g, '-');
return input;
}
function makeString(object) {
if (object === null) {
return '';
}
return '' + object;
}
})
.directive('slugInput', function (slugger) {
return {
require: 'ngModel',
link: function (scope, iElement, iAttrs, ngModelCtrl) {
iElement.on('input', function () {
ngModelCtrl.$setViewValue(slugger.generateSlug(iElement.val()));
ngModelCtrl.$render();
});
scope.$on('$destroy', function () {
iElement.off('input');
});
}
}
});
Usage:
Anywhere in your app,
<input ng-model="product.title" slug-input>
I don't know your exact requirement. But, you can write a service something like this
angular.module('app').service('slugService',
function () {
function serviceInstance() {
var services = {
slugify: slugify,
slug: slug
};
var slug = null;
function slugify(slug) {
var makeString = function (object) {
if (object === null) {
return '';
}
return '' + object;
};
var from = 'ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșšŝťțŭùúüűûñÿýçżźž',
to = 'aaaaaaaaaccceeeeeghiiiijllnnoooooooossssttuuuuuunyyczzz',
regex = new RegExp('[' + from + ']', 'g');
this.slug = makeString(slug).toString().toLowerCase().replace(regex, function (c) {
var index = from.indexOf(c);
return to.charAt(index) || '-';
})
.replace(/[^\w\-\s]+/g, '')
.trim().replace(/\s+/g, '-')
.replace(/\-\-+/g, '-');
}
return services;
}
return new serviceInstance();
}
);
//inject the service in your controller
angular.module('app').controller('urController', function(slugService){
}
and use it in your view
ng-change(slugService.slugify(product.title))
ng-model(slugService.slug) //probably need to use ng-init as well
//assuming the service is used once per page

How to get selected value from ng-autocomplete directive to controller

I am using a directive for auto complete / auto suggest in angular Js taken from http://demo.jankuri.com/ngAutocomplete/. It is working fine getting the data from server and filtering it. But I am facing problem into select and use that select item from the auto complete.
Here is the code of directive what I am using for this...
app.factory('ngAutocompleteService', ['$http', function($http)
{
var self = this;
self.getData = function (url, keyword) {
return $http.get(url, { query: keyword });
};
return self;
}])
app.directive('ngAutocomplete', ['$timeout','$filter','ngAutocompleteService',
function($timeout, $filter, ngAutocompleteService)
{
'use strict';
var keys = {
left : 37,
up : 38,
right : 39,
down : 40,
enter : 13,
esc : 27
};
var setScopeValues = function (scope, attrs) {
scope.url = base_url+attrs.url || null;
scope.searchProperty = attrs.searchProperty || 'skills';
scope.maxResults = attrs.maxResults || 10;
scope.delay = parseInt(attrs.delay, 10) || 300;
scope.minLenth = parseInt(attrs.minLenth, 10) || 2;
scope.allowOnlyResults = scope.$eval(attrs.allowOnlyResults) || false;
scope.placeholder = attrs.placeholder || 'Search...';
};
var delay = (function() {
var timer = 0;
return function (callback, ms) {
$timeout.cancel(timer);
timer = $timeout(callback, ms);
};
})();
return {
restrict: 'E',
require: '?ngModel',
scope: true,
link: function(scope, element, attrs, ngModel) {
setScopeValues(scope, attrs);
scope.results = [];
scope.currentIndex = null;
scope.getResults = function () {
if (parseInt(scope.keyword.length, 10) === 0) scope.results = [];
if (scope.keyword.length < scope.minLenth) return;
delay(function() {
ngAutocompleteService.getData(scope.url, scope.keyword).then(function(resp) {
scope.results = [];
var filtered = $filter('filter')(resp.data, {skills: scope.keyword});
for (var i = 0; i < scope.maxResults; i++) {
scope.results.push(filtered[i]);
}
scope.currentIndex = 0;
if (scope.results.length) {
scope.showResults = true;
}
});
}, scope.delay);
};
scope.selectResult = function (r) {
scope.keyword = r.skills;
ngModel.$setViewValue(r.skills);
scope.ngModel = r.skills;
ngModel.$render();
scope.showResults = false;
};
scope.clearResults = function () {
scope.results = [];
scope.currentIndex = null;
};
scope.hoverResult = function (i) {
scope.currentIndex = i;
}
scope.blurHandler = function () {
$timeout(function() {
if (scope.allowOnlyResults) {
var find = $filter('filter')(scope.results, {skills: scope.keyword}, true);
if (!find.length) {
scope.keyword = '';
ngModel.$setViewValue('');
}
}
scope.showResults = false;
}, 100);
};
scope.keyupHandler = function (e) {
var key = e.which || e.keyCode;
if (key === keys.enter) {
scope.selectResult(scope.results[scope.currentIndex]);
}
if (key === keys.left || key === keys.up) {
if (scope.currentIndex > 0) {
scope.currentIndex -= 1;
}
}
if (key === keys.right || key === keys.down) {
if (scope.currentIndex < scope.maxResults - 1) {
scope.currentIndex += 1;
}
}
if (key === keys.esc) {
scope.keyword = '';
ngModel.$setViewValue('');
scope.clearResults();
}
};
},
template:
'<input type="text" class="form-control" ng-model="keyword" placeholder="{{placeholder}}" ng-change="getResults()" ng-keyup="keyupHandler($event)" ng-blur="blurHandler()" ng-focus="currentIndex = 0" autocorrect="off" autocomplete="off">' +
'<input type="hidden" ng-model="skillIdToBeRated">'+
'<div ng-show="showResults">' +
' <div ng-repeat="r in results | filter : {skills: keyword}" ng-click="selectResult(r)" ng-mouseover="hoverResult($index)" ng-class="{\'hover\': $index === currentIndex}">' +
' <span class="form-control">{{ r.skills }}</span>' +
' </div>' +
'</div>'
};
}]);
I am unable to get value which is selected by ng-click="selectResult(r)" function. The value is showing into text field but not getting it into controller.
I was also using the same directive for showing the auto complete text box. I have tried the following for getting the selected value from auto complete.
in HTML
<div ng-controller="Cntrl as cntrl">
<ng-autocomplete ng-model="cntrl.selectedValue" url="url" search-property="keyword" max-results="10" delay="300" min-length="2" allow-only-results="true"></ng-autocomplete>
</div>
in JavaScript
app.controller('Cntrl', function($scope, $http) {
var self = this;
self.selectedValue = '';
$scope.getSelectedValue = function(){
console.log(self.selectedValue);
}
});
I hope this may help you.
I ran into the same issue. I ended up just watching the property from the details attribute in the ng-autocomplete input and it works pretty well.
$scope.$watch(function() {
return vm.location_result;
}, function(location) {
if (location) {
vm.location_list.push(location);
vm.location = '';
}
});
Fiddle Example: http://jsfiddle.net/n3ztwucL/
GitHub Gist: https://gist.github.com/robrothedev/46e1b2a2470b1f8687ad

Angularjs drag and drop table columns

Hi i use "asutosh" code:
myApp.directive('droppable', ['$parse',
function($parse) {
return {
link: function(scope, element, attr) {
function onDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
if (e.stopPropagation) {
e.stopPropagation();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function onDrop(e) {
if (e.preventDefault) {
e.preventDefault();
}
if (e.stopPropagation) {
e.stopPropagation();
}
var data = e.dataTransfer.getData("Text");
data = angular.fromJson(data);
var dropfn = attr.drop;
var fn = $parse(attr.drop);
scope.$apply(function() {
scope[dropfn](data, e.target);
});
}
element.bind("dragover", onDragOver);
element.bind("drop", onDrop);
}
};
}
]);
myApp.directive('draggable', function() {
return {
link: function(scope, elem, attr) {
elem.attr("draggable", true);
var dragDataVal='';
var draggedGhostImgElemId='';
attr.$observe('dragdata',function(newVal){
dragDataVal=newVal;
});
attr.$observe('dragimage',function(newVal){
draggedGhostImgElemId=newVal;
});
elem.bind("dragstart", function(e) {
var sendData = angular.toJson(dragDataVal);
e.dataTransfer.setData("Text", sendData);
if (attr.dragimage !== 'undefined') {
e.dataTransfer.setDragImage(
document.getElementById(draggedGhostImgElemId), 0, 0
);
}
var dragFn = attr.drag;
if (dragFn !== 'undefined') {
scope.$apply(function() {
scope[dragFn](sendData);
})
}
});
}
};
});
example here http://plnkr.co/edit/KvJglc?p=preview , to drag and drop table columns, but this code have a little issue, when you drop a column over border or blank area in the headers, the column dissapear. Someone could assist me please?
myApp.directive('angTable', ['$compile',function($compile) {
return {
restrict: 'E',
templateUrl: 'tabletemplate.html',
replace: true,
scope: {
conf: "="
},
controller: function($scope) {
$scope.dragHead = '';
$scope.dragImageId = "dragtable";
$scope.handleDrop = function(draggedData,
targetElem) {
var swapArrayElements = function(array_object, index_a, index_b) {
var temp = array_object[index_a];
array_object[index_a] = array_object[index_b];
array_object[index_b] = temp;
};
var srcInd = $scope.conf.heads.indexOf(draggedData);
var destInd = $scope.conf.heads.indexOf(targetElem.textContent);
swapArrayElements($scope.conf.heads, srcInd, destInd);
};
$scope.handleDrag = function(columnName) {
$scope.dragHead = columnName.replace(/["']/g, "");
};
},
compile: function(elem) {
return function(ielem, $scope) {
$compile(ielem)($scope);
};
}
};
}
]);
Add this 2 lines if(destInd == -1)
destInd = targetElem.cellIndex; after var destInd = $scope.conf.heads.indexOf(targetElem.textContent); and it should work

Resources