Scope array is not affected when bluring - angularjs

Having the following HTML:
<div ng-repeat="phone in user.phones">
<input type='text' value='{{phone}}' ng-model="phone" ng-blur="phoneBlur()"/>
</div>
and the following code:
$scope.phoneBlur = function() {
const newPhones = $scope.user.phones.filter((item) => item != '');
if(newPhones.length !== $scope.user.phones.length) {
$scope.user.phones = newPhones;
}
}
The if statement is never called. The idea is removing blank phones from the array and their inputs.

Related

computed setter not working with v-model inside v-for loop

I have an array with multiple input-fields with v-model inside a v-for loop. One of these the fields for each array-item contains a price. In the object this price should be in cents, but in the input fields it should be in whole euro's.
I made a computed property to basically devide (getter) and multiple (setter) the price by 100.
The getter works fine, but the setter seems to not do anything.
This is my (simplified) code:
<template>
<div>
<div v-for="(item, index) in geleverd" :key="index">
<div>
<label for="Omschrijving">Omschrijving</label>
<input v-model="item.naam" type="text" name="Omschrijving">
</div>
<div>
<label for="Aantal">Aantal</label>
<input
v-model="item.aantal"
type="number"
name="Aantal"
min="0"
step="1"
>
</div>
<div>
<label for="Prijs">Prijs</label>
<input
v-model="item.prijs"
type="number"
name="Prijs"
min="0"
step=".50"
>
</div>
<div>
<label for="Btw">Btw</label>
<input
v-model="item.btw"
type="number"
name="Btw"
min="0"
step="1"
>
</div>
</div>
</div>
</template>
<script>
export default {
computed: {
factuur () {
const foundFactuur = this.$store.state.facturen.list.find((factuur) => {
return factuur.info.id === this.$route.params.factuur
})
if (foundFactuur) {
return JSON.parse(JSON.stringify(foundFactuur))
} else {
return JSON.parse(JSON.stringify(this.$store.state.facturen.empty))
}
},
geleverd: {
get () {
return this.factuur.geleverd.map((item) => {
const newPrijs = (item.prijs / 100).toFixed(2)
return {
aantal: item.aantal,
naam: item.naam,
prijs: newPrijs,
btw: item.btw
}
})
},
set (newArray) {
const newGeleverd = newArray.map((item) => {
const newPrijs = (item.prijs * 100).toFixed(0)
return {
aantal: item.aantal,
naam: item.naam,
prijs: newPrijs,
btw: item.btw
}
})
this.factuur.geleverd = newGeleverd
}
}
}
}
</script>
Is there something wrong with my code, or is this just not possible in Vue?
I know I can probably achieve my goal by using a method which gets called #input, but a computed property seems better suited to me.
I don't really like to set up the computed property for an entire object, since I just have to modify 1 item. Any way to get around this?

How to bind dynamic element to DOM in angularjs 1.6?

I am creating a dynamic report builder which can have multiple rows. These rows are created dynamically based on the field selected. I am appending the dynamic HTML through my js controller but ng-model is not binded to the DOM. I tried adding $compile(element)($scope) but it didnt work. Please find the screenshot shared below.
HTML
<div class="page-content-wrap">
<form name="reportform" class="reportBuilder" ng-submit="getReport(reportform,report)">
<div class="row">
<div class="form-group col-md-4">
<select class="form-control" name="module" id="module"
ng-model="modules"
ng-options="module as module.formname for module in allModules track by module.id"
ng-change="getFields()">
<option value="" class="">Select Module</option>
</select>
</div>
</div>
<div class="dynamic_block">
<div class="row">
<div class="form-group">
<div class="col-md-4">
<select class="form-control field_type"
ng-model="fields[row_count]"
ng-options="moduleField.name as (moduleField.label) for moduleField in moduleFields">
<option value="" class="">Select Fields</option>
</select>
</div>
{{options}}
<div class="col-md-7 field_to_be_added">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<span ng-click="cloneRow()"><i class="fa fa-plus-circle"></i></span>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button class="btn btn-primary" type="submit">Generate Report</button>
</div>
</div>
</form>
</div>
JavaScript
$scope.cloneRow = function() {
$scope.row_count++;
$scope.model_name = 'field_'+$scope.row_count;
var new_html = $('#dynamic_block_fixed').clone();
$('.dynamic_block:last').after(new_html);
$compile(new_html)($scope);
$('.minus-icon').unbind().bind('click',function(item){
$(item.target).closest('div.dynamic_block').remove();
});
$('.field_type').unbind().bind('change',function(item){
var item_id = $(this).val().split(':');
for(fields in $scope.moduleFields){
if(typeof $scope.moduleFields[fields] != 'undefined') {
if($scope.moduleFields[fields]['name'] == item_id[1]){
createFieldOptions($scope.moduleFields[fields],item.target.parentElement);
}
}
}
});
}
function createFieldOptions(field, target) {
for (f in field) {
var name = field['name'];
if (field[f] == 'text') {
var element = `<input class="form-control" dynamic type="text" ng-model="report.${name}"/>`;
} else if (field[f] == 'textarea') {
var element = `<textarea class="form-control" ng-model="report.${name}"></textarea>`;
} else if (field[f] == 'select') {
var options = [];
for (key in $scope.moduleFields) {
var objectValues = $scope.moduleFields[key];
if (objectValues['type'] == 'select' && objectValues['name'] == name) {
options = objectValues['values'];
}
}
var element = `<select class="form-control" ng-model="report.${name}"><option>Select</option>`;
options.forEach(function(object) {
element += `<option value="${object.value}">${object.label}</option>`;
});
element += "</select>";
} else if (field[f] == 'checkbox-group') {
var checkoptions = [];
for (key in $scope.moduleFields) {
var objectValues = $scope.moduleFields[key];
if (objectValues['type'] == 'checkbox-group' && objectValues['name'] == name) {
checkoptions = objectValues['values'];
}
}
var element = "<span>";
checkoptions.forEach(function(object) {
element += `<label class="check"><input type="checkbox" name="${name}" ng-model="report.${name}" value="${object.value}"/>${object.label}</label>`;
});
element += "</span>";
} else if (field[f] == 'date') {
element = `<input type="date" name="${name}" ng-model="report.${name}"/>`;
} else if (field[f] == 'radio-group') {
var radiooptions = [];
for (key in $scope.moduleFields) {
var objectValues = $scope.moduleFields[key];
if (objectValues['type'] == 'radio-group' && objectValues['name'] == name) {
radiooptions = objectValues['values'];
}
}
var element = "<span>";
radiooptions.forEach(function(object) {
element += `<label class="check"><input type="radio" name="${name}" ng-model="report.${name}" value="${object.value}"/>${object.label}</label>`;
});
element += "</span>";
}
}
angular.element(target).next('div.col-md-7').html(element);
//$(target).next('div.col-md-7').html(element);
$compile(element)($scope);
$scope.$apply();
}
Open to alternative approach if any.
It sounds like you're appending the dynamic HTML in the JQuery style, with parent.append(newHTML) kinda thing; That's not great practice in AngularJS, and also when you have to use $compile, you know something's not quite right.
I would recommend structuring your code in directives and showing and hiding each directive via ng-if.
If you give some HTML examples, I could go more in depth

ng model not updating in radio button group with ng-repeat

I am displaying radio buttons based on search result using ng-repeat.
if i select any radio button, its color will change.
actual issue is, when i do second search, list will replace with new list.
but when i select any radion button its color not changed.
View:
<div class="col-md-4 col-sm-6 nl_item" ng-repeat="nomineeMgr in nomineesMgrList track by $index">
<div class="checkbox" ng-class="{'blue1': nomineeMgr.SystemUserId===nomManagerSelectedId}">
<label class="radio-inline">
<input type="radio" value="" name="selectedNomineeMgr{{$index}}"
ng-model="$parent.nomManagerSelectedId" ng-value="{{nomineeMgr.SystemUserId}}" />{{nomineeMgr.SystemUserId===nomManagerSelectedId?"SELECTED"}}
</label>
</div>
</div>
angular controller:
$scope.nomManagerSelectedId = 0;
$scope.searchNomineesManager = function (isValid) {
if (!isValid)
return;
var result = pepsicoService.getPepsicoEmployees($rootScope.UrlProvider.getPepsicoSearchEmployeesUrl, null, $scope.searchNomination.searchNomineMgr).then(function (response) {
if (response.data.success) {
$scope.nomineesMgrList = [];
$scope.nomManagerSelectedId = 0;
$scope.nomineesMgrList = response.data.EmployeeList;
}
else {
$rootScope.showFailureMsg(response.data.errorMessage);
}
});
};
any one have an idea to solve this issue?

Simple check all not working in AngularJS

I am trying to include a check all for my todo list, but once I hit toggleAll() it gets unchecked right away, plus it unchecks whichever one is already checked.
I really couldn't figure out why this behavior, perhaps some other things in the page are interfearing. A simple version of what I have included here is in this jsfiddle http://jsfiddle.net/TKVH6/487/ and it is working.
<section id="main">
<input id="toggle-all" type="checkbox" ng-model="checkAll" ng-click="toggleAll()">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
<li ng-repeat="todo in todos" ng-class="{'completed': todo.isCompleted=='true'}" class="editing">
<div class="view" >
<input class="toggle" type="checkbox" ng-click="complete(todo)" ng-model="todo.isCompleted" ng-checked="todo.isCompleted" ng-true-value="'true'" ng-false-value="'false'">
<label ng-hide="isEditing" ng-dblclick="isEditing = !isEditing">{{todo.title}}</label>
<button class="destroy" ng-click="remove(todo)"></button>
</div>
<input class="edit" ng-show="isEditing" ng-model="todo.title" ng-blur="isEditing = !isEditing;edit(todo);">
</li>
</ul>
</section>
Controller
$scope.toggleAll = function () {
if ($scope.selectedAll) {
$scope.selectedAll = true;
} else {
$scope.selectedAll = false;
}
angular.forEach($scope.todos, function (todo) {
todo.isCompleted = $scope.selectedAll;
});
};
EDIT 1
$scope.toggleAll = function() {
for(i in $scope.todos) {
$scope.todos[i].isCompleted = $scope.checkAll;
}
};
Any help is appreciated.
SOLVED! Treating the boolean as string solved it. That is because the server saves the boolean values as strings.
$scope.toggleAll = function() {
for(i in $scope.todos) {
$scope.todos[i].isCompleted = "" + $scope.checkAll;
}
};
At this point ng-checked="{{todo.isCompleted}} needs to be back since it is not a boolean.

How to change the placeholder in the textbox by changing checkbox using angular?

I am trying to change the placeholder in the textbox by changing the checkbox using angular. I tried fiddle http://jsfiddle.net/d9uc1dxc/5/.
I have the following code:
**SCRIPT**
function TController($scope) {
$scope.placeholder="%";
$scope.formData = {};
$scope.radioChecked = function ()
{
$scope.placeholder="%";
$scope.apply();
}
$scope.radiounChecked = function ()
{
$scope.placeholder="Count";
$scope.apply();
}
}
What I am trying to achieve is (1) if I change to "%" then the textbox placeholder and (2) if I change to "Count" then the textbox placeholder should change to "Count".
Someone please help me in this issue.
please try to use this code
this is the script file
var app = angular.module("TestApp", []);
function TController($scope) {
$scope.placeholder="%";
$scope.formData = {};
$scope.radioChecked = function ()
{
if($scope.placeholder == "%"){
$scope.placeholder = "Count";
}else{
$scope.placeholder = "%";
}
}
}
and here is the html file
<body ng-app="TestApp" ng-controller="TController">
<div class="flw vreq2">
<label>Voting require2</label>
<div class="oneline">
<div class="onoffswitches">
<input type="checkbox" name="onoffswitch" ng-click="radioChecked()" class="onoffswitch-checkbox" id="myonoffswitch7"/>
<label class="onoffswitch-label" for="myonoffswitch7">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</div>
</div>
<div class="per1">
<input type="text" placeholder="{{placeholder}}" ng-model="formData.textInput" />
</div>
</body>
hope you find this useful
you dont need the two functions for checked & unchecked
use ng-change in check box as and add a model to checkbox // model name = onoffswitch
<input type="checkbox" ng-model="onoffswitch" ng-change="radioChecked()" ...
when checkbox checked, onoffswitch model value will be true otherwise false
when changing the checkbox radioChecked() function will invoke
$scope.radioChecked = function ()
{
if($scope.onoffswitch) {
$scope.placeholder="%";
} else {
$scope.placeholder="Count";
}
}
see the demo Plunker

Resources