problems with ng-show angularjs - angularjs

ng-show did not work clearly for me in angular js.
this is the "loading" div:
<div class="loader" ng-show="vm.loadingNotifications" ng-cloak>loading...</div>
and that's the API call in the controller:
function getNotifications(userId) {
if (vm.generalNotifications.length > 0) {
vm.loadingNotifications = false;
} else {
vm.loadingNotifications = true;
$.ajax({
type: 'GET',
url: AppConfig.apiUrl + 'Notifications/GetAllNotificationsByUserId?userId=' + userId,
success: function (notifications) {
if (notifications) {
$("#all-not").addClass("active");
if (notifications.length > 0) {
let tempNotifications = [];
for (let j = 0; j < notifications.length; j++) {
let element = notifications[j];
let title = getSpecificConst(element.NotificationTitle)
element.NotificationTitle = title;
let text = getSpecificConst(element.NotificationText)
element.NotificationText = text;
tempNotifications.push(element);
}
vm.generalNotifications = sortArray(tempNotifications);
vm.displayedNotifications = sortArray(tempNotifications);
vm.isEmptyNotifications = false;
}
else {
vm.isEmptyNotifications = true;
}
} else {
vm.isEmptyNotifications = true;
}
vm.loadingNotifications = false;
}
});
}
}
the VM loading is updating clearly, but the ng-show stack always in true.

you need to use AngularJS Scope on the controller.
$scope.vm = {
generalNotifications:[],
loadingNotifications: false,
....
};
function getNotifications(userId) {
if ($scope.vm.generalNotifications.length > 0) {
$scope.vm.loadingNotifications = false;
} else {
$scope.vm.loadingNotifications = true;
.....
}

Related

Rewriting ng-options with ng-repeat so it works with md-select

I am trying to transform a Bootstrap select field into Angular Material, but am having difficulty getting the code to work with ng-repeat, instead of ng-options. The original code looks like this:
<select name="{{field.name}}" ng-model="fieldValue" ng-model-options="{getterSetter: true}" sn-select-width="auto" ng-disabled="field.isReadonly()" ng-options="c.value as c.label for c in field.choices track by c.value">
The new AngularJS Material html code looks like this:
<md-select name="{{field.name}}" ng-model="fieldValue" ng-disabled="field.isReadonly()">
<md-option ng-value="c.value" ng-repeat="c in field.choices | filter:searchTerm track by c.value">{{c.label}}</md-option>
</md-select>
The selected item from md-select won't save in the back-end table. What am I missing here? I am pretty sure not being able to use ng-options is causing this issue, but how do I fix it with ng-repeat?
UPDATE: The rest of the out of the box directive code is below for reference.
link: function(scope, element, attrs, ngModel) {
scope.clearSearchTerm = function() {
scope.searchTerm = '';
};
var g_form = scope.getGlideForm();
var field = scope.field;
var fieldOptions;
var isOpen = false;
scope.fieldValue = function() {
return field.value;
};
g_form.$private.events.on('change', function(fieldName, oldValue, newValue) {
if (fieldName == field.name) {} else if (fieldName == field.dependentField) {
field.dependentValue = newValue;
refreshChoiceList();
} else if (typeof field.variable_name !== 'undefined' && field.reference_qual && isRefQualElement(fieldName)) {
refreshReferenceChoices();
}
});
function isRefQualElement(fieldName) {
var refQualElements = [];
if (field.attributes && field.attributes.indexOf('ref_qual_elements') > -1) {
var attributes = spUtil.parseAttributes(field.attributes);
refQualElements = attributes['ref_qual_elements'].split(',');
}
return field.reference_qual.indexOf(fieldName) != -1 || refQualElements.indexOf(fieldName) != -1;
}
function refreshChoiceList() {
var params = {};
params.table = g_form.getTableName();
params.field = field.name;
params.sysparm_dependent_value = field.dependentValue;
var url = urlTools.getURL('choice_list_data', params);
return $http.get(url).success(function(data) {
field.choices = [];
angular.forEach(data.items, function(item) {
field.choices.push(item);
});
selectValueOrNone();
});
}
function selectValueOrNone() {
var hasSelectedValue = false;
angular.forEach(field.choices, function(c) {
if (field.value == c.value)
hasSelectedValue = true;
});
if (!hasSelectedValue && field.choices.length > 0) {
g_form.setValue(field.name, field.choices[0].value, field.choices[0].label);
}
}
function refreshReferenceChoices() {
var params = [];
params['qualifier'] = field.reference_qual;
params['table'] = field.lookup_table;
params['sysparm_include_variables'] = true;
params['variable_ids'] = field.sys_id;
var getFieldSequence = g_form.$private.options('getFieldSequence');
if (getFieldSequence) {
params['variable_sequence1'] = getFieldSequence();
}
var itemSysId = g_form.$private.options('itemSysId');
params['sysparm_id'] = itemSysId;
var getFieldParams = g_form.$private.options('getFieldParams');
if (getFieldParams) {
angular.extend(params, getFieldParams());
}
var url = urlTools.getURL('sp_ref_list_data', params);
return $http.get(url).success(function(data) {
field.choices = [];
angular.forEach(data.items, function(item) {
item.label = item.$$displayValue;
item.value = item.sys_id;
field.choices.push(item);
});
selectValueOrNone();
});
}
var pcTimeout;
g_form.$private.events.on('propertyChange', function(type, fieldName, propertyName) {
if (fieldName != field.name)
return;
if (propertyName == "optionStack") {
$timeout.cancel(pcTimeout);
pcTimeout = $timeout(function() {
field.choices = applyOptionStack(fieldOptions, field.optionStack);
selectValueOrNone();
}, 35);
}
});
setDefaultOptions();
if (field.choices) {
setChoiceOptions(field.choices);
}
selectValueOrNone();
function setDefaultOptions() {
setChoiceOptions([{
value: scope.field.value,
label: scope.field.displayValue || scope.field.placeholder
}]);
}
function setChoiceOptions(options) {
if (options) {
options.forEach(function(option) {
option.value = String(option.value);
});
}
fieldOptions = options;
scope.options = applyOptionStack(options, scope.field.optionStack);
}
function applyOptionStack(options, optionStack) {
if (!optionStack || optionStack.length == 0) {
return options;
}
var newOptions = angular.copy(options);
if (!newOptions) {
newOptions = [];
}
optionStack.forEach(function(item) {
switch (item.operation) {
case 'add':
for (var o in newOptions) {
if (newOptions[o].label == item.label)
return;
}
var newOption = {
label: item.label,
value: item.value
};
if (typeof item.index === 'undefined') {
newOptions.push(newOption);
} else {
newOptions.splice(item.index, 0, newOption);
}
break;
case 'remove':
var itemValue = String(item.value);
for (var i = 0, iM = newOptions.length; i < iM; i++) {
var optionValue = String(newOptions[i].value);
if (optionValue !== itemValue) {
continue;
}
newOptions.splice(i, 1);
break;
}
break;
case 'clear':
newOptions = [];
break;
default:
}
});
return newOptions;
}
}
};
}

How do I optimize filtering in AngularJS?

I have here a filter for AngularJS. Is there any better way for this?
return function (data, selected) {
var result = [];
if (selected[0] == 'All Types') {
result = data;
}
else {
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < selected.length; j++) {
if (data[i].Type == selected[j]) {
result.push(data[i]);
}
}
}
}
return result;
};
return function (data, selected) {
var result = [];
if (selected[0] == 'All Types') {
result = data;
}
else {
result=data.filter(x=>selected.indexOf(x.Type)>-1);
}
return result;
};
Obviously this is using lodash, but native methods can be substituted:
return (data, selected) => {
return
_.first(selected) === 'All Types' ? data :
_.reduce(data, (sum, value, key) => {
if (_.includes(selected, value.Type)) {
sum.push(value);
}
return sum;
}, []);
}
Use data for selected value. I am assuming selected value is in data[i].selected.
return function (data) {
var result = [];
if (data[0].selected == 'All Types') {
result = data;
}
else {
for (var i = 0; i < data.length; i++) {
if (data[i].Type == data[i].selected) {
result.push(data[i]);
}
}
}
return result;
};
We can use filters
return function (data) {
if (data[0].selected == 'All Types') {
return data;
}
else {
return data.filter(function (item) {
return item.Type == item.selected;
});
}
};

AngularJS : why is searching not working properly?

I am trying to search text on table using angular ..I am able to search text in table .But my search works when I press enter or “search button” .Example when I write “Active” it not show the result but when I press enter or press search button it show the output .can we do the like search like autocomplete .Example when I press “a’ it show all item which start from “a” .Then if user write “ac” then show “ac” value ..same like that .when user write “active “ it show rows which have “active” without using search button or enter .can we make add filter so that it works properly ?
here is my code
$scope.searchInvoices = function(evt, queryval) {
$scope.haveNorecordFound = true;
if (typeof queryval != "undefined" && queryval.length === 0 || evt.keyCode === 13 || evt.type === 'click') {
if (typeof queryval == "undefined" || queryval.length === 0) {
console.log("if===")
isfilterOccured = false;
$scope.tasklist_records = $scope.total_tasklist_records;
$scope.totalNumberOfrecord = $scope.tasklist_records.length + " records found."
} else {
console.log("esle===")
var recordset = $scope.serachObject;
results = [];
var recordsetLength = recordset.length;
var searchVal = queryval.toLowerCase();
var i, j;
for (i = 0; i < recordsetLength; i++) {
var record = recordset[i].columns;
for (j = 0; j < record.length; j++) {
if (record[j].value != null) {
var invoice = record[j].value.toLowerCase();
if (invoice.indexOf(searchVal) >= 0) {
results.push(recordset[i]);
}
}
}
}
var nameOrPathValues = results.map(function(o) {
var result = {};
o.columns.forEach(function(c) {
result[c.fieldNameOrPath] = c.value;
});
return result;
});
console.log("serach");
console.log(nameOrPathValues);
var objectarray = nameOrPathValues.map(function(o) {
var result = {};
collectNameOrPath.forEach(function(name) {
result[name] = o[name];
});
return result;
});
isfilterOccured = true;
$scope.tasklist_records = objectarray;
if ($scope.tasklist_records.length == 0) {
$scope.haveNorecordFound = false;
} else {
$scope.totalNumberOfrecord = $scope.tasklist_records.length + " records found."
}
}
}
};
After debugging in code, I found that you're biding function on either enter button press or search click. That's why it was not working on ng-keyup. Please replace your function from below code.
$scope.searchInvoices = function(evt, queryval) {
console.log(queryval)
$scope.haveNorecordFound = true;
var recordset = $scope.serachObject;
results = [];
var recordsetLength = recordset.length;
var searchVal = queryval.toLowerCase();
var i, j;
for (i = 0; i < recordsetLength; i++) {
var record = recordset[i].columns;
for (j = 0; j < record.length; j++) {
if (record[j].value != null) {
var invoice = record[j].value.toLowerCase();
if (invoice.indexOf(searchVal) >= 0) {
results.push(recordset[i]);
}
}
}
}
var nameOrPathValues = results.map(function(o) {
var result = {};
o.columns.forEach(function(c) {
result[c.fieldNameOrPath] = c.value;
});
return result;
});
console.log("serach");
console.log(nameOrPathValues);
var objectarray = nameOrPathValues.map(function(o) {
var result = {};
collectNameOrPath.forEach(function(name) {
result[name] = o[name];
});
return result;
});
isfilterOccured = true;
$scope.tasklist_records = objectarray;
if ($scope.tasklist_records.length == 0) {
$scope.haveNorecordFound = false;
} else {
$scope.totalNumberOfrecord = $scope.tasklist_records.length + " records found."
}
};

AngularJS Property Bag

Is there a formal property bag for Angular? I need a way to temporarily store variables and optionally save them between apps.
To save time, I whipped one up. It's here if anyone needs it, however I would love to find one in a framework that is supported by a team:
/**
* Created by Fred Lackey on 4/24/15.
*/
(function (module) {
var propertyBag = function (localStorage) {
var items = [];
var getIndex = function (key) {
if (!key || !key.trim || key.trim().length < 1) { return -1; }
if (items.length < 1) { return -1; }
for (var i = 0; i < items.length; i += 1) {
if (items[i].key.toLowerCase() === key.toLowerCase()) { return i; }
}
return -1;
};
var exists = function (key) {
return (getIndex(key) >= 0);
};
var getItem = function (key) {
var index = getIndex(key);
return (index >= 0) ? items[index] : null;
};
var getValue = function (key) {
var index = getIndex(key);
return (index >= 0) ? items[index].value : null;
};
var putItem = function (key, value) {
if (!key || !key.trim || key.trim().length < 1) { return; }
var index = getIndex(key);
if (index >= 0) {
items[index].value = value;
} else {
items.push({ key: key, value: value });
}
};
var removeItem = function (key) {
var index = getIndex(key);
if (index >= 0) { items.splice(index, 1); }
};
var count = function () {
return items.length;
};
var saveBag = function (key) {
if (!key || !key.trim || key.trim().length < 1) { return; }
localStorage.add(key, items);
};
var loadBag = function (key) {
if (!key || !key.trim || key.trim().length < 1) { return; }
var bag = localStorage.get(key);
if (!bag || !bag.length) { return; }
for (var i = 0; i < bag.length; b += 1) {
if (!bag[i].key || !bag[i].key.trim || bag[i].key.trim().length < 1) { continue; }
putItem(bag[i].key, bag[i].value);
}
localStorage.remove(key);
};
return {
getItem: getItem,
exists: exists,
getValue: getValue,
putItem: putItem,
removeItem: removeItem,
count: count,
save: saveBag,
load: loadBag
};
};
module.factory('propertyBag', propertyBag);
})(angular.module('common'));
Here's the local storage code if you don't already have one (referenced in the code above)...
(function (module) {
var localStorage = function ($window) {
var store = $window.localStorage;
var add = function (key, value) {
value = angular.toJson(value);
store.setItem(key, value);
};
var get = function (key) {
var value = store.getItem(key);
if (value) {
value = angular.fromJson(value);
}
return value;
};
var remove = function (key) {
store.removeItem(key);
};
return {
add: add,
get: get,
remove: remove
}
};
module.factory('localStorage', localStorage);
})(angular.module('common'));

For each string in Array

Just as the name says, I want that for each certain name in an array a value is added to a int.
For example: if there are 3 strings of the same name in the array, then 3 times 50 will be added to the value.
This is my script I have now:
var lootList = new Array();
var interaction : Texture;
var interact = false;
var position : Rect;
var ching : AudioClip;
var lootPrice = 0;
function Update()
{
print(lootList);
if ("chalice" in lootList){
lootPrice += 50;
}
}
function Start()
{
position = Rect( ( Screen.width - interaction.width ) /2, ( Screen.height - interaction.height ) /2, interaction.width, interaction.height );
}
function OnTriggerStay(col : Collider)
{
if(col.gameObject.tag == "loot")
{
interact = true;
if(Input.GetKeyDown("e"))
{
if(col.gameObject.name == "chalice")
{
Destroy(col.gameObject);
print("chaliceObtained");
audio.clip = ching;
audio.pitch = Random.Range(0.8,1.2);
audio.Play();
interact = false;
lootList.Add("chalice");
}
if(col.gameObject.name == "moneyPouch")
{
Destroy(col.gameObject);
print("moneyPouchObtained");
audio.clip = ching;
audio.pitch = Random.Range(0.8,1.2);
audio.Play();
interact = false;
lootList.Add("moneyPouch");
}
if(col.gameObject.name == "ring")
{
Destroy(col.gameObject);
print("ringObtained");
audio.clip = ching;
audio.pitch = Random.Range(0.8,1.2);
audio.Play();
interact = false;
lootList.Add("ring");
}
if(col.gameObject.name == "goldCoins")
{
Destroy(col.gameObject);
print("coldCoinsObtained");
audio.clip = ching;
audio.pitch = Random.Range(0.8,1.2);
audio.Play();
interact = false;
lootList.Add("goldCoins");
}
if(col.gameObject.name == "plate")
{
Destroy(col.gameObject);
print("plateObtained");
audio.clip = ching;
audio.pitch = Random.Range(0.8,1.2);
audio.Play();
interact = false;
lootList.Add("plate");
}
}
}
}
function OnTriggerExit(col : Collider)
{
if(col.gameObject.tag == "pouch")
{
interact = false;
}
}
function OnGUI()
{
if(interact == true)
{
GUI.DrawTexture(position, interaction);
GUI.color.a = 1;
}
}
It's for a game I'm making where you can steal items for extra score points.
I've tried using the for(i = 0; i < variable.Length; i++) but that didn't seem to work.
The only thing I can think of now is using booleans to add it once. But that isn't memory friendly.
Help is appreciated and thanks in advance!
You could use the standard .forEach(callback) method:
lootList.forEach(function(value, index, array)
{
if (value === "chalice") { lootPrice += 50; }
});
If you don't have that method, you could implement it like this:
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback) {
for(var i = 0; i < this.length; i++) { callback(this[i], i, this); }
}
}

Resources