Angular Bootstrap UI accordion not working as expected - angularjs

I am using accordion component of Angular Bootstrap UI. The first accordion is expanded by default. When user add new accordion then first accordion should collapse and newly added accordion should be expand. When user clicks any accordion then it should be expanded and collapse rest of the accordions. User can add more than one accordion.
How can I achieve this?
I'm newbie to angular and Angular Bootstrap UI.
What I have done so far
Ctrl.js
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function($scope) {
$scope.oneAtATime = true;
$scope.groups = [{
title: 'Dynamic Group Header - 1',
content: 'Dynamic Group Body - 1'
}, {
title: 'Dynamic Group Header - 2',
content: 'Dynamic Group Body - 2'
}, {
title: 'Dynamic Group Header - 3',
content: 'Dynamic Group Body - 3'
}];
$scope.status = {
isCustomHeaderOpen: false,
isFirstOpen: true,
isFirstDisabled: false
};
// work permit form
$scope.transforms = [{
name: "transform",
id: 1,
wpformfields: [{
employee: '',
admount: ''
}]
}];
$scope.addtransactionForm = function(transform) {
$scope.currentnum = transform.wpformfields.length;
//alert("hello");
transform.wpformfields.push({
employee: '',
amount: ''
});
};
});
index.html
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.1.3.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="AccordionDemoCtrl" class="container">
<br>
<br>
<br>
<div class="row">
<div class="col-md-10">
<form role="form" id="$index" class="base-form" ng-repeat="form in transforms track by $index">
<input type="checkbox" ng-model="oneAtATime" style="display:none">
<uib-accordion close-others="oneAtATime">
<div uib-accordion-group class="panel-default" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled" ng-repeat="itemfield in form.wpformfields track by $index">
<uib-accordion-heading>
Transaction <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.isFirstOpen, 'glyphicon-chevron-right': !status.isFirstOpen}"></i>
</uib-accordion-heading>
<div class="md-col-10 main-container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Employee name </label>
<input type="text" class="form-control" name="employee" id="employee" ng-model="itemfield.employee">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Amount </label>
<input type="text" class="form-control" name="amount" id="amount" ng-model="itemfield.amount">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button type="submit" class="btn btn-default pull-right" ng-click="addTransaction(form, $index)"><i class="fa fa-floppy-o"></i> Save record</button>
</div>
</div>
</div>
</div>
</uib-accordion>
<div class="row">
<div class="col-md-12 col-md-offset-5">
<a class="btn btn-danger" ng-click="addtransactionForm(form)"><i class="fa fa-user-plus fa-lgt" ></i> Add new transaction record</a>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Plunker available link

There is modified version which should satisfy your needs. Basically, you need to add isOpen and isDisabled property for each accordion then set isOpen to true for new accordion, others will be closed automatically.

Related

Single modal pulling data from inside ng-repeat

I am trying to create a single modal that pulls dynamic data from an ng-repeat (work in workList) in AngularJS. In other words, the modal does not live within the ng-repeat in order to prevent multiple modals from generating when I can just add dynamic content to one modal. Here's my view:
<div ng-controller="mainController">
<div ng-repeat="work in workList"
//some other code here...
<div ng-controller="modalController">
<button ng-click="open_modal(work)" data-toggle="modal" data-target="#myModal">
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<h2>
{{ timechosen.data.name }}
</h2>
</div>
</div>
Here's my modalController:
angular
.module('testApp')
.controller('modalController', ['$scope', function($scope) {
$scope.open_modal = function(time_chosen) {
$scope.timechosen = time_chosen.data;
}
}])
In my modal, {{ timechosen.data.name }} does not display anything and I'm pretty sure it's a nesting scope issue because when I set $scope.timechosen in my mainController, it seems to work fine. However, I do need to set $scope.timechosen in the modalController but can't seem to find a way around the possible nested scope issue. Any ideas?
Have you thought about putting everything inside a single controller? Like this:
angular
.module('app', [])
.controller('TestController', function($scope) {
$scope.items = [
{
label: 'Item 1',
body: 'This is the body of item 1',
title: 'This is number 1'
},
{
label: 'Item 2',
body: 'This is the body of item 2',
title: 'This is number 2'
},
{
label: 'Item 3',
body: 'This is the body of item 3',
title: 'This is number 3'
}
]
$scope.changeModalInfo = function(info) {
$scope.info = info;
}
});
#import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="TestController as ctrl">
<ul>
<li ng-repeat="item in items">
<button data-toggle="modal" data-target="#myModal"
ng-click="changeModalInfo(item)">
{{item.label}}
</button>
</li>
</ul>
<div class="modal fade"
id="myModal"
tabindex="-1"
role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div 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">{{info.title}}</h4>
</div>
<div class="modal-body">
<p>{{info.body}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div>
</div>
</div>
</body>
</html>
If you need to break into more than one controller, you can use services or $rootScope (not advised).
angular
.module('app', [])
.controller('ModalController', function($scope, ModalService) {
$scope.modal = ModalService;
})
.controller('TestController', function($scope, ModalService) {
$scope.items = [
{
label: 'Item 1',
body: 'This is the body of item 1',
title: 'This is number 1'
},
{
label: 'Item 2',
body: 'This is the body of item 2',
title: 'This is number 2'
},
{
label: 'Item 3',
body: 'This is the body of item 3',
title: 'This is number 3'
}
]
$scope.changeModalInfo = function(info) {
ModalService.info = info;
}
})
.service('ModalService', function() {
return {};
});
#import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="TestController as ctrl">
<ul>
<li ng-repeat="item in items">
<button data-toggle="modal" data-target="#myModal"
ng-click="changeModalInfo(item)">
{{item.label}}
</button>
</li>
</ul>
</div>
<div class="modal fade"
id="myModal"
tabindex="-1"
role="dialog"
aria-labelledby="myModalLabel"
ng-controller="ModalController as ctrl">
<div class="modal-dialog" role="document">
<div 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">{{modal.info.title}}</h4>
</div>
<div class="modal-body">
<p>{{modal.info.body}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div>
</div>
</body>
</html>

Displaying values in modal from ng-repeat

I have list of stories with images , content and title in ng-repeat.
When I click on particular story , I need a bootstrap model to open and values to be displayed . I am doing it by calling a function showStories(); But I couldnt do it . I am getting empty value since its globally declared as
$scope.selectedStoryPreview = "";
$scope.selectedStoryContent = "";
$scope.selectedStoryTitle = "";
Html :
<div class="image" ng-repeat="item in filteredStories track by $index">
<img ng-src="{{item.images}}" style="cursor: pointer;" ng-click="showStories(item)" data-toggle="modal" data-target="#storyPreview">
<button><span>{{item.title}}</span>
</button>
</div>
JS:
$scope.showStories = function(item) {
$scope.selectedStoryPreview = item.images;
$scope.selectedStoryContent = item.content;
$scope.selectedStoryTitle = item.title;
}
Modal :
<div class="modal fade" id="storyPreview" role="dialog" data-keyboard="false" data-backdrop="static" style="padding-top: 8em;">
<div class="modal-dialog">
<div class="modal-content" style="text-align: center;">
<div class="modal-header imagemodalhead">
<h4>{{selectedStoryTitle}}</h4>
<a class="edit" ng-click="openmanageprofile()"><img src="css/images/edit.png">
</a>
</div>
<div class="modal-body" style="background: #eee;">
<div class="row">
<img class="file-imageStory" ng-src="{{selectedStoryPreview}}" />
</div>
<br>
<div class="row">
<div class=" col-sm-12 storyPrv">
<span class="styletheStory">{{selectedStoryContent}}</span>
</div>
</div>
<div class="modal-footer imagefooter">
<button type="button" class="button share" ng-click="closePreview()" style="background-color: #7B7D7D; color: black;">close</button>
</div>
</div>
$scope.model is undefined. Set it as $scope.model = {} This way
you can dynamically add properties to it at compile time.
Moreover, you could use data-toggle="modal"
data-target="#viewdetails" as the action event to point to correct
modal.
Also, no need to pass individual properties as arguments in the
method showStories(item), you could send out complete object and
obtain its properties.
DEMO:
Click on the image to open modal.
function MyCtrl($scope) {
$scope.filteredStories = [{
id: 1,
images: 'sample1.png',
title: "sample1",
content: "content here..."
}, {
id: 2,
images: 'sample2.png',
title: "sample2",
content: "content here..."
}, {
id: 3,
images: 'sample3.png',
title: "sample3",
content: "content here..."
}, {
id: 4,
images: 'sample4.png',
title: "sample4",
content: "content here..."
}]
$scope.showStories = function(item) {
$scope.selectedStoryPreview = item.images;
$scope.selectedStoryContent = item.content;
$scope.selectedStoryTitle = item.title;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<body ng-app ng-controller="MyCtrl">
<div class="image" ng-repeat="item in filteredStories track by $index">
<img ng-src="{{item.images}}" style="cursor: pointer;" ng-click="showStories(item)" data-toggle="modal" data-target="#storypreview">
<button><span>{{item.title}}</span>
</button>
</div>
<div class="modal fade" id="storypreview" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" style="text-align: center;">
<div class="modal-header imagemodalhead">
<h4>{{selectedStoryTitle}}</h4>
<a class="edit" ng-click="openmanageprofile()"><img src="css/images/edit.png">
</a>
</div>
<div class="modal-body" style="background: #eee;">
<div class="row">
<img class="file-imageStory" ng-src="{{selectedStoryPreview}}" />
</div>
<br>
<div class="row">
<div class=" col-sm-12 storyPrv">
<span class="styletheStory">{{selectedStoryContent}}</span>
</div>
</div>
<div class="modal-footer imagefooter">
<button type="button" class="button share" ng-click="closePreview()" style="background-color: #7B7D7D; color: black;" data-dismiss="modal">close</button>
</div>
</div>
</div>
</div>
</div>
</body>
If modal controller is different. Then send the value using resolve method. If the controller is same. Then I think it should display the values.
And provide the id of modal here :
<div class="modal-content" id="storyPreview" style="text-align: center;">

Display comments in comment box with AngularJS - ng-repeat inside another ng-repeat using API JSON data

I'm simply trying to display comments that users put within a comment box. However, I'm having issues because it's within an ng-repeat directive. Let me show so you can better understand visually:
<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
<head>
<meta charset="UTF-8">
<title>Nuvi Interview Code Project</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="stylesheet.css">
</head>
<body ng-controller="HomeController">
<div class="container-fluid">
<h1>Nuvi Interview Code Project</h1>
<form class="form-inline well well-sm clearfix">
<span class="glyphicon glyphicon-search"></span>
<input type="text" placeholder="Search" class="form-control" ng-model="search">
</form>
<div class="row">
<div class="col-sm-6" ng-repeat="actor in data | filter:search">
<div class="well well-sm">
<div class="row">
<div class="col-md-6">
<img ng-src="{{actor.actor_avator}}" class="img-rounded img-responsive well-image pull-left">
<h3 class="name" data-toggle="modal" data-target="#actor-info" ng-click="changeActiveActor(actor)">{{actor.actor_name}}</h3>
<hr>
<p ng-repeat="say in activity_comments">{{say}}</p>
<div>{{actor.activity_comments}} Comments {{actor.activity_likes}} likes {{actor.activity_shares}} shares</div>
<br>
<input type="text" class="form-control" placeholder="Write a comment..." ng-model="comment">
<button class="btn btn-default" ng-click="postComment($index, comment)">Post Comment</button>
</div>
<div class="col-md-6">
<p class="pull-right"><strong>{{actor.provider}} </strong></p>
<p><strong>Post</strong></p>
<h5>{{actor.activity_message}}</h5>
<br><br><br><br><br>
<button ng-click="countUp($index)" type="button" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-thumbs-up"></span> Like
</button>
<button ng-click="countDown($index)" type="button" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-thumbs-down"></span> Unlike
</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal" id="actor-info">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2>{{activeActor.actor_name}}</h2>
</div>
<div class="modal-body">
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<img ng-src="{{activeActor.actor_avator}}" class="img-rounded img-responsive">
</div>
</div>
<div class="row top-buffer">
<div class="col-md-6">
<p>Message: {{activeActor.activity_message}}</p>
<p><strong>Username:</strong> {{activeActor.actor_username}}</p>
<p><strong>Date:</strong> {{activeActor.activity_date}}</p>
<p><strong>Comment:</strong> {{activeActor.activity_comments}}</p>
<p><strong>Likes:</strong> {{activeActor.activity_likes}}</p>
<p><strong>Sentiment:</strong> {{activeActor.activity_sentiment}}</p>
<p><strong>Shares:</strong> {{activeActor.activity_shares}}</p>
<p><strong>ID:</strong> {{activeActor.id}}</p>
<p><strong>Provider:</strong> {{activeActor.provider}}</p>
</div>
<div class="col-xs-12">
<p></p>
<button class="btn btn-danger pull-right" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- END OF MODAL -->
<hr>
<h6 class="pull-right">Coded by Saia Fonua</h6>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="app.js"></script>
</body>
</html>
Here is my app.js:
var app = angular.module("MyApp", []);
app.controller("HomeController", ["$scope", "$http", function($scope, $http) {
$scope.data = [];
$scope.search = "";
$scope.comment = "";
$scope.activeActor = {};
$scope.changeActiveActor = function(index) {
$scope.activeActor = index;
}
$scope.postComment = function(index, comment) {
console.log('comment ', comment);
//$scope.data[index].comments = [];
$scope.data[index].comments.push(comment);
console.log($scope.data[index]);
}
$scope.countUp = function(index) {
$scope.data[index].activity_likes++;
}
$scope.countDown = function(index) {
$scope.data[index].activity_likes--;
}
$http.get("https://nuvi-challenge.herokuapp.com/activities").then(function(response) {
console.log(response.data);
$scope.data = response.data;
})
}])
Can someone please help me to get the comments to display. When you start playing around with it, you'll see why it's harder than the problem sounds!
You have some problems with this line
<p ng-repeat="say in activity_comments">{{say}}</p>
As you are adding the comments to
$scope.data[index].comments.push(comment);
They would be reached by the actor.comments object
<p ng-repeat="say in actor.comments">{{say}}</p>

angular ui bootstrap doesn't load

I take everything from the example page. basically there is nothing different, controller and html body is pure copy paste from accordion example from
https://angular-ui.github.io/bootstrap/
I tried everything....
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<title>Test</title>
<!-- CSS files -->
<link rel="stylesheet" href="../../bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../../bower_components/bootstrap/dist/css/bootstrap-theme.min.css">
<!-- JS libs -->
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="../../bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../../bower_components/angular-animate/angular-animate.min.js"></script>
<!-- Application -->
<script>
var app = angular.module('app',['ui.bootstrap']);
app.controller('AccordionDemoCtrl', function ($scope) {
$scope.oneAtATime = true;
$scope.groups = [
{
title: 'Dynamic Group Header - 1',
content: 'Dynamic Group Body - 1'
},
{
title: 'Dynamic Group Header - 2',
content: 'Dynamic Group Body - 2'
}
];
$scope.items = ['Item 1', 'Item 2', 'Item 3'];
$scope.addItem = function() {
var newItemNo = $scope.items.length + 1;
$scope.items.push('Item ' + newItemNo);
};
$scope.status = {
isFirstOpen: true,
isFirstDisabled: false
};
});
</script>
</head>
<body>
<div ng-controller="AccordionDemoCtrl">
<script type="text/ng-template" id="group-template.html">
<div class="panel {{panelClass || 'panel-default'}}">
<div class="panel-heading">
<h4 class="panel-title" style="color:#fa39c3">
<a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span
ng-class="{'text-muted': isDisabled}">{{heading}}</span></a>
</h4>
</div>
<div class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" style="text-align: right" ng-transclude></div>
</div>
</div>
</script>
<p>
<button type="button" class="btn btn-default btn-sm" ng-click="status.open = !status.open">Toggle last panel</button>
<button type="button" class="btn btn-default btn-sm" ng-click="status.isFirstDisabled = ! status.isFirstDisabled">Enable / Disable first panel</button>
</p>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="oneAtATime">
Open only one at a time
</label>
</div>
<uib-accordion close-others="oneAtATime">
<uib-accordion-group heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
This content is straight in the template.
</uib-accordion-group>
<uib-accordion-group heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</uib-accordion-group>
<uib-accordion-group heading="Dynamic Body Content">
<p>The body of the uib-accordion group grows to fit the contents</p>
<button type="button" class="btn btn-default btn-sm" ng-click="addItem()">Add Item</button>
<div ng-repeat="item in items">{{item}}</div>
</uib-accordion-group>
<uib-accordion-group heading="Custom template" template-url="group-template.html">
Hello
</uib-accordion-group>
<uib-accordion-group heading="Delete account" panel-class="panel-danger">
<p>Please, to delete your account, click the button below</p>
<button class="btn btn-danger">Delete</button>
</uib-accordion-group>
<uib-accordion-group is-open="status.open">
<uib-accordion-heading>
I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</uib-accordion-heading>
This is just some content to illustrate fancy headings.
</uib-accordion-group>
</uib-accordion>
</div>
```
in complement I add my bower dependency:
"dependencies": {
"angular": "~1.4.6",
"angular-bootstrap": "~0.13.4",
"angular-route": "~1.4.6",
"bootstrap": "~3.3.5",
"jquery": "~2.1.4",
"lodash": "~3.10.1",
"angular-bootstrap-switch": "~0.4.1",
"angularjs-slider": "~0.1.35",
"angular-animate": "~1.4.7",
"angular-ui-notification": "~0.0.14"
}
In bower.json, update angular-bootstrap to the latest: 0.14.2 as of today.
Your example doesn't work because you copy pasted the code from the documentation: this code is valid for 0.14.x but you are still in 0.13.x.
If you want to stay with version 0.13.4, you will have to remove the uib- prefix in the name of the directives, i.e.:
Replace uib-accordion with accordion
Replace uib-accordion-group with accordion-group
Replace uib-accordion-heading with accordion-heading
Check your console for an error by inspecting the element. That information will make your question easier to answer. Also you could try switching the last two script references to make sure dependencies are loaded. Loading UI Bootstrap last would be safest.

AngularJS: Value from Page Not Showing in Modal on Click

I have a button (link) on a modal that when clicked (copySummaryToTask($event)) is supposed to copy data from the page's $scope element (thisRequest) into the modal's $scope element (nTask). It copies the correct data into the $scope but the data doesn't appear in the modal even though I am using $scope.$apply();
Here's the plunkr.
Here's my controller:
var myApp = angular.module('myApp', []);
myApp.controller('MainController', function($scope){
$scope.NewTaskPane = false;
$scope.thisRequest = {
ID: 543,
Title: 'Create This Wonderful SharePoint 2013 SPA',
Request_Summary: "Rule fruit and under female she'd every signs creepeth good Night, fly lesser they're be green cattle and living tree also spirit us years two. Seasons he good under creepeth fifth air is. For morning. It creeping multiply from, saying.",
Request_Type: 'Web'
};
$scope.Tasks = [
{ID: 20, Title: 'Prototype App', Assigned_To: 'Wayne, Bruce', Status: 'Completed', TOT: 4.5},
{ID: 21, Title: 'Develop App CSS', Assigned_To: 'Prince, Diana', Status: 'Completed', TOT: 6}
];
$scope.addNewTask = function($event){
$event.preventDefault();
$scope.NewTaskPane = true;
$scope.nTask = {
ID: $scope.Tasks.length + 1,
Request_ID: $scope.thisRequest.ID,
Title: $scope.thisRequest.Title,
Status: 'Assigned',
Resource_Instructions: ''
};
};
$scope.copySummaryToTask = function($event){
$event.preventDefault();
//alert($scope.thisRequest.Request_Summary);
$scope.nTask.Resource_Instructions = $scope.thisRequest.Request_Summary;
if (!$scope.$$phase) { $scope.$apply(); }
} // end copySummaryToTask fn
}); // end main controller
and here's the view:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link data-require="bootstrap-css#3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script data-require="jquery#*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="bootstrap#*" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<div id="overlay" data-ng-show="NewTaskPane">
<div class ="preference_form wModal" id="frmPreference">
<form name="frmNewTask" ng-submit="saveNewTask($event)">
<span class="close-modal">
close
</span>
<h1>New Task</h1>
<div class="row">
<div class="form-group col-lg-12">
<label for="description">Task Title:</label>
<input type="text" class="form-control" name="Title" ng-model="nTask.Title">
</div>
</div>
<div class="row">
<div class="form-group col-lg-12">
<label>Additional Instructions for Resource:</label>
<textarea class="form-control" rows="5">{{ntask.Resource_Instructions}}</textarea>
<button class="btn btn-link" style="float:right;" ng-click="copySummaryToTask($event)">Copy Customer Request Summary.</button>
</div>
</div>
<div class="frmElementSubmit">
<input type="button" class="btn btn-default" value="CANCEL" ng-click="NewTaskPane = false" />
<input type="submit" class="btn btn-primary" value="SAVE" ng-click="NewTaskPane = false" />
</div>
</form>
<pre>{{nTask | json}}</pre>
</div>
</div>
<div class="frmFull_Page">
<h1 class="frmTitle">Edit Request</h1>
<div class="frmBar clr-purple">
<h3>Request Information</h3>
</div>
<div class="frm_pane">
<div class="row">
<form name="EditSapForm" role="form">
<!-- ID / TITLE -->
<div class="row">
<div class="form-group col-lg-3">
<label for="req_id">Request ID:</label>
<input type="text" class="form-control" name="ID" ng-model="thisRequest.ID" disabled="disabled">
</div>
<div class="form-group col-lg-9">
<label for="title">Title:</label>
<input type="text" class="form-control" id="Title" ng-model="thisRequest.Title">
</div>
</div>
<!-- WORK SUMMARY -->
<div class="row">
<div class="form-group col-lg-12">
<label>Work Summary:</label>
<textarea name="Request_Summary" class="form-control" rows="5" ng-model="thisRequest.Request_Summary"></textarea>
</div>
</div>
<!-- WORK TASKS*** -->
<div class="row">
<div class="form-group col-lg-12">
<div class="row">
<div class="form-group col lg-12" style="margin-left:16px;">
<label>Work Tasks [{{Tasks.length}}]</label>
<table class="table table-striped" style="width:90%; margin:5px auto;">
<tr>
<th>ID</th>
<th>TITLE</th>
<th>ASSIGNED TO:</th>
<th>STATUS</th>
<th>TOT</th>
<th> </th>
</tr>
<tr ng-hide="Tasks.length">
<td colspan="6"><b>No Tasks Found!</b></td>
</tr>
<tr ng-repeat="task in Tasks">
<td>{{task.ID}}</td>
<td>{{task.Title}}</td>
<td>{{task.Assigned_To}}</td>
<td>{{task.Status}}</td>
<td>{{task.TOT}}</td>
<td>edit</td>
</tr>
<tr>
<td colspan="6"><a ng-click="addNewTask($event)">Add New Task</a></td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!-- SUBMIT BUTTON*** -->
<div class="row" style="margin-top:30px;">
<div class="form-actions col-lg-12">
<button type="submit" class="btn btn-primary">SUBMIT</button>
</div>
</div>
</form>
</div> <!-- end row -->
</div> <!-- end frm_pane -->
</div> <!-- end frmFull_Page-->
</body>
</html>
There's a typo in your view:
<textarea class="form-control" rows="5">{{ntask.Resource_Instructions}}</textarea>
... where ntask should be nTask. Once you fix it, you won't need the $scope.apply():
$scope.copySummaryToTask = function($event){
$event.preventDefault();
$scope.nTask.Resource_Instructions = $scope.thisRequest.Request_Summary;
} // end copySummaryToTask fn
Replace
<textarea class="form-control" rows="5">{{ntask.Resource_Instructions}}</textarea>
With
<textarea class="form-control" rows="5" ng-model="nTask.Resource_Instructions"></textarea>
This will do it, plus capture any new text added by the user.

Resources