how to append the specific values in array? - javascript

This is my directive.I want to append the array specific array value in existing array
localStorage.getItem('albumcomments') = "[{"id":1,"photocomment":"sdfsdfs"}]";
angular.module('albumlikeFeature',[]).directive('albumlikeFeature', ['$filter', '$route', function ($filter, $route) {
return {
restrict: 'E',
scope: {},
templateUrl: 'app/components/album/albumlikefeature.html',
link : function(scope, element, attrs) {
scope.likeCount = 0;
scope.unlikeCount = 0;
scope.likeClick = function (dataid) {
scope.likeCount += 1;
if(JSON.parse(localStorage.getItem('albumcomments'))){
var newDataLike = [];
angular.forEach(localStorage.getItem('albumcomments'), function(likeCount, item){
console.log('test');
newDataLike.push({id:item.id, photocomment:item.photocomment, like:likeCount});
});
console.log(newDataLike);
localStorage.setItem('albumcomments',JSON.stringify(newDataLike));
}
};
My expected output is
[{"id":1,"photocomment":"test","like":"1","unlike":"1"}
Now output is
[{"like":"["},{"like":"{"},{"like":"\""},{"like":"i"},{"like":"d"},{"like":"\""},{"like":":"},{"like":"1"},{"like":","},{"like":"\""},{"like":"p"},{"like":"h"},{"like":"o"},{"like":"t"},{"like":"o"},{"like":"c"},{"like":"o"},{"like":"m"},{"like":"m"},{"like":"e"},{"like":"n"},{"like":"t"},{"like":"\""},{"like":":"},{"like":"\""},{"like":"s"},{"like":"d"},{"like":"f"},{"like":"s"},{"like":"d"},{"like":"f"},{"like":"s"},{"like":"\""},{"like":"}"},{"like":"]"}]

Try this hope it will help
angular.module('albumlikeFeature',[]).directive('albumlikeFeature', ['$filter', '$route', function ($filter, $route) {
return {
restrict: 'E',
scope: {},
templateUrl: 'app/components/album/albumlikefeature.html',
link : function(scope, element, attrs) {
scope.likeCount = 0;
scope.unlikeCount = 0;
scope.likeClick = function (dataid) {
scope.likeCount += 1;
if(JSON.parse(localStorage.getItem('albumcomments'))){
var newDataLike = [];
angular.forEach(JSON.parse(localStorage.getItem('albumcomments')), function(likeCount, item){
newDataLike.push({id:likeCount.id, photocomment:likeCount.photocomment, like:scope.likeCount,unlike:scope.unlikeCount});
});
localStorage.setItem('albumcomments',JSON.stringify(newDataLike));
}
};
scope.unlikeClick = function (dataid) {
scope.unlikeCount += 1;
if(JSON.parse(localStorage.getItem('albumcomments'))){
var newDataUnlike = [];
angular.forEach(JSON.parse(localStorage.getItem('albumcomments')), function(i, item){
newDataUnlike.push({id:i.id, photocomment:i.photocomment,like:scope.likeCount,unlike:scope.unlikeCount});
});
console.log(newDataUnlike);
localStorage.setItem('albumcomments',JSON.stringify(newDataUnlike));
}
};
}
}
}]);

I guess you should create a new array and then you can push the things while iterating:
var data = [{"id":1,"photocomment":"test"},{"id":1,"photocomment":"test1"}];
var newData = [];
$.each(data, function(i, item){
newData.push({id:item.id, photocomment:item.photocomment, like:i, unlike:i});
});
console.log(newData);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

localStorage.getItem('albumcomments') = JSON.parse('[{"id":1,"photocomment":"sdfsdfs"}]');
angular.module('albumlikeFeature',[]).directive('albumlikeFeature', ['$filter', '$route', function ($filter, $route) {
return {
restrict: 'E',
scope: {},
templateUrl: 'app/components/album/albumlikefeature.html',
link : function(scope, element, attrs) {
scope.likeCount = 0;
scope.unlikeCount = 0;
scope.likeClick = function (dataid) {
scope.likeCount += 1;
if(localStorage.getItem('albumcomments').length > 0){
var newDataLike = [];
$.each(localStorage.getItem('albumcomments'), function(value, key){
$(this) = $this;
console.log('test');
newDataLike.push( {id: $this.id, photocomment: $this.photocomment, like: scope.likeCount} );
});
console.log(newDataLike);
localStorage.setItem('albumcomments',JSON.stringify(newDataLike));
}
};
Try that

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)
}

AngularJS: I can't understand a custom directive

Can someone help me to understand this code? I've found this code in a project and I need a directive that allows only numeric input in text areas, can this help me?
controllerManager.directive('chars', function () {
'use strict';
return {
require: 'ngModel',
restrict: 'A',
link: function ($scope, $elem, attrs, ctrl) {
var regReplace,
preset = {
'specialChars': "^\x20-\x22\x27-\x3F\x41-\x59\x61-\x7B\x7D",
'integer': "0-9"
},
filter = preset[attrs.chars] || attrs.chars;
$elem.on('input', function () {
regReplace = new RegExp('[' + filter + ']', 'ig');
ctrl.$setViewValue($elem.val().replace(regReplace, ''));
ctrl.$render();
var max = $elem.attr('maxLength');
var len = $elem.val().length;
document.getElementById($elem.attr('id')+"Count").innerHTML = max - len;
});
}
};
});
Use below directive. It will only allow integer values to be entered and will discard any other character.
app.directive('integerOnly', ['$compile', function ($compile) {
return {
restrict: 'A',
require: "ngModel",
scope: {
ngModel: '='
},
link: function (scope, element, attrs, ngModelCtrl) {
var oldValue = null;
element.addClass('text-right');
element.bind('focus', function () {
return scope.$apply(function () {
return oldValue = element.val();
});
});
return ngModelCtrl.$parsers.unshift(function (inputValue) {
var val = inputValue ? inputValue.toString().replace(/[^0-9]/g, '') : "";
while (val < "1" && val != val.replace(/[^1-9]/, '')) {
val = val.replace(/[^1-9]/, '');
}
if (val !== inputValue) {
ngModelCtrl.$setViewValue(val);
ngModelCtrl.$render();
}
return val;
});
}
};
}]);
I resolved with this change:
controllerManager.directive('chars', function () {
'use strict';
return {
require: 'ngModel',
restrict: 'A',
link: function ($scope, $elem, attrs, ctrl) {
var regReplace,
preset = {
'specialChars': "^\x20-\x22\x27-\x3F\x41-\x59\x61-\x7B\x7D",
'integer': "^0-9"
},
filter = preset[attrs.chars] || attrs.chars;
$elem.on('input', function () {
regReplace = new RegExp('[' + filter + ']', 'ig');
ctrl.$setViewValue($elem.val().replace(regReplace, ''));
ctrl.$render();
var max = $elem.attr('maxLength');
var len = $elem.val().length;
document.getElementById($elem.attr('id')+"Count").innerHTML = max - len;
});
}
};
});
So now this work:
<input type="text" chars="integer"/>

issue: dual selectlist moving all items

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;
};

How can i bind model in angular directive

I am using angular type ahead from here
http://pineconellc.github.io/angular-foundation/#/typeahead
I have made a directive where template is
<div>
<input type="text"
ng-model="user.selected"
placeholder="Type to select . . ."
typeahead="item as item.name for item in getData($viewValue)"
typeahead-loading="loadingData"
class="form-control">
<i ng-show="loadingData" class="glyphicon glyphicon-refresh"></i>
</div>
and directive is
return {
restrict: 'AE',
replace: true,
scope: true,
templateUrl: 'type.html',
link: function (scope, elem, attrs) {
var url = window.location.origin + attrs.url;
scope.getData = function (val) {
return $http.get(url, {
params: {
q: val
}
}).then(function (response) {
return response.data.map(function (item) {
return item;
});
});
};
}
};
i am using like this
<my-directivw url="api/user"> </my-directive>
Now instead of writing ng-model="user.selected" in template . i want to something like this
ng-model="somevar"
<my-directivw url="api/user" somevar="user.selected"> </my-directive>
How can i do that
It might help you.
The HTML code look like this.
<div ng-app="app" ng-controller="Ctrl as ctrl">
<form name="theform">
<range ng-model="ctrl.theRange" name="myRange" required="true"></range>
</form>
<button ng-click="ctrl.theRange = '10/100'">SET</button>
</div>
The JavaScript code look like this
var app = angular.module("app",[]);
app.controller("Ctrl", function($scope) {
this.theRange = "1/7";
});
app.directive("range", function() {
var ID=0;
function constructRangeString(from, to) {
var result;
if( !from && !to ) {
result = null;
}
else if( from ) {
result = from + "/" + (to || "");
}
else if( to ) {
result = "/" + to;
}
return result;
}
return {
require: "ngModel",
restrict: "E",
replace: true,
scope: {
name: "#"
},
template:
'<div ng-form="{{ subFormName }}">' +
'<input type="text" ng-model="from" class="range-from" />' +
'<input type="text" ng-model="to" class="range-to" />' +
'</div>',
link: function(scope,elem,attrs,ngModel) {
var re = /([0-9]+)\/([0-9]+)/;
if( scope.name ) {
scope.subFormName = scope.name;
}
else {
scope.subFormName = "_range" + ID;
ID++;
}
ngModel.$render = function() {
var result, from, to;
result = re.exec(ngModel.$viewValue);
if( result ) {
from = parseInt(result[1]);
to = parseInt(result[2]);
}
scope.from = from;
scope.to = to;
};
scope.$watch("from", function(newval) {
var result = constructRangeString(newval, scope.to);
ngModel.$setViewValue(result);
});
scope.$watch("to", function(newval) {
var result = constructRangeString(scope.from, newval);
ngModel.$setViewValue(result);
});
}
};
});

Pass scope and parameters to directive - AngularJS

I'm trying to set a class in a ng-repeat with a directive.
I need to pass a parameter to this directive: wineQty
if I use scope: { wineQty: '=' } this works however $scope.bullet1Color is undefined in my html and thus doesn't affect the class that I want.
If I use scope: '#' I get the correct class however I can't specify wineQty
Is there a way to combine theses two syntaxes? so that I can access the scope and pass a paramater?
I've tried { wineQty: '#' } but with no luck sadly.
Here's my directive
angular.module('myApp').directive('wineQtyBullets', function () {
return {
restrict: 'A',
scope: { wineQty: '=', totalBullets: '=', numRedBullets: '=', numOrangeBullets: '#', bullet1Color: '#' },
link: function (scope, element, attrs) {
// defaults
var defaultNumRedBullets = 1;
var defaultNumOrangeBullets = 2;
var defaultTotalBullets = 12;
var defaultWineQty = 0;
// set values from attributes
var numRedBullets = scope.numRedBullets ? scope.numRedBullets : defaultNumRedBullets;
var numOrangeBullets = scope.numOrangeBullets ? scope.numOrangeBullets : defaultNumOrangeBullets;
var totalBullets = scope.totalBullets ? scope.totalBullets : defaultTotalBullets;
var wineQty = scope.wineQty ? scope.wineQty : defaultWineQty;
for (var currentBullet = 1; currentBullet <= totalBullets; currentBullet++) {
var bulletColorClass = 'bg-grey';
if (currentBullet <= wineQty) {
if (currentBullet <= numRedBullets) {
bulletColorClass = 'bg-red';
}
else if (currentBullet <= (numOrangeBullets + numRedBullets)) {
bulletColorClass = 'bg-orange';
}
else {
bulletColorClass = 'bg-green';
}
}
scope["bullet" + currentBullet + "Color"] = bulletColorClass;
}
console.log(scope.bullet1Color);
}
};
}
);
Here's my html
<div class="bullets pull-left ml15 mt6" wine-qty="wine.owned_qty" wine-qty-bullets>
<ul>
<li class="bullet"
ng-class="bullet1Color"></li>
</ul>
</div>
I managed to solve the problem, by changing scope to true and accessing the parameters through attrs
If this can help anyone here's the directive:
angular.module('myApp').directive('wineQtyBullets', function () {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attrs) {
var options = { };
angular.forEach([
'numRedBullets',
'numOrangeBullets',
'totalBullets',
'wineQty'
], function (key) {
if (angular.isDefined(attrs[key]))
options[key] = attrs[key];
});
// defaults
var defaultNumRedBullets = 1;
var defaultNumOrangeBullets = 1;
var defaultTotalBullets = 12;
var defaultWineQty = 0;
// set values from attributes
var numRedBullets = parseInt(options.numRedBullets) ? parseInt(options.numRedBullets) : defaultNumRedBullets;
var numOrangeBullets = parseInt(options.numOrangeBullets) ? parseInt(options.numOrangeBullets) : defaultNumOrangeBullets;
var totalBullets = parseInt(options.totalBullets) ? parseInt(options.totalBullets) : defaultTotalBullets;
var wineQty = parseInt(options.wineQty) ? parseInt(options.wineQty) : defaultWineQty;
for (var currentBullet = 1; currentBullet <= totalBullets; currentBullet++) {
var bulletColorClass = 'bg-grey';
if (currentBullet <= wineQty) {
if (wineQty <= numRedBullets) {
bulletColorClass = 'bg-red';
}
else if (wineQty <= (numOrangeBullets + numRedBullets)) {
bulletColorClass = 'bg-orange';
}
else {
bulletColorClass = 'bg-green';
}
}
scope["bullet" + currentBullet + "Color"] = bulletColorClass;
}
}
};
});
Using "=" means 2-way data binding, and it's definitely fine.
The problem might be that your link function are executed only once at the very beginning, when it's possible that the values of your attributes are not yet assigned (may be caused by some AJAX calls).
I would suggest that you wrap all your link function into a scope.$watch function. Like:
link: function (scope, element, attrs) {
scope.$watch(function() {
return {
wineQty: scope.wineQty,
totalBullets: scope.totalBullets,
numRedBullets: scope.numRedBullets,
numOrangeBullets: scope.numOrangeBullets,
bullet1Color: scope.bullet1Color
}
}, function() {
// Your original code here.
})
}
Then your final result will automatically update if your directive got new attribute values.

Categories

Resources