How to popup chat window using node.js - angularjs

I am working on node.js and began to create a chat application I have built it successfully but the problem is that I want the chat window should be open when the client click on the name of the sender(who sent the message to the client).
I will show you the example what I have done till now.
Here you can see that the chat box is already open but I want it should open when a user is selected from "List of users" and the content of chat box should be replaced whenever a new user is selected and previous content should be removed.
Here is my index.html code :
<div class="col-md-4 user-list">
<h2>List of Users</h2>
<ul class="list-group">
<li class="list-group-item"
ng-repeat="user in userList"
ng-class="{ 'active' : user.id == selectedUser.uid}"
ng-click = seletedUser(user.id,user.userName);
ng-style="{
'cursor': user.id === socketId ? 'not-allowed' :'pointer'
}"
>
<span id='{{user.id}}' >{{ user.id === socketId ? 'You': user.userName }}</span>
<span id='{{user.id + "notify"}}' style="color:black; opacity:0.5; font:2px; padding:5px; visibility:hidden;"> {{'typing...'}}</span>
</li>
</ul>
</div>
</div>
<div class="container" id="messages">
<div class="row">
<div class="col-md-8">
<div class="panel panel-primary">
<div class="panel-heading">
<span class="glyphicon glyphicon-comment"></span> {{'Chat -' + selectedUser.uname}}
</div>
<div class="panel-body">
<ul class="chat col-md-7"
ng-repeat = "message in messages"
ng-style ="{'float':message.fromid == socketId ? 'left' : 'right'}">
<li>
<div class="clearfix">
<div class="direct-chat-text"
ng-style = "{'background-color': message.fromid == socketId ? '#d9edf7' : '#62f3bc'}"
>
{{message.msg}}
</div>
</div>
</li>
</ul>
<br></br>
</div>
<div class="panel-footer">
<div class="input-group">
<textarea elastic type="text" class="form-control custom-control" ng-model='message' ng-keyup="keyup()" ng-keydown="keydown()" ng-change="change()" placeholder="Type your message here..."></textarea>
<span class="input-group-addon btn btn-primary" ng-click="sendMsg()"><i class="glyphicon glyphicon-send"></i></span>
</div>
</div>
</div>
</div>
</div>
</div>
If you would require any other information related to code please comment.
As I am newbie to node.js so help me to solve my problem.
UPDATE
My script.js code which have sufficient details:
app.controller('app', ($scope,$timeout,socket) => {
$scope.socketId = null;
$scope.selectedUser ={ uid: null, uname: null};
$scope.messages = [];
$scope.msgData = null;
$scope.userList = [];
var TypeTimer;
var TypingInterval = 1000;
$scope.username = window.prompt('Enter Your Name');
if ($scope.username === '') {
window.location.reload();
}
$scope.seletedUser = (id,name) => {
if(id === $scope.socketId)
{
alert("Can't message to yourself.")
}
else
{
$scope.selectedUser =
{
uid: id,
uname: name
}
}
};
$scope.sendMsg = () => {
// const keyCode = $event.which || $event.keyCode;
if ($scope.message !== null && $scope.message !== '' && $scope.selectedUser.uid !== null) {
socket.emit('getMsg',{
toid : $scope.selectedUser.uid,
fromid: $scope.socketId,
msg : $scope.message,
name : $scope.username
});
$timeout.cancel(TypeTimer);
TypeTimer=$timeout( function(){
socket.emit('getTypingNotify',{
toid : $scope.selectedUser.uid,
fromid: $scope.socketId,
msg:"hidden"
});
});
$scope.message = null;
console.log($scope.selectedUser.uid);
}
else
{
alert("enter a message or select a User to send message");
}
};
socket.emit('username',$scope.username);
socket.on('userList', (userList,socketId) => {
if($scope.socketId === null){
$scope.socketId = socketId;
}
$scope.userList = userList;
});
socket.on('exit', (userList) => {
$scope.userList = userList;
});
socket.on('setMsg',(data) => {
document.getElementById(data.fromid+'notify').style.visibility= data.msg;
});
socket.on('sendMsg', (data) => {
//console.log('send');
$scope.messages.push(data);
});

my understanding is u want to show a pop up on click of a button or some text box u can use angular bootstarp model as shown here
"https://plnkr.co/edit/?p=preview"
and control the close and open in angularjs contoller and send the chat details too server side

After searching some tutorials and questions(on StackOverflow) I found a way and going to share with you all.
I created a directory name "open" and an attribute visible of this "open" directive to show and hide the dialog.
app.directive('open',function() {
return {
restrict: 'E',
template: `<div class="container">
<div class="row">
<div class="col-md-8">
<div class="panel panel-primary">
<div class="panel-heading">
<span class="glyphicon glyphicon-comment"></span>{{"Chat -" + selectedUser.uname}}
</div>
<div class="panel-body">
<div ppp-chat></div>
<br></br>
</div>
<div class="panel-footer">
<div class="input-group">
<textarea msd-elastic type="text" class="form-control custom-control" ng-model="message" ng-keyup="keyup()" ng-keydown="keydown()" ng-change="change()" placeholder="Type your message here..."></textarea>
<span class="input-group-addon btn btn-primary" ng-click="sendMsg()"><i class="glyphicon glyphicon-send"></i></span>
</div>
</div>
</div>
</div>
</div>
</div>`,
replace:true,
scope:false,
link: function postLink(scope,element,attrs) {
scope.$watch(attrs.visible,function(value){
if(value == true)
{
$(element).show();
}
else
$(element).hide();
});
$(element).on('show.bs.open',function() {
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.open',function() {
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
And a method in controller to toggle the chat window(hide or show)
$scope.toggleChat = () => {
$scope.showChat = false;
$scope.showChat = !$scope.showChat;
};
this toggleChat is used to change the value of showChat scope variable that is used to turn on(off) the visibility of chat box by alterating the showChat value as true or false.
In html I have replaced my id="messages" element( with its child and subchild) with
<open visible="showChat">
</open>

Related

two way binding not working even with dot notation

I'm starting with AngularJS and I am using a controller variable to navigate an array of questions, and it is working when using nextQuestion function, index gets updated and the next question is shown in the view, but if I try to obtain the same value (index) in a different function, it always returns 0.
I have seen on other questions that you should use an object to contain the variable to not manipulate primitive types directly in the controller, but it still does not work.
My controller:
myApp.controller('SurveyController',['$scope','$http', '$location','$routeParams','surveyMetrics','DataService',function($scope,$http, $location,$routeParams,surveyMetrics,DataService){
console.log('LOADED QUIZ CONTROLLER');
var vm = this;
vm.scope = {
index: 0
};
vm.surveyMetrics = surveyMetrics;
vm.surveyQuestions = DataService.surveyQuestions;
vm.DataService = DataService;
/*
vm.getQuestions = function(){
$http.get('/api/questions').then(function(response){
$scope.questions = response.data;
});
}
*/
/*
vm.activateSurvey = function(){
surveyMetrics.changeState(true);
}
*/
vm.getCurrentIndex = function(){
return vm.scope.index;
}
vm.nextQuestion = function () {
console.log('NEXT QUESTION!');
console.log('NUMBER OF QUESTIONS: '+ vm.surveyQuestions.length);
var currentIndex = vm.getCurrentIndex();
var newIndex = currentIndex+1;
scope = {};
if (currentIndex == vm.surveyQuestions.length) {
newIndex = vm.surveyQuestions.length -1;
}
vm.scope.index = newIndex;
console.log('Inside Object: '+vm.scope)
console.log('vm.index'+vm.scope.index);
console.log('vm.indexFunction'+vm.getCurrentIndex());
}
/*
vm.previousQuestion = function () {
console.log('PREVIOUS QUESTION!');
console.log('NUMBER OF QUESTIONS: '+ vm.surveyQuestions.length);
if (vm.scope.index == 0) {
vm.scope.index = 0;
}else{
vm.scope.index--;
}
}
*/
vm.activeSurveyQuestion = function(questionId,index){
console.log('question id and index',questionId,index);
if (questionId == index) {
var navBtn = document.getElementById('navBtn_'+index);
navBtn.classList.add('active');
}
}
vm.navigateSurvey = function () {
var answerPane = document.getElementById('answer-pane');
document.onkeydown = function (e) {
console.log('INSIDE KEYDOWN: ')
e.preventDefault();
var pressedKey = e.keyCode;
console.log('PRESSED KEY IN SURVEY: ' + pressedKey);
if (pressedKey === rightArrow) {
console.log('survey - right arrow pressed');
document.getElementById('nextQuestionBtn').click();
console.log('FUCKING INDEX FML!: '+vm.getCurrentIndex()+' | '+vm.scope.index);
var questionType = DataService.getQuestionType(vm.scope.index);
console.log('Survey Controller: question type: '+questionType);
}
if (pressedKey === leftArrow) {
console.log('survey - left arrow pressed');
document.getElementById('previousQuestionBtn').click();
}
(...)
My View:
<!--Satisfaction Survey-->
<div ng-controller="SurveyController as survey" ng-init="survey.getSurvey();">
<!--
<p ng-repeat="question in survey.surveyQuestions" ng-show ="survey.surveyMetrics.surveyActive">
{{question.question}}
</p>
-->
<!--Survey Modal -->
<div class="modal fade" id="surveyModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="text-center"> Customer Satisfaction Survey</div>
<div class="modal-header">
<h4 class="modal-title">{{survey.surveyQuestions[survey.getCurrentIndex()].question}}</h4>
</div>
<div class="modal-body survey" id="answer-pane">
<div class="row">
<div class="col-sm-2 survey-left-arrow" ng-click="survey.previousQuestion();" id="previousQuestionBtn">
<p>‹</p>
</div>
<div class="col-sm-8">
<!-- <p ng-repeat="answer in survey.surveyQuestions[survey.index].answers">{{answer}}</p> -->
<p ng-repeat="answer in survey.surveyQuestions[survey.getCurrentIndex()].answers">
<button type="button" class="btn" id="answerId_{{survey.getCurrentIndex()}}"
ng-class="{'survey-check-box': (survey.surveyQuestions[survey.getCurrentIndex()].type !== 'SingleChoice'),
'survey-btn_{{($index+1)}}': (survey.surveyQuestions[survey.getCurrentIndex()].type === 'SingleChoice')}">
<input type="checkbox" ng-if="survey.surveyQuestions[survey.getCurrentIndex()].type !== 'SingleChoice'"> {{answer}}
</button>
</p>
</div>
<div class="col-sm-2 survey-right-arrow " ng-click="survey.nextQuestion();" id="nextQuestionBtn">
<p>›</p>
</div>
</div>
</div>
<div class="text-center">
<strong> <p>Question: {{survey.surveyQuestions[survey.scope.index].questionNum}} of {{survey.surveyQuestions.length}}</p> </strong>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
<!-- <nav aria-label="Survey navigation">
<ul class="pagination pagination-sm justify-content-center">
<div ng-repeat="question in survey.surveyQuestions" >
<li class="page-item">
<a class="page-link" id = "navBtn_$index" ng-click="survey.index = $index">{{question.id}}</a>
</li>
</div>
</ul>
</nav> -->
</div>
</div>
I would like for the controller to change the variable and the view to update accordingly
Thank you for your time and thank you in advance.
It's 'survey.scope.index' not 'survey.index' in your HTML. I think you may be unclear the difference between using 'this' and '$scope'. You're mixing the two together which is not necessary. I would suggest removing 'scope' and just reference it in your HTML as 'survey.index'.

Angularjs cannot perform crud operations from accordion

I am trying to add a form to a bootstrap accordion and post a text value. Without accordion the form works alright. When i added the form to the accordion i am not able to pass text box value to angularjs controller. Basically i am not able to perform the CRUD operations as i am not able to pass the values. Minimum code related to the issue.
main.html
<div ng-controller="myController">
<accordion class="accordion" close-others="oneAtATime">
<accordion-group ng-repeat="group in groups" is-open="status.isOpen[$index]" >
<accordion-heading>
{{group.groupTitle}} <i class="fa chevron-icon" ng-class="{'fa-chevron-down': status.isOpen[$index], 'fa-chevron-right': !status.isOpen[$index]}"></i>
</accordion-heading>
<div ng-include="group.templateUrl"></div>
</accordion-group>
</accordion>
</div>
controller.js
App.controller('myController', ['$scope', 'Parts', function($scope, Parts) {
var original = $scope.parts;
$scope.submit = function() {
if ($scope.parts.a_id == null) {
$scope.createNewPart();
} else {
$scope.updatePart();
}
};
$scope.createNewPart = function() {
Parts.resource1.create($scope.parts);
};
$scope.updatePart = function() {
Parts.resource2.update($scope.parts)
};
$scope.oneAtATime = true;
$scope.groups = [{
groupTitle: "ADD 1",
templateUrl: "file1.html"
}, {
groupTitle: "ADD 2",
templateUrl: "file2.html"
}];
$scope.status = {
isOpen: new Array($scope.groups.length)
};
for (var i = 0; i < $scope.status.isOpen.length; i++) {
$scope.status.isOpen[i] = (i === 0);
}
} ]);
file1.html
<div>
<form name="myForm" ng-submit="submit()">
<div class="row">
<label class="col-md-2 control-lable" for="part">Add1</label>
<input type="text" ng-model="parts.part" id="part" required />
</div>
<div class="row">
<input type="submit" value="{{!parts.id ? 'Add' : 'Update'}}" ng-disabled="myForm.$invalid">
</div>
</form>
//inside table
<tr ng-repeat="a in availableparts >
<td>{{a.id}}</td>
<td>{{a.apart}}</td>
<td><button type="button" ng-click="editPart(a.id)" >Edit</button>
<button type="button" ng-click="deletePart(a.id)">Remove</button>
</td>
</tr>
</div>
Initially, you need to set $scope.parts to empty object {}, so when you access $scope.parts.id you will have null, instead of error saying id of undefined

angularjs enable/disable button on a directive

I'm new to Angular and I've been stuck on this for a day already. I have content for a modal being pulled with a directive which contains a simple form. I want to keep end-users from double clicking when submitting the form. So far this is the closets I've gotten. The content and modal pull up ok, when the button is clicked it gets disabled, the ajax calls is performed ok, the modal hides again, but the button remains disabled. When I mention button I refer to the button on the modal content with id="submitTradeForm"
This is the content in the modal
<div class="cdc-modal">
#using (#Html.BeginForm("_CreateTrade", "Employees", FormMethod.Post, new { #class = "cdc-form", #id = "createTradeForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(null, new { #class="text-danger" })
<div class="form-group">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", #placeholder = "trade" })
</div>
<div class="modal-footer">
<input id="submitTradeForm" type="button" ng-click="createTrade()" ng-disabled="isProcessing" class="btn cdc-button" value="Add new trade" />
</div>
}
</div>
This is the JS/Angular code
//********************** ANGULARJS - BEGIN *****************************************//
var app = angular.module('empApp',[]);
app.controller('empCtrl', function ($scope) {
});
app.directive('empModal',function($compile){
return {
restrict: 'EA',
templateUrl: '#Url.Content("~/Employees/_CreateTrade")',
replace: true,
controller: function ($scope) {
},
compile: function (tElement, tAttr) {
var contents = tElement.contents().remove();
var compiledContents;
return function (scope, iElement, iAttr) {
if (!compiledContents) {
compiledContents = $compile(contents);
}
compiledContents(scope, function (clone, scope) {
iElement.append(clone);
});
scope.createTrade = function () {
scope.isProcessing = true;
var form = $("#createTradeForm");
$.ajax({
cache: false,
async: true,
type: "POST",
url: form.attr("action"),
data: form.serialize(),
success: function (data) {
$("#createTradeModal").modal("hide");
//empty the container
$("#trades").html("");
var sel = $("#trades");
var newCont = "";
for (var i = 0; i < data.length; i++) {
sel.append('<option value="' + data[i].TradeId + '">' + data[i].Name + '</option>');
}
scope.isProcessing = false;
}
}).complete(function () {
scope.isProcessing = false;
console.log('completed');
console.log(scope.isProcessing);
});
};
};
}
}
});
//********************** ANGULARJS - END *****************************************//
This is in the main View
<div ng-app="empApp" ng-controller="empCtrl" class="container">
<div class="row">
<div class="col-sm-12">
<h3>Add New Employee</h3>
#using (Html.BeginForm("Create", "Employees", FormMethod.Post, new { #id = "createEmployeeForm"}))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(null, new { #class="text-danger" })
#Html.Hidden("selectedTrades", null, new { #id="selectedTrades" })
<div class="row" style="margin-bottom:15px;">
<div class="form-group col-sm-12">
#Html.TextBoxFor(m => m.EmployeeNumber, new { #placeholder = "employee number", #class = "form-control pull-left col-sm-8" })
<span style="min-width:160px;margin-top:5px;" class="col-sm-4 cdc-text pull-left">last entered: #lastentered</span>
</div>
</div>
<div class="form-group">
#Html.TextBoxFor(m => m.FirstName, new { #placeholder = "first name", #class = "form-control", #id = "firstname" })
</div>
<div class="form-group">
#Html.TextBoxFor(m => m.LastName, new { #placeholder = "last name", #class = "form-control", #id = "lastname" })
</div>
<div class="form-group">
#Html.TextBoxFor(m => m.StoreAs, new { #placeholder = "store as", #class = "form-control", #id = "storeas" })
</div>
<div class="row" style="padding-bottom:15px;min-width:320px !important;">
<div id="selectContainer" class="col-sm-8 pull-left" style="max-width:280px;">
<select id="trades" multiple="multiple">
#if (Model.Trades.Any())
{
foreach (CDCManagement.Trade trade in Model.Trades)
{
<option value="#trade.TradeId">#Html.Encode(trade.Name)</option>
}
}
</select>
</div>
<a href="#" onclick="addTrade()" data-toggle="modal" data-target="#createTradeModal">
<span class="glyphicon glyphicon-plus cdc-icon col-sm-4 pull-left cdc-icon-push" style="padding-left:0;"></span>
</a>
</div>
<div class="form-group">
#Html.TextBoxFor(m => m.PhoneNumber, new { #placeholder = "phone number", #class = "form-control" })
</div>
<div class="form-group">
#Html.TextAreaFor(m => m.Comments, new { #placeholder = "comments", #class = "form-control" })
</div>
<div class="form-group">
<input id="createButton" type="button" onclick="processForm()" class="btn cdc-button" value="Add New Employee" />
</div>
}
</div>
</div>
<!-- modal begin (add title) -->
<div class="modal fade" id="createTradeModal">
<div id="modal-dialog" class="modal-dialog">
<div id="modal-content" class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Add New Trade</h4>
</div>
<div id="modal-body" class="modal-body">
<emp-modal></emp-modal>
</div>
</div>
</div>
</div>
<!-- modal end -->
</div>
You're mixing jQuery and angular, and have hit the very common pitfall of using a jQuery event to trigger something in angular, in this case an AJAX response.
Whenever something changes that angular needs to know about, you need to trigger a $digest. There are lots of resources on the web about this, and I strongly recommend you get a good understanding of the angular lifecycle before writing any more code.
To fix your problem, you should simply be able to change the following line:
scope.isProcessing = false;
To
scope.$apply( function() {
isProcessing = false;
});
This tells angular you're changing something that it should know about, and it runs its digest loop which updates all of the views accordingly. This will re-enable the button that you previously disabled.
As an aside: I'm not sure if you're refactoring an existing application to use angular, or starting from scratch. Either way, you should try to remove your dependence on jQuery unless there is a specific reason for it. This stackoverflow question is a great reference that should get you thinking about things 'the angular way'. If you can get your head around this, it will pay dividends.

Angularjs autocomplete directive in 2 places in same dom

Hi,
I am building an autocomplete directive and I need it at two places in the same form. The autocomplete feature works fine but it shows the same directive at both the places. I have attached a image with this question, referring the Image even if I type in teh to colum the country autocomplete is also activated, how to I bind it to only the element where user is interacting ?
following is my code for the directive
angular.module('xyz').directive('autoComplete',['$rootScope',function($rootScope){
return {
restrict:'AE',
transclude: true,
replace: true,
scope:{
selectedTags:'=model',
userdata:'=',
name:'#'
},
templateUrl: function(elem,attr){ return 'views/rad/layout/autocomplete.html' },
link:function(scope,elem,attrs){
scope.suggestions=[];
scope.selectedTags=[];
scope.selectedIndex=-1; //currently selected suggestion index
scope.search=function(){
var newSuggestions = [];
// if(attrs.userdata.indexOf(scope.searchText)===-1){
// //dataUser.unshift(scope.searchText);
// }
for(var i=0; i < scope.userdata.length;i++)
{
if(dataUser[i].toLowerCase().indexOf(scope.searchText.toLowerCase()) !== -1){
newSuggestions.push(dataUser[i]);
}
}
scope.suggestions = newSuggestions;
scope.selectedIndex = -1;
}
scope.checkKeyDown=function(event){
console.log(event.keyCode);
if(event.keyCode===40){//down key, increment selectedIndex
event.preventDefault();
if(scope.selectedIndex+1 !== scope.suggestions.length){
scope.selectedIndex++;
}
}
else if(event.keyCode===38){ //up key, decrement selectedIndex
event.preventDefault();
if(scope.selectedIndex-1 !== -1){
scope.selectedIndex--;
}
}
else if(event.keyCode===13){ //enter pressed
scope.addToSelectedTags(scope.selectedIndex);
}
}
scope.addToSelectedTags=function(index){
if(scope.selectedTags.indexOf(scope.suggestions[index])===-1){
scope.selectedTags.push(scope.suggestions[index]);
scope.searchText='';
scope.suggestions=[];
}
}
scope.$watch('selectedIndex',function(val){
if(val!==-1) {
scope.searchText = scope.suggestions[scope.selectedIndex];
}
});
scope.removeTag=function(index){
scope.selectedTags.splice(index,1);
}
}
}
}])
following is the auto complete template
<div class="tags-wrapper">
<div id="tagsList" class="tags-cloud">
<div class="suggestionListing">
<div ng-repeat="selectedTag in selectedTags track by $index" class="tag">
<span class="tagName">{{selectedTag}}</span>
<span> <b ng-click="removeTag($index)" class="fa fa-times cross"></b></span>
</div>
</div>
<div class="input-group">
<input type="text" name="{{inputname}}"placeholder="" aria-describedby="basic-addon2" id="searchInput" class="form-control no-border" ng-model="searchText" ng-keydown="checkKeyDown($event)" class="form-control" ng-model="searchText" ng-change="search()"/>
<div class="suggestions-list">
<div ng-repeat="suggestion in suggestions track by $index" class="blockSpan" ng-click="addToSelectedTags($index)" ng-mouseover="$parent.selectedIndex=$index" ng-class="{active : selectedIndex===$index}">
<div class="userAvatar">
<i class="fa fa-user"></i>
</div>
<div class="userInfo">
{{suggestion}}
</div>
<br clear="all" />
</div>
</div>
</div>
</div>

how to handle scope in angular js

I am working with angular js for my dashboard. I have an over all minimize button to minimize all widget and then each widget have own minimize button. I done with following script its not working.
when i click widget minimize button its minimize all widget. but i want minimize that widget only.
var dashboard = angular.module("dashboard",['ui.bootstrap']);
dashboard.controller('dash-control', ['$scope', function($scope) {
$scope.isHidden = false;
$scope.toggle = function(){
$scope.isHidden = !$scope.isHidden;
};
$scope.toggleonce= function()
{
if( this.isHidden === true)
this.isHidden = false;
else
this.isHidden = true;
};
}]);
HTML code like follow:
<div class="contentpanel" ng-app="dashboard" ng-controller="dash-control as ctrl">
<button class="btn btn-white" type="button" ng-click="toggle()"><i class="fa fa-minus-square"> </i> </button>
<div>
<i class="fa fa-minus"></i>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 1</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
<div>
<i class="fa fa-minus"></i>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 2</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
......
.....
.....
</div>
I would rather create a directive with isolated scope for represent a inner widget. for instance;
dashboard.directive('myWidget',function(){
return {
scope:{},
template:"<div>\r\n<a href=\"\" class=\"tooltips\" ng-click=\"toggleonce()\" title=\"Minimize Panel\"><i class=\"fa fa-minus\"><\/i><\/a>\r\n<div class=\"row tinychart\" ng-show=\"isHidden\">asdasdasd<\/div>\r\n<div class=\"row tinychart\" ng-hide=\"isHidden\">sdasdasd<\/div>\r\n\r\n <\/div>",
link:function($scope)
{
$scope.isHidden = false;
$scope.toggle = function(){
$scope.isHidden = !$scope.isHidden;
};
$scope.togglesingle = function()
{
if( this.isHidden === true)
this.isHidden = false;
else
this.isHidden = true;
};
}
}
});
Then In Html Body;
<div class="contentpanel" ng-app="dashboard" >
<button class="btn btn-white" type="button" ng-click="toggle()"><i class="fa fa-minus-square"> </i> </button>
<div my-widget></div>
<div my-widget></div>
</div>
Note that I haven't run and check the example. I hope you got the idea.
Edited:
The ng-repeat will loop the array (list) and initiate each element to 'item' variable. You can pass that data to your directive. Check the updated code.

Resources