How activate ng-class only on one element? - javascript

I have ng-repeat and ng-class for each element. I use it for selecting elements (add border for selected).
<div class="main-block_channel_create">
<section class="parent_messageList cancelDelete">
<div id="section_animate" class="messagesList_block cancelDelete" infinite-scroll='messagelist.nextSet()' infinite-scroll-listen-for-event='anEvent' infinite-scroll-distance='100'>
<!-- User Images List -->
<a href="" class="messageBl message_preview animated" ng-repeat='preview in messagelist.previewList'>
<div class="image_container_preview" ng-class="{community_select: item.isSelected}" ng-click='communitySelect(preview)' attr="{{preview.preview_id}}">
<img class="deleteMessageBtn" src="images/close_icon.svg" ng-click="deleteMessage(preview.message_id)">
<div class="spinner_container">
<!--<img src="/images/logo-80.svg" class='spinner_img'>-->
<img class="spinner_logo_vertical" src="images/logo_vertical-part.svg" alt="">
<img class="spinner_logo_left" src="images/logo_left-part.svg" alt="">
<img class="spinner_logo_right" src="images/logo_right-part.svg" alt="">
</div>
<img class="message_preview-image" src="{{preview.image}}" alt="">
<!-- Tсли нет изображения — показываем текст -->
<div class="message_preview-text MediumNormalJunior" ng-if="!preview.image">
<div class="message_preview-text-inner" ng-if='preview.name'>
{{preview.name}}
</div>
<!-- если нету и текста показываем empty-->
</div>
<div class="empty_message" ng-if='!preview.text && !preview.image'>
<!--<h4>Empty</h4> -->
</div>
</div>
<div class="stats" ng-show='preview.total_score > 0'>
<p>{{preview.total_score}}</p>
</div>
</a>
<footer class="listFooter">
</footer>
</div>
</section>
sass
.community_select
border: 3px solid white
directive
(function(){
'use strict';
angular
.module('buzz')
.directive('channelcreate', channelcreate);
function channelcreate($rootScope, $location, $timeout, $cookies, $window, communityApiService, getCommunities){
return{
restrict: "E",
replace: true,
scope: true,
templateUrl: '/templates/channelCreate/channelCreate.html',
link: function($scope){
// $rootScope.showChannelCreate = null;
// Select communities for create new channel
$scope.communityList = [];
$scope.communitySelect = function(communityId){
$scope.selected = false;
if ($scope.communityList.indexOf(communityId) == -1){
$scope.communityList.push(communityId);
} else {
$scope.communityList.pop(communityId)
}
console.log($scope.communityList);
};
// all messages preview are loaded from messagesLoadFactory
$scope.messagelist = new getCommunities();
}
};
};
})();
I can identify each div by id when it is clicked. How can I change only one element, but not all of them?

Following your login... an option can be to check if the element's id is in the list of selected elements with communityList.indexOf(preview.id) != -1 so your ng-class would look like:
ng-class="{community_select: communityList.indexOf(preview.id) != -1}"
Edit
Also, when deleting an id from the $scope.communityList make sure you first find its index and then remove it with splice.
Now the portion for removing/adding the id would look like this:
// ... content omitted
$scope.communitySelect = function(communityId) {
$scope.selected = false;
var index = $scope.communityList.indexOf(communityId);
if (index == -1) {
$scope.communityList.push(communityId);
} else {
$scope.communityList.splice(index, 1)
// ^^^ ^
// remove starting_here one_element
}
console.log($scope.communityList);
};
// ... content omitted

I guess you want to keep selection on screen to highlighted, for the same I don't think so you need to maintain extra collection list. Rather you can add flag isSelected on that record and toggle it based on user click.
HTML
I have and ng-repeat and ng-class for each element. I use it for selecting elements (add border for selected).
<a href="" class="messageBl message_preview animated"
ng-repeat='preview in messagelist.previewList'>
<div class="image_container_preview"
ng-class="{community_select: item.isSelected}"
ng-click='communitySelect(preview)'
attr="{{preview.preview_id}}">
</a>
Code
$scope.communitySelect = function(communityId) {
item.isSelected = !item.isSelected;
};
And whenever you need list of selected previews, you can easily loop over the previews collection and grab those ones who have isSelected flag ticked.
var selected = $scope.previews.map(i => i.isSelected);

Related

how to move in an array of images (blobs) in Angular?

I have an image gallery displayed on my page. I need to implement a modal for whenever the user clicks on the images. In the modal I need to show the full size of the selected image. Here is the problem: I have already made the modal work, but when I click on any of the gallery images, the modal shows all of them together in a single modal. I need the modal to only show the one that the user clicked on.
Please note that my webpage is based on AngularJS and PHP. I used ngModal for this modal and that I'm new to using Angular (basically I know nothing, I'm learning), so please be patient with me. Here is my code:
app.js
readApp.controller('newsGallery', function($scope) {
$scope.myData = {
modalShown: false,
}
$scope.logClose = function() {
console.log('close!');
};
$scope.toggleModal = function() {
$scope.myData.modalShown = !$scope.myData.modalShown;
};
});
HTML
<div ng-controller='newsGallery'>
<modal-dialog show='myData.modalShown' width='75%' height='80%' on-close='logClose()'>
<div ng-repeat = "i in idsBlobs" >
<img src="php/visualizar_archivo.php?id={{i.id}}">
</div>
</modal-dialog>
<div class="row" style="display:flex; flex-wrap: wrap;">
<div class = "col-md-4" ng-repeat = "i in idsBlobs" >
<div class="news-image" align="center">
<img src="php/visualizar_archivo.php?id={{i.id}}" class = "img-responsive img-rounded" ng-click='toggleModal();'>
</div>
</div>
</div>
</div>
One way to have the image that the user clicked on shown in the modal is to introduce a scope variable e.g. $scope.selectedImage. Next, in the function toggleModal(), accept an argument for the image and set that scope variable to that argument.
$scope.toggleModal = function(image) {
$scope.myData.modalShown = !$scope.myData.modalShown;
$scope.selectedImage = image;
};
Next update the call to that function in the ng-click handler:
<img src="php/visualizar_archivo.php?id={{i.id}}" ng-click='toggleModal(i);' class = "img-responsive img-rounded">
Then in the modal markup, show that selected image.
<modal-dialog show='myData.modalShown' width='75%' height='80%' on-close='logClose()'>
<img src="php/visualizar_archivo.php?id={{selectedImage.id}}">
</modal-dialog>
That way the modal will only show the image that the user clicked on, instead of all images in the list.
See a demonstration of this below.
readApp = angular.module('readApp', ["ngModal"]);
readApp.controller('newsGallery', function($scope) {
$scope.idsBlobs = [{
"id": 'MA',
"src": "http://www.animatedimages.org/data/media/96/animated-lighthouse-image-0032.gif"
},
{
"id": "MU",
"src": "http://icons.iconarchive.com/icons/aha-soft/large-home/128/Museum-icon.png"
}
];
$scope.myData = {
modalShown: false
}
$scope.logClose = function() {
console.log('close!');
};
$scope.toggleModal = function(image) {
$scope.myData.modalShown = !$scope.myData.modalShown;
$scope.selectedImage = image;
};
});
.img-thumb {
height: 48px;
width: 48px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//elliott.andrewz.org/cdn/ng-modal.min.js"></script>
<link href="//elliott.andrewz.org/cdn/ng-modal.css" rel="stylesheet" />
<div ng-app="readApp" ng-controller="newsGallery">
<modal-dialog show="myData.modalShown" width="75%" height="80%" on-close="logClose()">
<img src="{{ selectedImage.src }}" />
</modal-dialog>
<div class="row" style="display:flex; flex-wrap: wrap;">
<div class="col-md-4" ng-repeat="i in idsBlobs">
<div class="news-image" align="center">
<img src="{{ i.src }}" class="img-responsive img-rounded img-thumb" ng-click="toggleModal(i);" />
</div>
</div>
</div>
</div>

ng-repeat toggle slide, but others should be close

I am using below code for slide toggle, it
<div ng-repeat="item in $ctrl.searchitems track by $index">
<div class="quickinfo-overlap"> Content here...
<a class="btn-link" ng-click="$ctrl.quickinfoToggle(item)">quick info</a>
</div>
</div>
And I am using ng-repeat, so it is showing list, I want others list should be close or quickinfo false. so can I do?
This is the controller code:
function listingController($scope) {
var vm = this;
vm.quickinfo = false;
vm.quickinfoToggle = function(event) {
event.quickinfo = !event.quickinfo;
};
};
HTML:
<div ng-repeat="item in $ctrl.searchitems track by $index">
<div class="quickinfo-overlap"> Content here...
<a class="btn-link" ng-click="$ctrl.quickinfoToggle(item,$index)">quick info</a>
</div>
<div>
DIV that needs to be toggled on click
</div>
</div>
Javascript:
function listingController($scope) {
var vm = this;
$scope.toggleList = [];
for(var i=0;i< $scope.searchitems.length;i++)
$scope.toggleList[i] = false;
vm.quickinfoToggle = function(event,index) {
for(var i=0;i< $scope.toggleList.length;i++)
$scope.toggleList[i] = false;
$scope.toggleList[index] = true
event.quickinfo = !event.quickinfo;
};
};
while looping with ng-repeat to show the items, set ng-show:
<div class="quickinfo slide-toggle" ng-show="quickinfo == 1" ng-cloak>
Content here ....
</div>
<a class="btn-link" ng-click="quickinfo = 1">quick info</a>
Of course 1 is not fixed number, it should be unique to each item, like the index or id of the item.
The idea is when clicking the quickinfo link you assigned the clicked item's id not assign true\false to the quickinfo, and in ng-show check if the current id assigned to quickinfo is the same as this item id (or index).
Of course variable names can be changed.

Access and bind data outside of ng-repeat

I have an ng-repeat which repeats a bunch of products in a dropdown.
On hover over these guys, I want to bounce the image that I'm hovering into a container outside of the dropdown.
MARKUP:
<div class="quick-view-filters-container" ng-controller="setZoomDrop">
<!-- zoomed image container from ng-repeat below -->
<div class="product--shade__image-zoom--container">
<img class="ng-hide" ng-show="zoom=1" image="option.product" step="1" always="1" />
</div>
<!-- dropdown -->
<div class="product-select-shades-container" ng-repeat="attribute in attributes | onlyAttrsWithManyOptions | orderBy:$parent.$parent.$parent.configurableOrder">
<h4>Products:</h4>
<div class="product--options_list">
<div ng-repeat="option in attribute.options" class="product--option_item" ng-if="option.product">
<span class="product--shade__image ">
<!-- image -->
<img class="{{:: attribute.code == 'lamp_colour_config' ? 'zoomed' : ''}}" image="option.product" step="1" ng-mouseenter="setZoom(1)" ng-mouseleave="setZoom(0)" always="1" />
</span>
</div>
</div>
</div>
</div>
Controller:
window.app.controller('setZoomDrop', ['$scope', function($scope) {
var zoom = null;
$scope.setZoom = function(number) {
$scope.zoom = number;
};
}]);
Workings:
You can see in the markup that I am setting a variable to 1 or 0 dependable on whether a product in the dropdown is hovered over.
This I have tried to use in the zoomed image container.
option.product in the zoomed image container will not work as I don't know how to pull out the active image from the ng-repeat.
in your setZoom function, instead of passing a number pass the option object if mouseenter or null if mouseleave:
$scope.curOpt = null;
$scope.setZoom = function(option) {
$scope.curOpt = option;
}
Then in your html:
<img ng-show="curOpt" image="curOpt.product" step="1" always="1" />

Adding objects to the DOM after adding new data to the list

I have an array of objects which i populate on a button click.
When populating this array i make sure that i only add 10 objects to it.
When this is all loaded in the dom i give the user the oppertunity to add a few more objects.
I do this like this:
$scope.Information = [];
$.each(data, function (i, v) {
if (i<= 9)
$scope.Information.push(data[i]);
if(i >= 10) {
cookieList.push(data[i]);
}
}
if (cookieList.length) {
localStorage.setItem("toDoList", JSON.stringify(cookieList));
$(".showMore").removeClass("hidden");
}
$(".showMore").on("click", function() {
var obj = JSON.parse(localStorage.getItem("toDoList"));
console.log(obj);
console.log(obj.length);
SetSpinner('show');
$scope.Information.push(obj);
SetSpinner('hide');
//$.removeCookie("toDoList2");
});
part of the HTML:
<div ng-repeat="info in Information" class="apartment container" style="padding-right:35px !important">
<div class="row" style="height:100%">
<div class="col-md-1 col-xs-12">
<div>
<h4 class="toDoListHeadings">Nummer</h4>
<div style="margin-top: -15px; width:100%">
<span class="toDoListItems number">
{{info.orderraderid}}
</span>
</div>
</div>
</div>
</div>
</div>
My issue: When i add objects to my array of objects "$scope.Information.push(obj);" I assumed that they would get added in the DOM but they do not, how do i do this the angular way?
EDIT MY SOLOUTION:
edited the HTML to use ng-click and the method is as follows:
$scope.addMore = function() {
var obj = JSON.parse(localStorage.getItem("toDoList"));
SetSpinner('show');
$.each(obj, function(i,v) {
$scope.Information.push(v);
});
SetSpinner('hide');
}
Here is the angular way:
 The view
<!-- Reference your `myapp` module -->
<body data-ng-app="myapp">
<!-- Reference `InfoController` to control this DOM element and its children -->
<section data-ng-controller="InfoController">
<!-- Use `ng-click` directive to call the `$scope.showMore` method binded from the controller -->
<!-- Use `ng-show` directive to show the button if `$scope.showMoreButton` is true, else hide it -->
<button data-ng-click="showMore()" data-ng-show="showMoreButton">
Show more
</button>
<div ng-repeat="info in Information" class="apartment container" style="padding-right:35px !important">
<div class="row" style="height:100%">
<div class="col-md-1 col-xs-12">
<div>
<h4 class="toDoListHeadings">Nummer</h4>
<div style="margin-top: -15px; width:100%">
<span class="toDoListItems number">
{{info.orderraderid}}
</span>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
The module and controller
// defining angular application main module
var app = angular.module('myapp',[])
// defining a controller in this module
// injecting $scope service to the controller for data binding with the html view
// (in the DOM element surrounded by ng-controller directive)
app.controller('InfoController',function($scope){
$scope.Information = [];
$scope.showMoreButton = false;
// Bind controller method to the $scope instead of $(".showMore").on("click", function() {});
$scope.showMore = function(){
var obj = JSON.parse(localStorage.getItem("toDoList"));
console.log(obj);
console.log(obj.length);
SetSpinner('show');
$scope.Information.push(obj);
SetSpinner('hide');
//$.removeCookie("toDoList2");
};
$.each(data, function (i, v) {
if (i<= 9) $scope.Information.push(data[i]);
if(i >= 10) cookieList.push(data[i]);
});
if (cookieList.length) {
localStorage.setItem("toDoList", JSON.stringify(cookieList));
//$(".showMore").removeClass("hidden");
$scope.showMoreButton = true; // use $scope vars and ng-class directive instead of $(".xyz").blahBlah()
}
});
You should not use JQuery, use ng-click to detect the click, because angular has no idea when JQuery is done and when it needs to refresh the interface

How to dynamically update view in AngularJS

I have 2 div elements as following and I want to show only one of them based on the doStuff() function being called in the controller when an anchor element is clicked.
<div ng-controller='myController'>
<div ng-show="{{states['currentState'] == 'A'}}">
//displaying this div if the currentState is A
<a ng-click="doStuff('B')">Do stuff and show B</a>
</div>
<div ng-show="{{states['currentState'] == 'B'}}">
//displaying this div if the currentState is B
</div>
</div>
Following is the controller code:
myApp.controller('myController', ['$scope', function($scope) {
var states = ['A', 'B'];
$scope.states = states;
$scope.states['currentState'] = $scope.states['currentState'] || 'A';
$scope.doStuff = function(stateToShow) {
//doing stuff
$scope.states['currentState'] = stateToShow;
};
}]);
The code above doesn't work as the state remains 'A' even after clicking the Do stuff and show B anchor element.
Could somebody help me understand why is it not working?
Edit
app.js
//...
.state('home', {
url: '/',
views: {
'': { templateUrl: 'partials/index.html' },
'myView#home': {
templateUrl: 'partials/myView.html',
controller: 'VehicleController'
}
//other named ui views
}
})
//...
index.html
<div class="main">
<div class="container">
<div class="row margin-bottom-40">
<div class="col-md-12 col-sm-12">
<div class="content-page">
<div class="row">
<div ui-view="myView"></div>
<!-- other named ui-views -->
</div>
</div>
</div>
</div>
</div>
</div>
myView.html
<div ng-controller='myController'>
<div ng-show="states['currentState'] == 'A'">
//displaying this div if the currentState is A
<a ng-click="doStuff('B')">Do stuff and show B</a>
</div>
<div ng-show="states['currentState'] == 'B'">
//displaying this div if the currentState is B
</div>
</div>
It is updating the scope. But possibly the issue is with the ng-show you are setting a string by using "{{notation}}" which becomes truthy always (even if it is "true" or "false"), just use the expression directly.
Change
<div ng-show="{{states['currentState'] == 'A'}}">
to
<div ng-show="states.currentState === 'A'">
Demo
From Doc:-
ngShow expression - If the expression is truthy then the element is shown or hidden respectively.
You are very close. The reason it is not working is the attribute "ng-show" does not need the "{{" "}}" notation to work.
I just built your code but took those off, and it is working as you described you wanted it to.
<div ng-show="states['currentState'] == 'A'">
//displaying this div if the currentState is A
<a ng-click="doStuff('B')">Do stuff and show B</a>
</div>
<div ng-show="states['currentState'] == 'B'">
//displaying this div if the currentState is B
</div>

Categories

Resources