I am using selectboxit plugin for the selection list on my angularJS page an have bind the "ng-change" event on it. But unfortunately, it is not giving me the data on change.
index.html
<select data-ng-model="object.word" ng-change="test(object.word)" id="blog-cat">
<option value="" selected="selected">Select...</option>
<option ng-hide="item.name == ''" ng-repeat="item in businessParentItems track by $index" value="{{item.term_id}}" item-business-directive>{{item.name}}</option>
</select>
{{object.word}}
testCtrl.js
$scope.test = function(test) {
console.log('got it!');
}
directive.js
resource_app.directive('itemBusinessDirective', function () {
return function (scope, element, attrs) {
if (scope.$last === true) {
$('.resources-search-bar .container .select-part select').selectBoxIt();
}
};
});
Please help with this to render the ng-model value on change of selection list.
Related
I select element bound with a list using ng-options. I have a custom directive which adds validation directive to the select element. This custom directive compiles the select element. After compiling the select element, the options are duplicated. Is there a way to stop the duplication or clear them before compiling atleast ?
In the below code, metadata is a custom directive. In that directive, I have the compile($el)($scope) line. After executing this line, select becomes like below
Please select gender
Male
Female
Male
Female
function ($scope, $el, $attr, $ngModel) {
if (!$ngModel) {
return;
}
var elementMetadata = JSON.parse($attr.metadata);
angular.forEach(elementMetadata.validators,
function (item) {
$el.attr(item.name, item.value);
});
$el.removeAttr('metadata');
$compile($el)($scope);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<select name="gender" id="lstGender" ng-options="gender for gender in genderList track by gender" ng-model="fields.gender" metadata="{{template.gender}}">
<option value="">Please select gender</option>
</select>
Move the compiling select element to last function of compiling to execute by using post
pre: function(scope, element) {
scope.values = [ 'male', 'female' ];
},
post: function() {
$compile(tElement)(scope);
}
codepen- https://codepen.io/nagasai/pen/MQQLbB
I am trying to perform a case-insensitive bind of an ng-model to a dynamic select drop-down using AngularJS.
by going through various other relavent answers from stack over flow, i have come up with something like below on the view , here caseinsensitive-options is an directive which i have come up with referencing the following solution
AngularJS case-insensitive binding to a static select drop-down
HTML:
<select id="dcName" caseinsensitive-options="" ng-model="DC.name" class="form-control">
<option value="">--- Please Select ---</option>
<option ng-repeat="dataCenter in inventoryDataCenters" value="{{dataCenter}}">{{dataCenter}}</option>
</select>
js directive code :
app.directive('caseinsensitiveOptions', function() {
return {
restrict: 'A',
require: ['ngModel', 'select'],
link: function(scope, el, attrs, ctrls) {
var ngModel = ctrls[0];
ngModel.$formatters.push(function(value) {
var option = [].filter.call(el.children(), function(option) {
return option.value.toUpperCase() === value.toUpperCase()
})[0];
return option ? option.value : value
});
}
}
});
The expected result is
when i pass something like this for
$scope.inventoryDataCenters = ["TEST1","test2",teST3]; and ng-model for DC.name has value TesT1.
The drop down should show TEST1 by doing case insensitive binding. That doesnt happen now. The above solution works perfect when we have static drop down.
things to be considered is that the select is inside a div which ng-repeat as shown below
ng-repeat="DC in workflowData.project_data.service_info.variables.service_data['data-center']"
and ng-model for select DC.name is derived from the above array DC.
check this URL for binding based on case insensitive value
https://jsfiddle.net/dwd2du17/6/
<div ng-app="module" ng-controller="controller as ctrl">
<select id="animal" ng-model="ctrl.animal">
<option value="">--- Select ---</option>
<option value="CaT">Cat</option>
<option value="DOg">Dog</option>
</select>
{{ctrl.animal}}
</div>
var appForm = angular.module('module', [])
.controller('controller', function($scope) {
});
I am exploring advanced features in AngularJS such as custom directives. I want to have a textbox which by using custom directive should allow either numbers only or text only depending upon the value chosen by the user from a dropdown box. I have managed to create a custom directive which allows numbers only based upon AngularJs Custom Directive fails the text box validation . I am not sure how to apply a custom directive dynamically to the same textbox. I have create another custom directive which allows text only, but not sure how to replace the number only directive with the text only directive dynamically.
<body>
<div ng-app="TextboxExample" ng-controller="ExampleController">
<form name="shippingForm" novalidate>
<select id="textBoxOptions" >
<option value="number" selected="selected">Numbers Only</option>
<option value="text">Text Only</option>
<option value="special">Special Characters</option>
<option value="any">Any Value</option>
</select>
<input id="customTextBox" unbindable number-only-input type="text" name="name" ng-model="testvalue.number" required />
<span class="error" ng-show="shippingForm.name.$error.required">
Please enter a value
</span>
</form>
</div>
<script src="scripts/angular.js"></script>
<script src="scripts/jquery.min.js"></script>
<script>
$("select").change(function () {
var selected = $("#textBoxOptions").val();
$('#customTextBox').attr("ng-model", selected);
});
</script>
<script>
angular.module('TextboxExample', [])
.controller('ExampleController', ['$scope', function ($scope) {
$scope.testvalue = { number: 1, validity: true };
}])
.directive('numberOnlyInput', ['$compile', function ($compile) {
return {
link: function (scope, element, attrs) {
var watchMe = attrs["ngModel"];
scope.$watch(watchMe, function (newValue, oldValue) {
if (newValue == undefined || newValue == null || newValue == "") {
return;
} else if (isNaN(newValue)) {
var myVal = watchMe.split(".");
switch (myVal.length) {
case 1:
scope[myVal[0]] = oldValue;
break;
case 2:
scope[myVal[0]][myVal[1]] = oldValue;
}
}
$compile(element)(scope);
});
}
};
}]);
</script>
When I change the value in the dropdown box, it correctly changes the ng-model on customTextBox as checked by inspect element. However, I am not sure how to create and apply multiple directives. Thanks
There are several possibilities. You can switch directive atttibute or whole elements:
<input {{ yourmode ? number-directive : text-directive }} ng-model="data">
or
<input ng-show="yourmode" number-directive ng-model="data">
<input ng-show="!yourmode" text-directive ng-model="data">
or you change the mode with dynamic directive attributes
<input directive-data="yourmode" my-input-directive ng-model="data">
Here's a general idea of what I am doing:
<html ng-app="myapp">
<head>...</head>
<body>
<select class="form-control" ng-model="change_group" change-group>
<!-- options loaded in from Symfony/twig -->
<option value='0'>lala</option>
<option value='1'>bla</option>
</select>
<div ng-view></div>
</body>
</html>
When that all loads, the directive seems to work, and I can get it to trigger whenever the select is changed; but it's creating an empty option, and I can't seem to get it to pre-select an existing option, instead of it generating an empty one and having that be default.
myapp.directive('changeGroup', function() {
return {
restrict: 'A',
require: "ngModel",
scope: { },
controller: function($scope) {
$scope.change_group = 0;
},
link: function(scope, element, attrs, ngModel) {
ngModel.$viewChangeListeners.push(function() {
console.log('changed');
});
}
};
});
When I load the page, the desired option (0) flickers for a split second and then goes back to the empty option.
This is what the select looks like, after angular inserts that empty option:
<select class="form-control ng-pristine ng-valid ng-isolate-scope ng-touched" ng-model="change_group" change-group="">
<option value="? undefined:undefined ?"></option>
<option value="0">Public</option>
<option value="1">xil3</option>
</select>
Initialize to a string; not a number.
Also use no scope; not isolate scope.
angular.module("app",[]).directive('changeGroup', function() {
return {
restrict: 'A',
require: "ngModel",
//Do not use isolate scope
//scope: {},
controller: function($scope,$element) {
//Initialize to string
$scope.change_group = '1';
//Not to a number
//$scope.change_group = 1;
},
link: function(scope, element, attrs, ngModel) {
ngModel.$viewChangeListeners.push(function() {
console.log('changed');
});
}
};
});
The DEMO on JSFiddle.
Remove the scope: {} as that creates a new isolate scope and I think you are losing your change_group scope variable.
This question my seems silly to you but i just want to know that is it possible to show ionic loader in between the process of rendering data in dropdown by ng-repeat.I goggled and found two directives one is for after-render and other is for on-finish-render both works good but i am really confused that how can i show and hide my ionic loader during this whole process.
here is some of my code :-
<label class="item item-input"> <select class="input-select"
ng-model="user.country.value"
ng-change="selectedCountry(user.country.value)">
<option ng-selected="country.value==user.country.value"
ng-repeat="country in results" value="{{country.value}}">
{{country.name}}</option>
<option value="" disabled hidden>{{'checkoutPage.country' |
translate}}</option>
</select>
</label>
<label class="item item-input" ng-if="showDropDownInStateLabel()">
<select class="input-select" ng-model="userState.states.region_id"
ng-change="selectedState(userState.states.region_id)">
<option ng-selected="states.region_id==userState.states.region_id" ng-repeat="states in StatesArray" on-finish-render="ngRepeatFinished"
value="{{states}}">{{states.name}}</option>
<option value="" disabled hidden>{{'checkoutPage.state' |
translate}}</option>
</select>
</label>
here is directive :-
app.directive('onFinishRender', function($timeout) {
return {
restrict : 'A',
link : function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
scope.$emit('ngRepeatFinished');
});
}
}
}
});
here is the listener for event:-
$scope.$on('ngRepeatFinished', function(
ngRepeatFinishedEvent) {
alert("rendering ends here");
});
can any one tell me that how to show loader to user when ng-repeat rendering the data in dropdown.I even try by making two different functions for showloader() and hideloader() . showLoader i call when user select some value in dropdown and hideLoader gets call in $scope.$on function.
Actually i am having two dropdowns one is for countries and other is for their respective states.When user select country that state dropdown got visible to user.this whole process took some time in rendering which make application looks like hanged to user so i just want to display user a loader to avoid this illusion.
here is the function which finds which country have states array and according to which stats dropdown got visible to user :-
$scope.user = {};
$scope.selectedCountry = function(value) {
// alert(value);
$scope.data.region = '';
if (angular.isString(LocalStorage
.getData("StateSelected"))) {
LocalStorage.setData("StateSelected", "");
LocalStorage.setData("Statename", "");
}
if (angular.isString(LocalStorage
.getData("Addressregion"))) {
LocalStorage.setData("Addressregion", "");
}
$scope.user.country_id = value;
LocalStorage.setData("CountrySelected", value);
for ( var c = 0; c < LocalStorage
.getObject("getCountriesresult").length; c++) {
if (value == LocalStorage
.getObject("getCountriesresult")[c].value) {
if (LocalStorage
.getObject("getCountriesresult")[c].state.length > 0) {
shouldShowDropdown = true;
$scope.StatesArray = LocalStorage
.getObject("getCountriesresult")[c].state;
} else {
shouldShowDropdown = false;
}
}
}
}
Any help will be appreciated,
Thanks
This kind of feature should never take so long to execute.
I think you should try to remove the huge amount of LocalStorage access inside loops. From what I saw, you can do everything you want using local variables (in-memory).
$ionicLoading works fine for async calls that take time, like an AJAX call.