issue: dual selectlist moving all items - javascript

below code is about dual selectlist. as shown in below image.
Its working as desire. Only problem is, if I click on last subject from Right hand side list box (select Subject list), it is moving all subject to left list box. Technically it should only move the clicked (selected) one subject.
Any suggestion to resolve this?
Code is as following
(function () {
'use strict';
angular
.module("eSchoolSystem")
.directive('multiSelect',['$compile', '$log', multiSelect])
function multiSelect($compile, $log) {
return {
restrict: 'E',
scope: {
name: '#',
selectedModel: '=',
availableModel: '='
},
/*template: '<select id="{{name}}-available" multiple ng-model="availableModel" ng-click="toSelected()" ng-options="a as a.subjectShortName for a in Model.available"></select>\n\n\
<select id="{{name}}-selected" ng-click="toAvailable()" multiple ng-model="selectedModel" ng-options="s as s.subjectShortName for s in Model.selected"></select>',
*/
templateUrl:'app/class/html/dualMultiSelect.html',
compile: function() {
return {
pre: function($scope, $elem, $attr) {
var RefreshSelect = function(original, toFilter) {
var filtered = [];
angular.forEach(original, function(entity) {
var match = false;
for (var i = 0; i < toFilter.length; i++) {
if (toFilter[i]["subjectId"] === entity["subjectId"]) {
match = true;
break;
}
}
if (!match) {
filtered.push(entity);
}
});
return filtered;
};
var RefreshModel = function() {
/*$scope.selectedModel = $scope.Model.selected;*/
$scope.selectedModel = angular.copy($scope.Model.selected);
/*$scope.availableModel = $scope.Model.available;*/
$scope.availableModel = angular.copy($scope.Model.available);
};
var Init = function() {
$scope.Model = {
available: $scope.availableModel,
selected: $scope.selectedModel
};
$scope.selectedModel = [];
$scope.availableModel = [];
$scope.toSelected = function() {
$scope.Model.selected = $scope.Model.selected.concat($scope.availableModel);
$scope.Model.available = RefreshSelect($scope.Model.available, $scope.availableModel);
RefreshModel();
};
$scope.toAvailable = function() {
console.log("in here -x1")
console.log("x3-> " + JSON.stringify($scope.selectedModel))
$scope.Model.available = $scope.Model.available.concat($scope.selectedModel);
$scope.Model.selected = RefreshSelect($scope.Model.selected, $scope.selectedModel);
RefreshModel();
};
};
Init();
}
};
}
};
}
}());

Try to remove RefreshModel function and updating selected values in toSelected and toAvailable:
$scope.toSelected = function() {
$scope.Model.selected = $scope.Model.selected.concat($scope.availableModel);
$scope.Model.available = RefreshSelect($scope.Model.available, $scope.availableModel);
$scope.selectedModel = $scope.availableModel;
$scope.availableModel = [];
};
$scope.toAvailable = function() {
$scope.Model.available = $scope.Model.available.concat($scope.selectedModel);
$scope.Model.selected = RefreshSelect($scope.Model.selected, $scope.selectedModel);
$scope.selectedModel = [];
$scope.availableModel = $scope.selectedModel;
};

Related

AngularJS : Can't able to access scope inside call back function

Below function is being called from directive link function. My problem is, I cant able to access scope inside then function
function workerInit(scope) {
var data = scope.vm.graphData;
graphViewService.send(new WorkerData(data.node[0].id,2,data.node[0].currentEntity)).then(function(response){
postWorkerResponse(response);
//scope is not defined
})
nodesinQueue.push(data.node[0].id)
}
My factory code
app.factory("graphViewService",['$q',function($q){
var graphViewService = {};
var worker = new Worker('./app/modules/common/graphViewWorker.js');
var defer = $q.defer();
worker.addEventListener('message', function(e) {
defer.resolve(e.data);
}, false);
return {
send : function(data){
defer = $q.defer();
worker.postMessage(data); // Send data to our worker.
return defer.promise;
}
};
}])
My Directive Code(removed unnecessary function def from original)
(function () {
var app = angular.module('sureApp');
app.directive('graphView', function ($rootScope, graphViewService) {
var controller = function () {
var vm = this;
//controller code
};
var linkFunction = function (scope, elem, attrs) {
var el = angular.element(elem);
var graph = graphInit(scope, scope.vm.graphData.node[0]);
nodes = new vis.DataSet(graph.nodeList);
edges = new vis.DataSet(graph.edgeList);
var container = el.find('#network')[0];
var data = {
nodes: nodes,
edges: edges
};
network = new vis.Network(container, data, networkOptions());
networkEvents(network, scope);
new detailWindow(el, scope);
}
function graphInit(scope, node) {
var nodeList = [];
var edgeList = [];
workerInit(scope);
scope.vm.graphChips = [];
scope.vm.graphChips.push(node.currentEntity);
nodeList.push(updateNodeStructure(node, lIcons));
return {
nodeList: nodeList,
edgeList: edgeList
}
}
function workerInit(scope) {
var data = scope.vm.graphData;
WorkerData.url = data.url;
WorkerData.requestHeaders = requestConfig.headers;
graphViewService.send(new WorkerData(data.node[0].id,2,data.node[0].currentEntity)).then(function(response){
postWorkerResponse(response);
//scope is not defined
})
nodesinQueue.push(data.node[0].id)
console.time("test");
}
function WorkerData(id, level, currentEntity){
this.url = WorkerData.url
this.requestHeaders = WorkerData.requestHeaders;
this.id = id;
this.level = level;
this.currentEntity = currentEntity;
}
//removed other function def
return {
restrict: 'E',
scope: {
graphData: '=',
detailedView: '=',
mainEntity: '='
},
link: linkFunction,
controller: controller,
controllerAs: 'vm',
bindToController: true,
templateUrl: './app/modules/common/graphView.html'
};
})
}());
Can anyone help me on this?
Check by adding apply function
function workerInit(scope) {
var data = scope.vm.graphData;
graphViewService.send(new WorkerData(data.node[0].id,2,data.node[0].currentEntity)).then(function(response){
scope.$apply(function () {
postWorkerResponse(response);
//Check here able to access scope
});
});
nodesinQueue.push(data.node[0].id)
}

Sharing object array between controllers while working with modal window in angularJS

I am trying to work with an object array which I am sharing among two controllers one of which is dealing with modal window.
Here is the js code.
angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache', 'ui.bootstrap'])
.service('Faq', function ($http) {
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
this.getFaqs = function ()
{
return this.faqList;
}
this.addfaq = function (obj) {
this.faqList.push(obj);
};
})
.controller('AppCtrl', function ($scope,$modal,Faq) {
$scope.faqData = [];
Faq.getFaqs().then(function (msg) {
$scope.faqData = msg.data;
});
}
$scope.show = function () {
$modal.open({
templateUrl: "faqAddUpdate.html",
controller: "faqctrl"
});
};
})
.controller('faqctrl', function ($scope, $modalInstance, Faq) {
$scope.question = '';
$scope.id = '';
$scope.answer = '';
$scope.editFaq = function (id) {
$scope.divFaq = true;
$scope.faqs = [];
Faq.getData().then(function (msg) {
$scope.faqs = msg.data;
var l = $scope.faqs.length;
for (var i = 0; i < l; i++) {
if ($scope.faqs[i].id == id) {
$scope.question = $scope.faqs[i].question;
$scope.id = $scope.faqs[i].id;
$scope.answer = $scope.faqs[i].answer;
}
}
});
};
$scope.AddUpdateFAQ = function () {
var faq = {
id: $scope.id,
question: $scope.question,
answer: $scope.answer
};
Faq.addfaq(faq);
console.log(faq);
$modalInstance.close();
};
$scope.Cancel = function () {
$modalInstance.dismiss();
};
});
but when I am submitting the data through the modal it says this.faqList.push is not a function.
It is because your faqList variable is not an array.
You overide the first definition:
this.faqList = [];
With this:
this.faqList = $http.get('/Json/faq.json');
But $http.get returns a promise (see doc), not an array.
You should do something like this:
this.faqList = [];
$http.get('/Json/faq.json').then(function(result) {
// process your results here
this.faqList = result.data;
});
Not tried, but this is within the function scope, so create a _this var first might help:
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
var _this = this;
this.getFaqs = function ()
{
return _this.faqList;
}
this.addfaq = function (obj) {
_this.faqList.push(obj);
};

removing a element from ng-repeat only when checkbox is selected and console the removed value

Hi I'm new to angular and in my problem I am able to remove the line when checkbox is selected, but I want to console the removed value
var app = angular.module("appTable", []);
app.controller("Allocation", function($scope) {
$scope.dataList = [{
name: 'lin',
dept: 'b'
}, {
name: 'fie',
dept: 'bbbb'
}, {
name: 'test',
dept: 'aaa'
}];
$scope.add = function() {
var data = {};
data.name = '';
data.dept = '';
$scope.dataList.push(data);
};
$scope.remove = function() {
var newDataList = [];
angular.forEach($scope.dataList, function(v) {
if (!v.isDelete) {
newDataList.push(v);
}
});
$scope.dataList = newDataList;
console.log($scope.dataList)
};
});
I'm having trouble to console the removed value
https://jsfiddle.net/7g9na001/
Any help is appreciated. thanks in advance
You can just log the object content inside the remove handler like this.
JS CODE:
$scope.remove = function() {
var newDataList = [];
angular.forEach($scope.dataList, function(v) {
if (!v.isDelete) {
newDataList.push(v);
} else {
//Value deleted from list
console.log("Value being removed :" + JSON.stringify(v));
}
});
$scope.dataList = newDataList;
console.log($scope.dataList);
};
Live Demo # JSFiddle
$scope.remove = function() {
var newDataList = [];
angular.forEach($scope.dataList, function(v) {
if (!v.isDelete) {
newDataList.push(v);
}else{
console.log(v); //Here you can console the deleted values
}
});
$scope.dataList = newDataList;
};
Use splice() like below:
$scope.remove = function() {
var deletedItems = [];
for(var i=0; i<$scope.dataList.length; i++){
if ($scope.dataList[i].isDelete) {
deletedItems.push($scope.dataList.splice(i--, 1));
}
}
console.log($scope.dataList, deletedItems);
};

AngularJS share function/common code in a controller

I have a subroutine I want to use in my controller. In the case or working with data, a new record blanks fields, as would a screen clear, and after some other processes, I would like to clear the editable fields on the view.
Controller:
angular.module('MyApp').controller('Ctrl', ["$scope", "ServiceData",
function ($scope, ServiceData) {
function ClearMemberStruture()
{
$scope.member.Key = "";
$scope.member.Name = "";
$scope.member.Points = 0;
$scope.EditMode = false;
}
$scope.Members = ServiceData.GetAllMembers();
$scope.member = {};
ClearMemberStruture();
$scope.DeleteMember = function(Member) {
ServiceData.DeleteMember(Member.Key);
$scopeEditMode = false;
};
$scope.EditMember = function(Member) {
var EditMember = ServiceData.GetOneMember(Member.Key);
EditMember.$bindTo($scope, "member").then(
function(unbind) {
$scope.MemberUnbind = unbind;
});
$scopeEditMode = true;
};
$scope.SaveMember = function(Member) {
if( ! $scopeEditMode )
{
$scope.member = ServiceData.AddMember(Member);
ClearMemberStructure();
}
};
$scope.ClearMember = function() {
$scope.member.unbind;
ClearMemberStructure();
$scope.MemberUnbind();
};
}
]);
ClearMemberStructure() is used to reset the common structure fields and the Edit flag which controls showing information on the screen. When I run this code, I always get a
ReferenceError: ClearMemberStructure is not defined
How can I share this common function in my controller in AngularJS?
If I add a Factory, I can achieve this using calls to the factory:
angular.module('MyApp').factory("MemberRecord", function() {
var Member = {
Key: "",
Name: "",
Points: ""
};
return {
Clear: function() {
Member.Key = "";
Member.Name = "";
Member.Points = "";
return Member;
}
};
}
);
And then in the controller:
$scope.member = MemberRecord.Clear();
Is there a way to do the simply function style code sharing, as I do want this to be handled as a private function, but cannot get it to recognize the function in the controller.
var ClearMemberStruture = function()
{
$scope.member.Key = "";
$scope.member.Name = "";
$scope.member.Points = 0;
$scope.EditMode = false;
}
is your solution to declare ClearMemberStruture without breaking your whole code.
I use a separate file with factories to share code between controllers.
App.factory('CommonServices', function ($http) {
return {
createComment: function($api_key, $post_id, $comment) {
var comment_data = {
content: $comment
};
return $http({
url: '/api/v1/posts/' + $post_id + '/comments',
method: "POST",
headers: { 'X-API-TOKEN': $api_key },
params: comment_data,
data: ''
})
}
});
Then in a controller you can access the common functions like:
$scope.saveComment = function($post_id) {
CommonServices.createComment($scope.api_key, $post_id, $scope.comment.text)
.then(function(_data) {
var index = $scope.feed_items.filter(function (post) { return post.id == $post_id });
index[0].comments.unshift(_data.data);
$scope.showComment = false;
});
}
I prefer to use factory for Member and encapsulate method there. But you can try the easier way:
angular.module('MyApp').controller('Ctrl', ["$scope", "ServiceData",
function ($scope, ServiceData) {
var that = this;
that.ClearMemberStruture = function()
{
$scope.member.Key = "";
$scope.member.Name = "";
$scope.member.Points = 0;
$scope.EditMode = false;
}
$scope.Members = ServiceData.GetAllMembers();
$scope.member = {};
that.ClearMemberStruture();
$scope.DeleteMember = function(Member) {
ServiceData.DeleteMember(Member.Key);
$scopeEditMode = false;
};
$scope.EditMember = function(Member) {
var EditMember = ServiceData.GetOneMember(Member.Key);
EditMember.$bindTo($scope, "member").then(
function(unbind) {
$scope.MemberUnbind = unbind;
});
$scopeEditMode = true;
};
$scope.SaveMember = function(Member) {
if( ! $scopeEditMode )
{
$scope.member = ServiceData.AddMember(Member);
ClearMemberStructure();
}
};
$scope.ClearMember = function() {
$scope.member.unbind;
ClearMemberStructure();
$scope.MemberUnbind();
};
}
]);

AngularJs: Can't set option as selected in select programatically

I have a service that calls to pop up.
The pop up is contains two drop-down lists.
The user is asked to choose the two drop down lists and press ok to return to the service.
In the next call to the pop up i would like that the pop up will display the previous options that was selected by the user.
Everytime i returns to the pop up the drop down are full but no selection has happened and i can't figure out what i am missing.
The service that calls to the pop up:
app.service('OriginalService', [ '$modal',
function ($modal) {
var that = this;
this.filtersMananger = { // my-ng-models for the two drop-down-lists
firstFilter: "",
secondFilter: ""
};
this.openDialog = function(){
var modalInstance = $modal.open({
templateUrl: 'ModalScreen.html',
controller: 'ModalController',
resolve: {
filtersManagerObject: function () {
return that.filtersMananger;
}
}
});
modalInstance.result.then(function (filtersMananger) {
that.filtersMananger.firstFilter = filtersMananger.selectedFirstFilter;
that.filtersMananger.secondFilter = filtersMananger.selectedSecondFilter;
}, function () {
});
};
}
]);
The pop up html:
<div class="data-filters-container">
<div class="data-filter">
<label for="filter-data-drop-down">FIRST FILTER</label>
<select name="filterDataDropDown" ng-model="filtersMananger.selectedFirstFilter" ng-options="filter.value as filter.name for filter in filterDropDownItems"></select>
</div>
<div class="data-filter col-xs-4">
<label for="filter-data-drop-down">SECOND FILTER</label>
<select name="filterDataDropDown" ng-model="filtersMananger.selectedSecondFilter" ng-options="filter.value as filter.name for filter in filterDropDownItems"></select>
</div>
</div>
The code :
app.controller('ModalController', ['$scope', '$modalInstance', 'filtersManagerObject',
function ($scope, $modalInstance, filtersManagerObject) {
$scope.filtersMananger = {
selectedFirstFilter : "",
selectedSecondFilter : ""
};
$scope.filterDropDownItems = [
{name: "4h", value: "lastFourHours"},
{name: "24h", value: "lastDay"},
{name: "All", value: "all"}
];
/*
* The function checks if the the values in filters are not "".
* If there are not so we found the selected filter and returns it.
*/
$scope.fillPreviousSelections = function(){
if ($scope.isfiltersManagerObjectNotEmpty()){
$scope.fillSelections();
}
};
$scope.isfiltersManagerObjectNotEmpty = function(){
return (filtersManagerObject.firstFilter !== "" || filtersManagerObject.secondFilter !== "");
};
$scope.fillSelections = function(){
if (filtersManagerObject.firstFilter !== ""){
$scope.findDropDownItem(filtersManagerObject.firstFilter);
}
};
$scope.findDropDownItem = function(filterValue){
var isFound = false;
for (var i = 0; i < $scope.filterDropDownItems.length && !isFound; i++){
var dropDownItem = $scope.filterDropDownItems[i];
if (dropDownItem.value === filterValue){
//////////////////////////////////////////////////////////////
Maybe the problem is here:
$scope.filtersMananger.selectedOneFilter = dropDownItem;
/////////////////////////////////////////////////////////////
isFound = true;
}
}
};
$scope.fillPreviousSelections();
$scope.ok = function () {
$modalInstance.close($scope.filtersMananger);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]);
I found out the problem :)
Look at the select tag:
<select name="filterDataDropDown" ng-model="filtersMananger.selectedFirstFilter" ng-options="filter.value as filter.name for filter in filterDropDownItems"></select>
The ng-model in this case (filtersMananger.selectedFirstFilter) holds the value (filter.value).
So in my function in which i search the proper item from the drop down list named
$scope.findDropDownItem
I need to return the value of the item and not the item itself.
$scope.findDropDownItem = function(filterValue){
var isFound = false;
var dropDownItemToReturn = "";
for (var i = 0; i < $scope.filterDropDownItems.length && !isFound; i++){
var dropDownItem = $scope.filterDropDownItems[i];
if (dropDownItem.value === filterValue){
dropDownItemToReturn = dropDownItem;
isFound = true;
}
}
//my change:
return dropDownItemToReturn.value;
};
After that i assigned the returned value to the model:
var previousDropDownItem = $scope.findDropDownItem(filtersManagerObject.oneFilterFilter);
$scope.filtersMananger.selectedOneFilter = previousDropDownItem ;
And that it!! :)

Categories

Resources