AngularUI Accordion toggle on scope variable - javascript

I am using AngularUI Bootstrap accordion and I need it to be open depending on data, coming from a $http request, here's my markup:
<div data-accordion>
<div data-accordion-group data-heading="Group 1" is-open="!$parent.toggle">
<!-- random content -->
</div>
<div data-accordion-group data-heading="Group 2" is-open="$parent.toggle">
<!-- random content -->
</div>
</div>
And here's an example of the data coming in:
randomService.getdata(id).then(function(response) {
randomService.toggle = response.data;
$scope.toggle = randomService.toggle;
});
The problem with this setup is that if I click the header to open/close, the variable gets toggled as well(I want to avoid that). It can be avoided by changing the is-open to !( !!($parent.toggle) and !!($parent.toggle), respectively.
However the problem remains: When $scope.toggle is false the proper accordion is open, when it's true both accordions are closed.

One solution could be to use two scope variables open1 and open2, so you can always set the right one to true when the data comes in, no matter what state they are in. This should also work if the accordion has the attribute close-others set to true.

Related

angularjs dynamically change footer

In my app for android I have multiple html's, most of them have the same footer with three icons, but some of the pages have different footers with 2 or 3 icons.
What is the correct way to accomplish this?
Because I would like to maintain mu ion-footer-bar in the main.html with the ion-header-bar, ion-nav-bar and ion-nav-view(where are showed all htmls).
I've tried to use a sort of ng-repeat with conditional reading of a structure depending on the current page, also using a tabs.html with different sections with different id's, none of the two solutions is working and I messed to much the code, so while I continue trying I would like to know if one of these approximations is correct.
thanks
You could use ng-show and ng-include to conditionally load in the right template from a set of footer html templates.
<div ng-show="$scope.template == 'footer_one'" >
<div ng-include src="'/partials/footer_one.html'"></div>
</div>
<div ng-show="$scope.template == 'footer_two'" >
<div ng-include src="'/partials/footer_two.html'"></div>
</div>
You'd need to programmatically set the $scope.template variable based on some condition in the controller.

How to load content from all tabs from angular ui tabset even when not active

I've been stuck on this for a while, I hope someone can help.
I have four different controllers and templates. One controller has a heading, a submit button, and 3 tabs in it.For the purpose of this question I will call it the parent controller, the module for this parent controller is personManagement
The tabset in parent.html looks like this:
<div>
<h3> Main page title </h3>
<div>
<tabset>
<tab role="tab" heading="General Info" ui-sref="tab1"></tab>
<tab role="tab" heading="Detailed Info" ui-sref="tab1"></tab>
<tab role="tab" heading="Related Info" ui-sref="tab1"></tab>
</tabset>
<div ui-view></div>
</div
Each of the controller uses $stateprovider
I am able to load each html tab correctly and switch around between tabs fine either manually in each tab controller using $state.go or ui-sref. However each tab has form data in it with some of the fields being required fields and I need to be able to verify that the required fields are all filled across the three different tabs before the Submit button is enabled in the parent html.
In the html for each tab, I use ng-init on each required field input box and call a function checkAllRequiredFields in the controller for that tab which checks whether all the required fields are filled. However, it will only check the ones in the current tab.
I tried moving the checkAllRequiredFields function to the parent controller and then used a factory like this
angular.module('myApp.personManagement').factory('RequiredFieldsFactory', function () {
return { AllRequiredFields: [], checkAllRequiredFields: '' };
}); //this code is in the parent controller. The definition for the `checkAllRequiredFields` function is also declared in the parent controller..
Each time an input box is modified, the function in the parent controller is called but it always only knows about the required fields for the current tab. I am pretty sure it is because the other tabs are hidden until you navigate to those tabs and so the DOM only has the data from the current tab.
Is there a way around this so I can verify that all required field across all 3 tabs are filled so that the Submit button can be enabled?

Open up content in another div with AngularJS

I have some content I wish to load into a div using Angular. For example:
<div class="number-and-description" ng-controller="thingDetails">
<div class="number" ng-click="loadContent(thing.number, thing.description, thing.status)" ng-cloak>{{ thing.number }}</div>
<p class="description" ng-click="loadContent(thing.number, thing.description, thing.status)" ng-cloak>{{ thing.description }}</p>
</div>
I have another view outside of this div like this:
<!-- Main Content Area -->
<section class="main-content group" ng-controller="thingDetails">
<h1 ng-cloak>{{ thingNumber }}</h1>
<div ng-cloak>{{ thingDescription }}</div>
<div ng-cloak>{{ thingStatus }}</div>
</section>
In my app.js file, I have this code:
thingApp.controller('thingDetails', ["$scope", function($scope) {
$scope.loadContent = function(number, description, status) {
$scope.thingNumber = number;
$scope.thingDescription = description;
$scope.thingStatus = status;
return $scope;
};
}]);
My question is, why doesn't the main content area div update when these values are changed? Right now it remains blank. thing.number, thing.description loads fine in the div I am clicking on - this data is coming from hardcoded JSON which appears fine. The issue is that when I click on the div, the OTHER main content div doesn't show/update the data. Could someone please help me out? Note that when I console.log(number) or console.log(description) etc. I can see the correct values, so they are being passed correctly to the loadContent() function.
You have two separate instances of controller thingDetails , not one. They each have their own scope and do not share anything directly. A simple way to see this is put a console.log() in your controller and you will see it run each time the controller initializes
For controllers to share data you use a service and inject that service wherever it needs to be accessed.
Alternatively perhaps you don't need two instances and can wrap them in one scope in your view
You are basically creating two controllers here with two different scopes. Thus, in the outer div, $scope.thingNumber, description, etc. are undefined as you are only changing the values on the inner scope.
A quick but messy fix to this problem would be to change your $scope's to $rootScopes. The proper way to do this though is via services/factories.

Semantic UI Meteor modal initalization

I'm running Meteor with Semantic UI as a framework .
I've got my main page on which I load X detail cards who all come from the same data source. All the detail cards have buttons, for example trash to remove the card.
I'm confirming actions on the buttons through modals.
I've got all of my modals in a separate template called modals.
From my main page I load my modals:
{{>modals}}
Inside my modals template I've got:
<template name="modals">
<div id="takeModal" class="ui modal">
{{#with data}}
<div class="ui header">
//HEADER
</div>
<div class="ui content">
// DATA USAGE IN TEMPLATE
{{city}}</td>
</div>
</div>
</template>
Above example is commented with // and just a fraction of the real thing.
The problem I'm running into is that I'm using the buttons on said card to call for the modal. The button eventhandler looks like:
Template.availablCard.events({
'click #checkmark': function () {
Session.set('data', this);
$('#takeModal').modal('show');
}
....
and the modal template has a helper:
Template.modals.helpers({
data: function () {
return Session.get('data');
}});
The problem I am facing is that the modals never function properly the first time because a click hasn't been registered yet and Session.data hasn't been set yet.
Is there a way to initialize the modals so they get loaded into the DOM, but still give them a data context?
ps. I've chosen this approach so I don't have to give every card it's own modal.

viewContentLoaded - Without duplicating code per each controller - AngularJS

Hey all I'm trying to get a feel for angular and have ran into a little snag.
I have a container structure like the following:
<div class="main-container" ng-view>
<!-- The below divs are constantly being
reloaded based on the current URL and it's associated view -->
<div class="left-col">
</div>
<div class="right-col">
</div>
</div>
Before I implemented Angular I just had a simple script that would check the height of the window and set the height of the left column and right column divs accordingly.
With angular there is probably a better way to do this then attaching an event function to the window object. Basically I want to fire a function everytime a new view is rendered but not duplicate the below code in all of my angular controllers like so:
$scope.$on('$viewContentLoaded', setColumnHeight);
Any help would be appreciated. Thanks!
I've solved this problem in my app by having a root "Application Controller" at the top of the DOM tree. For example:
<body ng-controller='applicationController'>
...
<div class="ng-view"></div>
...
</body>
applicationController is always there, and can set up bindings on its scope when it is created.
How about putting that event listener on the root scope:
$rootScope.$on('$viewContentLoaded', setColumnHeight);
You could use something like this:
<div class="main-container" ng-view>
{{ setColumnHeight() }}
<!-- The below divs are constantly being
reloaded based on the current URL and it's associated view -->
<div class="left-col">
</div>
<div class="right-col">
</div>
</div>
and it will check the height every time a render is made, however, this seems to be a bit over processing.
The best approach would be to only update the height from both columns when the height of one of them changes. For that you could use DOM Mutation Observers, however they are not yet available on all browsers. If that's not a problem for you, check the mutation-summary lib.
If you are using jQuery you can also try this: https://github.com/jqui-dot-net/jQuery-mutate (examples here).

Categories

Resources