How to access a ngform name from controller? - angularjs

I need to check if the elements on the current html page (being rendered using ui-view) are dirty or pristine before I navigate to next tab.
Parent page:
<div class="inner-menu">
<nav>
<div>
<ul class="nav nav-tabs edit-menu" role="tablist">
<!-- location 1 -->
<li ng-repeat="innerTab in innerTabListArr" ng-click="switchTab($index, $event)">
<a role="tab" data-toggle="tab" href="">{{innerTab.text}}</a>
</li>
</ul>
</div>
</nav>
<div ui-view="innerTabHolder" name="currForm"></div>
</div>
and the HTML template that will be rendered to innerTabHolder view is :
<div class="edit-general" id="General">
<div class="modal-dialog modal-lg">
<form class="form-horizontal" name="generalForm">
<label for="inputL3" class="control-label">Text</label>
<div class="col-sm-4">
<input type="text" class="form-control" ng-model="gn.myMdl">
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-10">
<!-- location 2 -->
<button class="btn" type="button" ng-click="switchTab(generalForm, $event)"> BCK </button>
<button class="btn" type="button" ng-click="saveGen()">Save Above</button>
<button class="btn" type="button" ng-click="switchTab(generalForm, $event)"> FWD </button>
</div>
</div>
</div>
</form>
</div>
</div>
There are multiple tabs that will get rendered into the view. And this is the controller I have:
myApp.controller('compTabCtrl',[ '$rootScope', '$scope', '$state', 'mainWebService',
function($rootScope, $scope, $state, mainWebService){
$scope.innerTabListArr = [{"text" : "Tab 1"},{"text" : "Tab 2"}];
$scope.switchInnerTab = function(tabId, event){
};
}]);
Ok, so this is basic outline and I believe, I have covered all parts. Now, my issue is I am not able to pass the form : "generalForm" into switchTab function at location 1 where as I can do the same at location 2.
I am using the form's $dirty and $pristine to check if the user has made any changes to the form. So, while clicking on the tab for navigation, the form becomes undefined.
How do I access the $dirty property of sub-view in controller.
Plunker for demo :
https://plnkr.co/edit/06F5JfXltinyxrZbbc14?p=preview

When you are trying to access the variable always use $scope
access curForm using
$scope.curForm.$dirty

Related

Angular add class to body from inside view

I have an app where, when a thumbnail is clicked a modal will open and play the video connected to the thumbnail. What I need to do is add a class to the body tag when this modal is open so I can stop the body content scrolling behind the modal.
I am using an ng-click to activate an ng-show and ng-if. The problem is all of this is inside the scope of an ng-repeat which in turn is inside the view. I am new to Angular and any help would be appreciated.
<div class="videos" ng-controller="modalCtrl">
<ul>
<li class="clear-fix" ng-repeat="video in filtered = videos | filter:search | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
<!-- THIS ACTIVATES THE MODAL WHEN CLICKED -->
<div ng-click="showModal = !showModal" class="item-thumbnail float-left pointer" back-img="{{video.thumbnail}}">
</div>
<div class="item-details-container float-left">
<div class="item-header">
<div ng-click="showModal = !showModal" class="item-title pointer">
<h3 class="underline">{{video.title}}</h3>
</div>
<div class="item-author pointer">
<span>by: <a class="underline" ui-sref="{{video.author_link}}">{{video.author}}</a></span>
</div>
</div>
<div class="item-description">
<p>{{video.description.trunc(150)}}</p>
</div>
</div>
<!-- THIS IS THE MODAL BACKGROUND COVER -->
<div ng-show="showModal" class="modal-cover"></div>
<!-- THIS IS THE MODAL -->
<div ng-show="showModal" class="modal-container">
<div ng-if="showModal" class="video-modal clear-fix">
<button class="btn-close" ng-click="$parent.showModal = false">
<span></span>
<span></span>
</button>
<div class="video-container float-left">
<youtube-video video-url="video.url"></youtube-video>
</div>
<div class="video-info-container float-right">
<div class="video-info">
<div class="item-header">
<div class="item-title">
<h3>{{video.title}}</h3>
</div>
<div class="item-author pointer">
<span>by: <a class="underline" ui-sref="{{video.author_link}}">{{video.author}}</a></span>
</div>
</div>
<div class="item-description">
<p>{{video.description}}</p>
</div>
</div>
<div class="voting-container clear-fix">
<div class="votingButton btn-solid pointer" ng-click="upVote(video); showDetails = !showDetails">
<i class="fa fa-thumbs-o-up" aria-hidden="true"></i>
</div>
<div class="bugButton btn-solid pointer">
<i class="fa fa-flag-o" aria-hidden="true"></i>
</div>
<div ng-show="showDetails = showDetails"><span>Thank you for voting.</span></div>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
Here's what you need to do :
You can use ng-class in your body tag like this
<body ng-class="{'is-modal-open': freeze}">
And you can write ng-click on your thumbnail like this
<div class="thumbnail" ng-click="is-modal-open=true"></div>
You could just make a div in your template like this:
<div class="fullscreen-modal">
//content here
</div>
And in your controller you could do this:
var elementResult = element[0].getElementsByClassName('fullscreen-modal');
angular.element(document.body).append(element);
Now your element is a direct child of <body>.
OR
Define the modal div outside of ng-repeat.
Then define a scope function
$scope.openModal() = function(contentOrVideoId)
{
//put logic here
$scope.showModal = true;
$scope.modalContent = contentOrVideoId;
}
And just call this function inside ng-repeat with ng-click="openModal('IdOrContent')"
You are looking for ngClass directive.
So if you would add this to the body element you want to disable scrolling on, it would give you what you are looking for:
<div ng-class="{'is-modal-open': showModal}">
In short, this will add the class is-modal-open when showModal validates to true
Just to clarify (Thanks #Ronnie), you need to make sure the <div> that contains what you call body is inside the scope of your controller (somewhere inside the div that has ng-controller). And you shouldn't put it directly on the <body> tag
[edit]
I don't like using $rootScope, but you could try this:
<body ng-class="{'is-modal-open': showModal}">
// Your div
<div ng-click="showHideModal()" class="item-title pointer">
// your controller
app.controller('modalCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.showHideModal = function() {
$rootScope.showModal = !$rootScope.showModal;
};
}]);

How to pass value to modal in Mobile Angular Ui modal?

I am using Mobile Angular UI.
In parent window there is list of category names. I want selected category name should get updated from modal. I am able to display modal. I want to pass selected category item from parent view to modal.
My code in parent view
<div ng-controller="CategoryController as TitleCats">
<div ng-repeat="cats in TitleCats.categories">
<a href=""
ui-turn-on="titleCatUpdatemodal"
class="btn btn-default" ng-click="TitleCats.openUpdateModel(cats)"> {{cats.name}} --> Edit</a>
</div>
<div ui-content-for="modals">
<div ng-include="'pages/titleCatUpdatemodal.html'"></div>
</div>
</div>
My Modal is
<div class="modal" ui-if='titleCatUpdatemodal' ui-state='titleCatUpdatemodal'>
<div class="modal-backdrop in"></div>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close"
ui-turn-off="titleCatUpdatemodal">×</button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<p><input type="text" ng-model="cats.name" >{{ cats.name }}</p>
</div>
<div class="modal-footer">
<button ui-turn-off="titleCatUpdatemodal" class="btn btn-default">Close</button>
<button ui-turn-off="titleCatUpdatemodal" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
When i click button it opens modal but no value!
Anyone please let me know how to get value in modal. Thanks in advance.
In your controller. you should have something similar to this:
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'templates/myModal.html',
controller: 'myModalCtrl',
resolve: {
myData: function () {
//do stuff
return stuff;
}
}
});
Inside that resolve, you can fill out the function which should then be accessible in your modals controller

Mobile Angular UI modal not able to update

Seems like modals in Angular UI is difficult to update, previously in Bootstrap I could update via jQuery but in Angular UI, not able to do even a simple update.
I have <span id="spnApproveSelectedCount">0</span> inside my modal-body, and I update it using jQuery $('#spnApproveSelectedCount').text(selectedCount); like this. It was working in Bootstrap but not in Angular UI.
Even update from $scope is not working if that variable is inside the modal. But if I moved them outside of modal it is working. I suspect it is because the modal is not display yet?
Updated:
I have a repeat in which the each item is clickable. When user clicked on it, it's supposed to open up the modal with further info. Below are my codes.
<div class="list-group">
<div ng-repeat="approval in approvals" class="list-group-item">
<div class="row">
<div class="selectable" style="float: left; width: 95%" ui-turn-on="detailsModal" ng-click="SetDetails(approval)">
<p class="list-group-item-text"><b>Ref</b> <span>{{ approval.ref }}</span></p>
<p class="list-group-item-text"><b>Pay To</b> <span>{{ approval.payTo }}</span></p>
<p class="list-group-item-text"><b>From</b> <span>{{ approval.from }}</span></p>
</div>
</div>
</div>
</div>
Notice that I have the ng-click on the row and below are my codes at controller.
$scope.SetDetails = function(current)
{
$scope.details = current;
}
And also partial of my modal code..
<div class="modal" ui-if="detailsModal" ui-state='detailsModal'>
<div class="modal-backdrop in"></div>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" ui-turn-off="detailsModal">×</button>
<h4 class="modal-title">Transaction Details</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-5">
Type
</div>
<div class="col-sm-7">
<b>{{ details.category }}</b>
</div>
</div>
<br />
<div class="row">
<div class="col-sm-5">
Submitted By
</div>
<div class="col-sm-7">
<b>{{ details.submittedBy }}</b>
</div>
</div>
Before everything, in fact in my controller I have a line of code to pre-set the details variable to take the first element (before it is passed to ng-repeat), this works and when the modal open, it is showing the first element value and that's it, the value stays there even if I click on row 2, 3 ...
$scope.details = $scope.approvals[0];

Using ng-click inside np-repeat

I'm trying to implement a shortlisting functionality in a case where I'm using ng-click inside ng-repeat.
While the $index is being displayed correctly outside the ng-click, $index is only the index of the last object in the JSON array in all the cases where the html is generated using ng-repeat.
I was expecting the respective venue or venue.id to be passed as an argument to shortlistThis(). I'm guessing that this could be an issue related to event binding.
Can someone help me understand what's going wrong here and probably a better way to do this if possible.
I did try checking this Bind ng-model name and ng-click inside ng-repeat in angularjs The fiddle here works just fine but, mine doesn't.
Update: I've found something interesting here. When the shortlist button is placed just under the ng-repeat, it work just as intended. But when, nested inside a div with a ng-class, it isn't working as intended. Can anyone explain and suggest a fix for this ?
//locationsapp.js var locationsApp = angular.module('locationsApp', []);
var venues = [{
id: "Flknm",
name: "ship",
}, {
id: "lelp",
name: "boat",
}, {
id: "myp",
name: "yacht",
}, ];
var shortlistedVenues = [];
var locationsApp = angular.module('locationsApp', ['ui.bootstrap']);
locationsApp.controller("getvenues", function($scope) {
$scope.venues = venues;
$scope.shortlistThis = function(venue) {
console.log(venue);
if (shortlistedVenues.indexOf(venue) == -1) {
shortlistedVenues.push(venue);
//alert('If');
} else {
console.log('already shortlisted')
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="locations" ng-app="locationsApp">
<div ng-controller="getvenues">
<div ng-repeat="venue in venues" ng-mouseover="" class="venue">
<div ng-controller="manageInfo">
<div class="row-fluid">
<div class="control" ng-click="showInfo()">
</div>
<div class="maps" class="info">
<div ng-class="class">
<div class="close-info" ng-click="hideInfo()">
<i class="fa fa-times">
</i>
</div>
<div class="row full-venue-contents" ng-app="ui.bootstrap.demo">
<div class="">
<div class="row-fluid myclass">
<div class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup" ng-click="shortlistThis(venue)">
Shortlist{{$index}}
</button>
</div>
</div>
</div>
</div>
</div>
<!-- End of Full Info Container -->
</div>
</div>
</div>
</div>
<div class="compare">
<button type="button" class="btn btn-default btn-lg btn-sup">
Compare ( {{shortlistedVenues.length}} )
</button>
</div>
</div>
</div>
</div>
</div>
The problem is with your button div which was position: fixed, it is actually showing the 1st button but clicking on it firing last button click, I'd suggest you should suggest you render only the shortlist button which has been selected by you. For that you can use ng-if and render those button which index is the same as that of selected $index
HTML
<div ng-if="selected==$index" class="button-holder">
<div class="row-fluid">
<div class="col-md-4 col-xs-4 text-center btn-grid">
<button type="button" class="btn btn-default btn-lg btn-sup"
ng-click="shortlistThis($parent.$index)">Shortlist{{$index}}</button>
</div>
</div>
</div>
& then put ng-click="selected='$index'" on ng-repeat div like
<div ng-repeat="venue in venues" class="venue" ng-click="selected=$index">
Working Fiddle
Hope this could help you, Thanks.

AngularJS boostrap dropdownmenu linked to input field keypress for autocomplete

I am a beginner to angulajs. I am trying to write this code that would display google search suggestions for a search field when i am typing in letters of my search text.
This is how I have done this inside the boostrap 3 navbar:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<div class="col-sm-4 col-md-4 pull-right dropdown" ng-controller="SearchCtrl">
<div class="navbar-form input-group">
<input type="text" class="form-control" placeholder="Search" name="q" id="dropdownMenu1" ng-model="text" ng-keyup="suggest()" data-toggle="dropdown">
<div class="input-group-btn">
<button class="btn btn-success" type="submit">
<i class="glyphicon glyphicon-search"></i>
</button>
</div>
</div>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="result in results">{{result}}</li>
</ul>
</div>
</div>
</div>
</div>
And correspondingly the AngularJS code:
app.controller('SearchCtrl', function ($scope, $http) {
$scope.suggest = function() {
var url = "http://google.com/complete/search?callback=JSON_CALLBACK&output=firefox&q=" + $scope.text;
$http.jsonp(url).success(function(data) {
$scope.results = data[1];
});
};
});
But for some reason the dropdown of suggestion is not showing up.
I monitor in debug console and see that request goes through just fine returning the suggestions, so no javascript error.
Any suggestion if how to make this work as it should (in both, bootstrap and angularjs) is appreciated.
Cheers :))
P.S. In debug I see the dropdown is created and populated just fine when I type "welcome" word:

Resources