angularJS, flatten checkboxes list to a CSV - javascript

I have a service, say this one that returns
{"001":"Communication","002":"Developement","003":"Environment","004":"Equipment"}
I need to put this all in checkboxes, users enable-disable them and finally I recuperate the checked values as CSV keys.
Say user checked the "Development" and "Equipment", so I need to obtain in the "002,004" value.
Here is my codepen with some values already checked (002-Developement and 003-Environment):
angular.module('tagsApp', [])
.controller('tagsController', ['$scope', '$http', function ($scope, $http) {
// an initial value is present in the #Tags hidden element
$scope.tags = $('#Tags').val();
var tags = $scope.tags.split(",");
// I need an obj['key']='key' array
$scope.myTagsArray = {};
tags.forEach(function (tag) { $scope.myTagsArray[tag] = tag; });
// get all possible values
$http.get("http://www.mocky.io/v2/597866a7130000d704c0fed3")
.then(function (response) {
$scope.allTags = response.data;
});
$scope.change = function (myTagsArray) {
console.log("myTagsArray: '" + Object.values($scope.myTagsArray).join(",") + "' !");
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="tagsApp">
<label>Tags</label>
<div ng-controller="tagsController">
<input type="hidden" id="Tags" value="002,003"/>
<div ng-cloak ng-repeat="(key, value) in allTags">
<label for="tag_{{key}}">
<input type="checkbox"
id="tag_{{key}}"
ng-model="tagsArray['{{key}}']"
ng-true-value="'{{key}}'"
ng-false-value=""
ng-change="change(tagsArray)" />
{{value}}
</label>
</div>
</div>
</div>
However all that code does not really work. Where is the problem?

You can try the below code if you want the corresponding keys to be saved on checking
angular.module("tagsApp", []).controller("tagsController", [
"$scope",
"$http",
function($scope, $http) {
// get all possible values
$scope.allTags = {
"001": "Communication",
"002": "Developement",
"003": "Environment",
"004": "Equipment"
};
$scope.hidval="002,003";
$scope.checked = [];
$scope.tags = [];
$scope.keys = [];
$scope.tags = $scope.hidval.split(",");
$scope.tags.forEach(function(tag) {
$scope.checked[tag] = true;
$scope.keys.push(tag);
});
$scope.change = function(mykey) {
var ind = $scope.keys.indexOf(mykey);
if ($scope.checked[mykey]) {
$scope.checked[mykey] = false;
$scope.keys.splice(ind, 1);
} else {
$scope.checked[mykey] = true;
$scope.keys.push(mykey);
}
var result=$scope.keys.join();
console.log(result);
$scope.hidval=result;
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="tagsApp">
<label>Tags</label>
<div ng-controller="tagsController">
<input type="hidden" id="Tags" ng-model="hidval"/>{{hidval}}
<div ng-cloak ng-repeat="(key, value) in allTags">
<label for="tag_{{key}}">
<input type="checkbox"
id="tag_{{key}}"
ng-checked="checked[key]"
ng-click="change(key)"/>
{{value}}
</label>
</div>
</div>
</div>

Based on the Vivz answer (thanks a lot for the effort), here is the working solution
angular.module("tagsApp", []).controller("tagsController", [
"$scope",
function($scope) {
// get all possible values
$scope.allTags = {
"001": "Communication",
"002": "Developement",
"003": "Environment",
"004": "Equipment"
};
$scope.selectedTags = $("#Tags").val().split(",");
$scope.tagsArray = {};
// init all with "false"
Object.keys($scope.allTags).forEach(function(tag) { $scope.tagsArray[tag] = ""; });
// check pre-selected from hidden #Tags
$scope.selectedTags.forEach(function(tag) { $scope.tagsArray[tag] = tag; });
$scope.change = function(mykey) {
var result = Object.values($scope.tagsArray)
.filter(function(o){return o;})
.join(); // remove the empty values in array
$("#Tags").val(result); // update the hidden #Tags
console.log(result);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="tagsApp">
<label>Tags</label>
<div ng-controller="tagsController">
<input type="hidden" id="Tags" value="002,003"/>
<div ng-cloak ng-repeat="(key, value) in allTags">
<label for="tag_{{key}}">
<input type="checkbox"
id="tag_{{key}}"
ng-model="tagsArray[key]"
ng-true-value="{{key}}"
ng-false-value=""
ng-change="change(key)" />
{{value}}
</label>
</div>
</div>
</div>

Related

Use $scope function on input type checkbox with ngClick or ngChecked to dispaly results

I want to show results on clicking checkbox items.
For that I tried with ng-click but it returns results only after it was unchecked rather on checked.
Here is my code:
HTML:
<div class="business-type">
<div class="col-sm-12 filter-wrap-inner">
<label for="rad1" ><input type="checkbox" name="reason-closing" value="Transporter" id="ad_Checkbox1" class="ads_Checkbox" ng-model="isTransporterSelected" ng-change="searchUser()"> Transporter</label>
</div>
<div class="col-sm-12 filter-wrap-inner">
<label for="rad1" ><input type="checkbox" name="reason-closing" value="Broker" id="ad_Checkbox1" class="ads_Checkbox" ng-model="isBrokerSelected" ng-change="searchUser()">Broker</label>
</div>
<div class="col-sm-12 filter-wrap-inner">
<label for="rad1" ><input type="checkbox" name="reason-closing" value="Fleet Owner" id="ad_Checkbox1" class="ads_Checkbox" ng-model="isFleetownerSelected" ng-change="searchUser()">Fleet Owner</label>
</div>
</div>
JS:
$scope.isTransporterSelected = false;
$scope.isBrokerSelected = false;
$scope.isFleetownerSelected = false
$scope.searchUser = function(){
$('.load-board-loader').show();
var i;
var containCount= 41;
var vFromStateId = vToStateId = fromStateId = toStateId = '';
var stateId=[];
var $el=$("#usersearch-origin");
$el.find('option:selected').each(function(){
stateId.push({value:$(this).val(),text:$(this).text()});
});
var originId=[];
var $el=$("#usersearch-source");
$el.find('option:selected').each(function(){
originId.push({value:$(this).val(),text:$(this).text()});
});
for(i=0;i<(stateId.length);i++)
{
if(i==0)
{
fromStateId = stateId[i].value;
}
else{
fromStateId = fromStateId+','+stateId[i].value;
}
}
for(i=0;i<(originId.length);i++)
{
if(i==0)
{
toStateId = originId[i].value;
}
else{
toStateId = toStateId+','+originId[i].value;
}
}
vFromStateId = fromStateId ;
vToStateId = toStateId ;
var data ={
fromStateIds: vFromStateId,
toStateIds: vToStateId,
typeOfBusiness: businessTypeValue,
vehicleClassIds: truckTypeValue,
orgName: '',
}
var url = 'url.com';
//if(vFromStateId != '' || vToStateId != ''){
$.ajax({
url: url,
type: "POST", //Use "PUT" for HTTP PUT methods
dataType: 'json',
data: data,
success:function(response){
if ($scope.isTransporterSelected || $scope.isBrokerSelected || $scope.isFleetownerSelected) {
debugger
$scope.users = response.directory;
for(var j= 0; j<response.directory.length; j++){
}
$scope.$apply();
$('.load-board-loader').hide();
} else {
$scope.users = response.directory;
for(var j= 0; j<response.directory.length; j++){
}
$scope.$apply();
$('.load-board-loader').hide();
}
},
error: function(error){
alert("Sorry , No data available");
}
});
I am updated my code with latest code as per comments below in this question.
Please let me know which part i need to change.
Any help over this will be very much helpful.
You should bind ngModel directive with checkbox then use ngChange which evaluates the given expression when the user changes the input value instead of ngClick
(function(angular) {
'use strict';
angular.module('myApp', [])
.controller('Controller', ['$scope', function($scope) {
$scope.isTransporterSelected = false;
$scope.searchUser = function() {
//For debugging
console.clear();
if ($scope.isTransporterSelected) {
console.log('Transporter selected search student')
} else {
console.log('Transporter deselected donot search student')
}
}
}]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="Controller as nb">
<label><input type="checkbox" ng-model="isTransporterSelected" value="Transporter" ng-change="searchUser()" > Transporter</label>
</div>

how to iterate through checkbox object

I have three checkboxes:-
<label>Type:</label>
<label>one</label>
<input type="checkbox" name="type" ng-model="a.Type[0]"/>
<label>two</label>
<input type="checkbox" name="type" ng-model="a.Type[1]"/>
<label>three</label>
<input type="checkbox" name="type" ng-model="a.Type[2]"/>
These checkboxes are stored in the backend as an array of string.
My value is displaying in:-
<li class="list-group-item"><strong>Type</strong>: <span ng-repeat="values in myArray">{{values}}</span></li>
My directive code is:-
(function () {
'use strict';
angular.module('myApp.components')
.directive('abc', abc);
abc.$inject = ['$http', '$timeout', 'ApiServices'];
function abc($http, $timeout, ApiServices) {
return {
restrict: 'EA',
scope: {
},
link: function (scope, el, attrs) {
scope.a = {};
$('#abc').on('hide.bs.modal', function () {
scope.active = false;
});
$('#abc').on('shown.bs.modal', function () {
scope.active = true;
scope.myArray = [];
scope.iterate = function () {
for (var key in scope.a.Type) {
if (scope.a.Type.hasOwnProperty(key)) {
scope.myArray.push(scope.a.Type[key]);
}
}
};
scope.iterate();
},
templateUrl: ''
};
}
})();
Here what I am trying to do is- I want to iterate through 'Type' checkboxes and pushed the values in 'myArray', and then display only the values.
Probably, my example below is somewhat similar to what you are looking for:
HTML:
<span>Select Type:</span>
<div ng-repeat="type in myArray">
<input type="checkbox" ng-model="type.value" /> {{type.type}}
</div>
<span>Selected Types:</span>
<div ng-repeat="type in myArray">
<span ng-show="type.value"> {{type.type}}</span>
</div>
JS:
$scope.a = {};
$scope.a.Type = ["One","Two","Three"]; // your string array
$scope.myArray = [];
$scope.a.Type.forEach(function(item){
$scope.myArray.push({type: item, value: false }); // create new array to make it selectable via checkbox
});
I guess, you no more need your directive now. The iteration and filtering is done in HTML itself.
I hope this helps.

Uncheck first filter after click in second

I am doing a table, with two filters checkbox. First is "360" - when you click it in table shows only 360, the same works filter "2D" - when you click it in table shows only 2D. I do this in JS, but what i want to do is when you click "360", in table shows only 360, but when you click "2D" at this time "360" is uncheck. I try to do this by radio button, but then my css checkbox don't works.
JSON "datas":
[{"type":"2D"},{"type":"2D"},{"type":"360"},{"type":"2D"},{"type":"360"},{"type":"2D"},{"type":"360"},{"type":"2D"},{"type":"360"},{"type":"2D"}]
My Html:
<div class="form-group" style="display:block;width:40px;padding-left: 5px;float:left;height:70px;">
<input type="checkbox" id='checkbox-360' class='tags-checkbox sr-only' value="" ng-model="type2.type360"><label for='checkbox-360'>
<i class='glyphicon glyphicon-unchecked' style="color:darkgrey;width:2px;font-size:25px;"></i>
<i class='glyphicon glyphicon-check' style="color:cornflowerblue;width:2px;font-size:25px;"></i>
<h4><small>360</small></h4>
</label>
</div>
<div class="form-group" style="display:block;width:40px;padding-left:5px;float:left;height:70px;">
<input type="checkbox" id='checkbox-20' class='tags-checkbox sr-only' value="" ng-model="type1.type2D"><label for='checkbox-20'>
<i class='glyphicon glyphicon-unchecked' style="color:darkgrey;width:2px;font-size:25px;"></i>
<i class='glyphicon glyphicon-check' style="color:cornflowerblue;width:2px;font-size:25px;"></i>
<h4><small>2D</small></h4>
</label>
</div>
<tr ng-repeat="data in datas |TypeFilter360:type2.type360 | TypeFilter2D:type1.type2D>
<td>{{data.type}}</td>
</tr>
CSS :
input[type='checkbox'].tags-checkbox:checked + label > i:first-of-type,
input[type='checkbox'].tags-checkbox + label > i:last-of-type{
display: none;
}
input[type='checkbox'].tags-checkbox:checked + label > i:last-of-type{
display: inline-block;
}
JS
var app = angular.module('app', []);
app.service('service', function($http, $q){
this.getDatas = function () {
var datas = $http.get('datas.json', {cache: false});
return $q.all({datas});
};
});
app.controller('FirstCtrl', function($scope, service, $http) {
var promise = service.getDatas();
promise.then(function (data) {
$scope.datas = data.datas.data;
console.log($scope.datas);
})
})
.filter('TypeFilter2D', function(){
return function(data, type2D){
if (!type2D) return data;
var filtered2D = [];
angular.forEach(data, function(item){
if(type2D == false) {
filtered2D.push(item);
}
else if(type2D == true && item.type == "2D"){
filtered2D.push(item);
}
});
return filtered2D;
};
})
.filter('TypeFilter360', function(){
return function(data, type360){
if (!type360) return data;
var filtered360 = [];
angular.forEach(data, function(item){
if(type360 == false) {
filtered360.push(item);
}
else if(type360 == true && item.type == "360"){
filtered360.push(item);
}
});
return filtered360;
};
})
Well what i want to do - when "360" filter is clicked, and then i click "2D" filter "360" should uncheck.
Thanks for answers in advance!
That behavior can actually be defined in your HTML using:
<input type="radio" name="filterOptions" id="checkbox-360" ... />
...
<input type="radio" name="filterOptions" id="checkbox-20" ... />
https://www.w3schools.com/tags/tag_input.asp
https://docs.angularjs.org/api/ng/input/input%5Bradio%5D
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_radio

How to restrict first character alphabet only for a given input field using angularjs?

I have a text field , <input type="text" placeholder="" class="form-control" ng-model="firstName"> in that text field first character must be alphabet only , when user try to enter first character not a alphabet not accepting.
Generic regex check of first string character.
var testString= "This is testString"
console.log(testString+" - "+alphabeticalFirstChar(testString));
testString= "1This is testString"
console.log(testString+" - "+alphabeticalFirstChar(testString));
testString= "This is testString0"
console.log(testString+" - "+alphabeticalFirstChar(testString));
testString= ""
console.log(testString+" - "+alphabeticalFirstChar(testString));
function alphabeticalFirstChar(str){
if(/^[A-z]+$/.test(str[0]) && !str.length<1)//added check for str not being empty - returns true otherwise
return true;
else
return false;
}
Try the following code:
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function($scope){
$scope.firstName = "";
var regex = /^[A-z]+$/;
$scope.$watch('firstName', function(newValue, oldValue){
if($scope.firstName.length > 0){
if(regex.test(newValue)){
$scope.firstName = oldValue;
}
}
});
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<input type="text" placeholder="" class="form-control" ng-model="firstName">
</div>
var myApp = angular.module('myApp', []);
myApp.controller('controller', function($scope) {
$scope.password;
$scope.check = function () {
if($scope.password != null){
var charArray = $scope.password.split('');
console.log(charArray);
if(/[a-zA-Z\_]$/.test(charArray[0]) && charArray[0] != null) {
return true;
}
else {
return false;
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="controller">
<input type="password" ng-model="password" placeholder="Enter Password"/>
<img src="http://icons.iconarchive.com/icons/custom-icon-design/pretty-office-2/256/success-icon.png" ng-show="check()" width="25" height="25"/>
<img src="https://dialectline.files.wordpress.com/2013/06/sign-error-icon.png" ng-show="!check()" width="25" height="25"/>
</div>
I hope it helps.
In Html
<input type="text" placeholder="" class="form-control" ng-model="firstName" ng-change="checkAlphabet()">
In Controller
$scope.checkAlphabet = function() {
if($scope.firstName.substr(0, 1).match(/[A-Za-z]/) == null)
$scope.firstName = $scope.firstName.substr(1);
}
Working example using $watch using regex as pointed by #Adam
Follow: https://jsfiddle.net/nirus/3Lytwybr/2/
Javascript:
function LoginController($scope) {
$scope.user = {
firstName: ""
};
$scope.$watch('user.firstName', function(){
console.log("changed");
var cache = $scope.user.firstName;
if (!(/^[a-zA-Z]+$/.test($scope.user.firstName[0]))){
$scope.user.firstName = cache.slice(1,cache.length);
console.log("here: "+ cache)
}
})
}
Html:
<div ng-app ng-controller="LoginController">
<div>Hello {{ user.firstName }}</div>
<input ng-model="user.firstName" />
</div>
Note : Avoid using too many watchers as it hampers the performance of the app.
I modified Adam K`s code and translated it into angular.
if(/^[A-z]+$/.test($scope.firstname[0]) == false) {
$scope.firstname = ""; }
Hope it helped.

Push data on array when checkbox is checked and remove data when checkbox is unchecked

I am taking data from table and display as multi check checkboxes.My checkboxes when checked pushes data on array for that particular checkbox.But when unchecked ,the respective data should be removed from the array.How can I achieve this?
HTML:
<div ng-repeat="data in filters.status" >
<label class="Form-label--tick">
<input type="checkbox" value="data.id" id="status" ng-model="status" class="Form-label-checkbox" ng-change="IfCheck(data.id,status)" >
<span class="Form-label-text"> {{data.status}}</span>
</label>
</div>
Javascript:
<script>
$scope.IfCheck = function (data, check) {
if (check) {
status.push(data);
$scope.checkedData[0].status = status;
}
else {
var index = $scope.status.indexOf(data);
$scope.status.splice(index);
}
};
</script>
This can be written as like this:
var app = angular.module('sa', []);
app.controller('FooCtrl', function($scope) {
$scope.ids = [];
$scope.filters = [{
id: 1,
status: false
}, {
id: 2,
status: false
}, {
id: 3,
status: false
}]
$scope.IfCheck = function(id, check) {
if (check) {
$scope.ids.push(id);
} else {
var index = $scope.ids.indexOf(id);
$scope.ids.splice(index, 1);
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="sa" ng-controller="FooCtrl">
<div ng-repeat="data in filters">
<label class="Form-label--tick">
<input type="checkbox" value="data.id" id="status" ng-model="data.status" class="Form-label-checkbox" ng-change="IfCheck(data.id, data.status)">
<span class="Form-label-text"> {{data.status}}</span>
</label>
</div>
Selected ids: {{ids}}
</div>
You can utilize the ng-model to see if the input is checked or unchecked. Note that I simplified the code, so you will need to add in your various attributes and logic to what's below:
HTML:
<input type="checkbox" ng-model="isChecked" ng-change="IfCheck()">
JS:
$scope.isChecked = false;
$scope.IfCheck = function () {
if ($scope.isChecked === true) {
// checked
} else {
// unchecked
}
};
This is the example plnkr for a checkbox input with ng-model that is on the Angular documentation.
For multiple checkboxes, you will need to track something like isChecked for each checkbox.

Categories