AngularJS how to re-initialize directive? - javascript

I have a directive in AngularJS which is first initialized by default when the parent controller of it is being loaded.
The directive takes data from remote server using AJAX and implements the data in checkboxes - each checkbox get the clue if its already checked or not.
On first load of this page (controller) and directive, the checkboxes are being checked properly.
When I move to another scope (controller) and then back again to the checkboxes scope, none of them are checked.
Even though the data is being requested again from the remote server using AJAX (I console logged it), those checkboxes are ain't get checked.
Should I re-init the directive?
This is the directive (notice the checked attribute):
<checkbox key="{{num}}" selector="{{category.key}}/{{module.key}}" changefunction="togglePermission"
checked="{{permissions[num] && permissions[num].modules.indexOf(category.key+'/'+module.key)!=-1}}"></checkbox>
and this is the checkbox directive html file:
<div class="form-group" ng-class="{'has-danger': errors[selector].length>0}">
<label class="control control-outline control--checkbox {{selector}}">
<div class="input-group">
<span ng-show="title.length>0">{{title}}</span>
<input type="checkbox"
ng-model="this[key][selector]"
ng-disabled="loading"
ng-click="this[changefunction](key, selector)"
ng-checked="checked"
/>
<span class="control__indicator"></span>
</div>
</label>
<small class="text-danger" ng-show="errors[selector].length>0">{{errors[selector]}}</small>
</div>
A quick explaination: I am sending custom key and selector names, for example:
$scope.teams = {
level: ""
}
So the teams will be the key and the level will be the selector
This is the checkbox component js file:
app.directive("checkbox", ($rootScope, parseService) => {
return {
templateUrl: "/shared/checkbox/checkbox.html",
scope: true,
link: function($scope, element, attrs) {
$scope.key = parseService.parse(attrs.key);
$scope.selector = parseService.parse(attrs.selector);
$scope.changefunction = parseService.parse(attrs.changefunction);
$scope.checked = parseService.parse(attrs.checked);
}
}
});

Related

Cannot interpolate vm.value in template - AngularJS

I am updating and modifying a project using Angular JS 1.2.25.
I have my controller where I have a value called vm.stageValue which is then called in template with an ng-if, so when the vm.stageValue increments it shows different containers. But whhen I define a value on the vm object that I want to interpolate on the template, eg a string that will be used and will not change on the template, I cannot seem to get it display.
This has makes me think I have not set up my controller correctly using the vm method.
It seems weird that I can use the ng-if and call function from the controller using ng-click on the template but I cannot interpolate a string or send it to another child component
Code is below, thank you in advance. Any help would be hugely appreciated
Controller
angular
.module('formModule')
.controller('NewBusinessFormCtrl', [
function() {
let vm = this;
// Methods used in controller
vm.methods = {
incrementStageValue: incrementStageValue,
decrementStageValue: decrementStageValue,
canIncrement: canIncrement,
canDecrement: canDecrement
};
//Initial stage values
vm.stageValue = 1;
vm.maxStageValue = 7;
// This is the string that I want to interpolate below
vm.contactFormCategory = 'New Business';
}
]);
Template of Controller
<div class="new_busines_cf" ng-controller="NewBusinessFormCtrl as vm">
<div class="form_wrapper">
<div ng-if="vm.stageValue == 1">
<input-text
class="form_input"
ng-model="ngModel"
input-text-label="This is the label">
</input-text>
// I want to send the vm.contactFormCategory into the component
// Value is sending but the component display 'vm.contactFormCategory'
// Not the value set in the controller
<form-headline
form-headline-sup-title="vm.contactFormCategory"
form-headline-text="This is a form headline text">
</form-headline>
</div>
// Trying to interpolate value here into template, but nothing display
{{vm.contactFormCategory}}
<div ng-if="vm.stageValue == 2">
<input-text
class="form_input"
ng-model="ngModel"
input-text-label="This is the label of stage 2">
</input-text>
<form-headline
form-headline-sup-title="vm.contactFormCategory"
form-headline-text="This is a form headline text">
</form-headline>
</div>
<button ng-click="vm.methods.incrementStageValue()">Increment Value</button>
<button ng-click="vm.methods.decrementStageValue()">decrement Value</button>
</div>
</div>
** Form Headline **
angular
.module('formModule')
.directive('formHeadline', function() {
return {
restrict: 'E',
templateUrl: '/partials/form/form-headline.component.html',
scope: {
formHeadlineText: '#',
formHeadlineSupTitle: '#'
},
link: function () {
}
};
});
Change your ng-if to
<div ng-if="vm.stageValue === '2'">

Why is my angularjs check-box custom directive not working?

In my app I make frequent use of a checkbox. Given the repetitiveness I wanted to make a custom directive out of it, but when I call the directive in my html it does not check the checkbox. I cannot figure out what I am missing. Any suggestions would be appreciated.
HTML
<div class="col-xs-12 col-sm-9 col-md-9">
<input type="checkbox"
class="form-control"
name="{{attrs.name}}"
id="{{attrs.id}}"
data-ng-model="model">
<label for="{{attrs.id}}">
<span>{{labelText}}</span>
</label>
</div>
JS
(function () {
'use strict';
angular
.module('app.directives')
.directive('ccCheckBox', checkbox);
checkbox.$inject = [];
/* #ngInject */
function checkbox() {
return {
restrict: 'E',
scope: {
model: '=',
labelText: '#'
},
templateUrl: './src/_directives/checkbox.html',
link: CheckBox
};
function CheckBox(scope, attrs){
activate();
function activate(){
scope.attrs = attrs;
}
}
}
})();
Called in my code as
..
<cc-check-box
data-label-text="Test CheckBox Label"
data-name="checkBoxGrp"
data-id="myCheckBox"
data-for="myCheckBox"
data-ng-model="vm.model.myCheckBoxValue">
</cc-check-box>
No errors in the dev tools console.
You cannot set data-ng-model to bind with model attr.
You should use model (as you defined into the isolated scope) or data-model.
<cc-check-box
data-label-text="Test CheckBox Label"
data-name="checkBoxGrp"
data-id="myCheckBox"
data-for="myCheckBox"
data-model="vm.model.myCheckBoxValue"
></cc-check-box>

AngularJS: wait that context is loaded before write HTML

When the input select is loaded in an HTML form, sometimes the data get from the back-end is not ready and the select is displayed without any option selected.
Could be possible to wait that the data is loaded before write the input select in the page?
or there are any other way to select the right option depending on the angular value.
PS. i can't change the data that i get from the back-end and that are una array for the all value and another variable with the selected option. The first one is always loaded correctly but sometimes the second one is empty when i want to select an option.
thanks
I assume you're using asynchronous methods to load the data. In such case, the following should work.
First, have such markup:
<div ng-show="loading">
Loading, please wait...
<!-- can also put gif animation instead -->
</div>
<select ng-hide="loading">...</select>
And in the controller:
$scope.loading = true;
GetData().then(function() {
$scope.loading = false;
}, function() {
$scope.loading = false;
alert('error');
});
This assumes you load the data in a function that returns a Promise, you can of course just put the $scope.loading = false; line in the proper location in your code, after the data is actually loaded.
The effect will be that while $scope.loading is set to true, the user will see the "Loading" message while the drop down is hidden, and when you set it to false, the drop down will become visible while the "Loading" message will become hidden.
Try to get access after event stateChangeSuccess
$scope.$on('$stateChangeSuccess', function() {
(function() {
})();
});
That is how I fix this problem using AngularJS, Angular Resource & Ui-router to display selected object in an entity with Relationship:
Given that we have to entity in a simple relationship:
Class: name(String), level(String). ----> A class in school.
Child: name(String), pseudo(String). ----> A Child.
A child can be in one class at a time and there is many classes in school.
So We can have something like this(a One-To-One):
Class: name(String), level(String). ----> A class in school.
Child: name(String), pseudo(String), class(Class). ----> A Child.
In my Ui-router state I do something like this when editing a Child:
That is the state of the child to edit, when click on a link corresponding to it we query him and use a controller to resolve the entity related to him.
.state('child-edit', {
parent: 'entity',
url: '/child/{id:int}',
views: {
'content#': {
templateUrl: 'path/to/chil/view/child-edit.html',
controller: 'ChildEditController'
}
},
resolve: {
translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
$translatePartialLoader.addPart('child');
return $translate.refresh();
}],
entity: ['$stateParams', 'ChildService', function($stateParams, ChildService) {
// We return the child to edit using a service.
return ChildService.get({id : $stateParams.id});
}]
}
})
That is the controller I use to make this run normally:
angular.module('myApp').controller('ChildEditController',
['$scope', '$stateParams', '$q', 'entity', 'ClassService',
function($scope, $stateParams, $q, entity, ClassService) {
// We get all classes of school here.
$scope.classes = ClassService.query();
// That is the promise of child to edit get from resolve in state.
$scope.childToEdit = entity;
$q.all([$scope.classes.$promise, $scope.childToEdit.$promise]).then(function() {
// When all data are resolved
// In Js two objects with same properties and valyes but different memory allocation are different.
// So I test value of Id before setting the right class of this child and angular will make able to edit
// him in the UI with the ng-model
var classOfChild = $scope.childToEdit.class;
for (var k in $scope.classes) {
if ($scope.classes[k].id === classOfChild.id) {
// We put the same reference of this class: then it will be selected in the UI of select box
$scope.childToEdit.class = $scope.classes[k];
}
}
});
}]);
And the associated UI in HTML:
<!-- The name of Child -->
<div class="form-group">
<div class="col-md-4">
<label for="field_child_name">Name of Child</label>
<input type="text" class="form-control" name="name" id="field_child_name"
ng-model="childToEdit.name"
required />
</div>
</div>
<!-- Selected class of child will be display here with all other classes available -->
<div class="form-group">
<div class="col-md-4">
<label for="field_child_class">Class of Child</label>
<select class="form-control" id="field_child_class" name="class" ng-model="childToEdit.class" ng-options="class as class.name + ' : ' + class.level for class in classes">
<option value=""></option>
</select>
</div>
</div>
Note: Hope it is the same situation where the selected data is not displaying because the references of querying class and property class in child object are different.

How to get parameter on ngClick. And then, triggered the directive to injected dinamically template

I need to inject new template dynamically depending on the value or parameter of radio button.
This is my HTML
<div class="container-fluid" ng-app="rjApp">
<div class="panel-body" ng-controller="mainController">
<input name="penanggung_biaya" type="radio" ng-model="checked" ng-click="broadcast(umum)" class="ace" value="umum"> <!-- I though, umum is the parameter which I want passed through to the Controller -->
<input name="penanggung_biaya" type="radio" ng-model="checked" ng-click="broadcast(instansi)" class="ace" value="instansi">
<example-directive message="message"> </example-directive>
</div>
</div>
and, this is the JS
var rjApp = angular.module('rjApp',[]);
rjApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{::');
$interpolateProvider.endSymbol('::}');
})
//mainCotroller, should be work by ngClick through radio button
function mainController($scope, $rootScope) {
$scope.broadcast = function(event){
console.log(event) //I've been thought, this is the part to passing the parameter of radio button, but not gonna works.
$rootScope.$broadcast('handleBroadcast');
};
}
//the Directive, should be injected dinamically template, depends on ngClick parameter inside radion button
rjApp.directive('exampleDirective', function() {
return {
restrict: 'E',
scope: {
message: '='
},
link: function(scope, elm, attrs) {
scope.$on('handleBroadcast', function(doifq) {
templateUrl= '<?php echo url("registrasi/rawat_jalan/penanggung_biaya/") ?>'+doifq //This is the part to injected the dinamically template. And I've been guess the **doifq**, is the paramter to passing by the mainController
});
},
};
});
Please, somebody help me.
Regards.
In broadcast, you could pass the parameter,
$scope.broadcast = function(event){
console.log(event);
$rootScope.$broadcast('handleBroadcast',event);
};
This way you would be getting doifq value in directive depending on the which radio button is clicked.

How to get ng-repeat radio-button value inside the controller?

I have a form, within there are different input-tags and labels :
form action="">
<div class="fields" data-ng-repeat="option in question.body.options">
<input id="{{option.text}}" type="radio" name="gender" ng-model="demographic_value" ng-value="{{option.text}}">
<label for="{{option.text}}">{{option.text}}</label>
</div>
</form>
I want to access the value of the selected radio button, how is the data binded? Is there any standard-method, or "isChecked" value or something like that?
EDIT: OK, to be more clear: I want to have only the option which is selected. Inside the controller, not in the view.
So i can send the selected value over HTTP to a server.
Click a radio button
do something like var checked = $scope.radiobutton
array.push(checked)
Send over to a server
Use a shared service and inject it to any controllers:
angular.module("yourAppName", []).factory("mySharedService", function(){
var mySharedService = {};
mySharedService.values = {};
mySharedService.setValues = function(params){
mySharedService.values = params;
}
return mySharedService;
});
And after inject it into any controller.
For example:
function MainCtrl($scope, myService) {
$scope.radioButtons= myService.values;
}
function AdditionalCtrl($scope, myService) {
$scope.var= myService.values;
}
EDIT: as for checked/unchecked values:
You can use watcher:
$scope.$watch('question.body.options', function (changedOptions) {
//some actions with changed options
}, true);
UPDATE:
As for your update:
1) You should create watcher, such as above.
2) Into the watcher, when value changes - you initialize necessary service property with your values (call setValue function)
3) You should inject sharedService into another controller, and can get these values from this service.
4) Call $http or $resource method to sent this value on server.
ng-repeat creates its own scope for each item, so you might have problem accessing it. Try put the model in an object from parent scope.
ng-value accepts expression but not like {{expression}}.
http://jsfiddle.net/g8qLY/
HTML:
<form ng-app ng-controller="ctrl" name="inputform">
<label for="{{option}}" ng-repeat="option in options">
{{option}}
<input id="{{option}}" type="radio" name="gender"
ng-model="inputform.radioinput" ng-value="option">
</label>
<div ng-bind-template="Radio Input: {{inputform.radioinput}}"/>
</form>
JS:
function ctrl($scope) {
$scope.options = ['Option1', 'Option2', 'Option3'];
}

Categories

Resources