ng-show when dict is not empty - javascript

I have tried:
ng-show="Object.keys(config.taggedNgramsDict).length !== 0"
ng-show="config.taggedNgramsDict !== {}"
ng-show="JSON.stringify(config.taggedNgramsDict) !== '{}'"
Here's what config.taggedNgramsDict looks like:
var add = function (word) {
var final_booleans = []
for(var i = 0; i < $scope.number_terms; i++) {
final_booleans.push(false)
}
$scope.config.taggedNgramsDict[word] = final_booleans
}
Note: add gets triggered every time a 'word' button is clicked in the frontend.
I have checked:
config.taggedNgramsDict is the proper var name
the Dict does become filled and emptied successfully, based on a function in controller.js
'===', '==',''!==' and '!='

Related

Change grid column value from null to string empty

I'm currently working on ASP.Net Core MVC app with Telerik Kendo Grid
On the grid I have columns like:
columns.Bound(x => x.PrimaryContact.EmailAddress)
.ClientTemplate("#= PrimaryContact ? PrimaryContact.EmailAddress : '' #")
It works, but now the property EmailAddress inside PrimaryContact is showing the value "null" instead empty space, i.e: if PrimaryContact is not null but the property EmailAddress inside it is null, it displays it as a null. How can I solve that?
Can I add something to the .ClientTemplate? or is it possible to replace all null values for empty space on the jquery?
Current jquery:
function onDataBound(e) {
const grid = this;
grid.table.find("tr").each(function () {
const dataItem = grid.dataItem(this);
const text = dataItem.IsActive ? 'Active' : 'Inactive';
if (dataItem.IsActive) {
//code here
}
else {
//code here
}
});
UPDATE
I access the property as:
const test = dataItem.PrimaryContact.EmailAddressNumber;
if (test === null)
{
dataItem.PrimaryContact.EmailAddress.val = "";
}
The console returns the 3 values I want to change but I can not replace them, as you can see I tried accessing .val property but it did not work
Finally found how to achieve this, you need to iterate table rows as:
const rows = e.sender.tbody.children();
for (let i = 0; i < rows.length; i++) {
const row = $(rows[i]);
const dt = e.sender.dataItem(row);
const emailAddress = dt.get("PrimaryContact.EmailAddress");
if (emailAddress === null) {
row[0].cells[4].innerHTML ="";
}
}
Hopefully, it helps someone

How to iterate through javascript object and run a function on each value

I am new to JS.
I set up a Saved Search in NetSuite that gives us the image fields (containing URLs) of our items. I am now setting up a script in NS which tests these fields to see what item fields return 404 (i.e. need to be fixed).
My question is, how to set up function imageURLValidator to iterate through the field values of function searchItems?
Below is my start to the process but obviously has much incorrect syntax.
function imageURLValidator() {
var searchResults = searchItems('inventoryitem','customsearch529');
var url = '';
var item = '';
var field = '';
//insert loop here to iterate over items in searchResults array
//loop through items
for (var i = 0, i > searchResults[inventoryObject].length, i++) {
item = searchResults.[inventoryObject].[i];
//loop through fields in item
for (var f = 2, f > item.length, f++) {
field = item[f];
//check URL via item field's value
var code = checkURL(item[field].getvalue([field]));
//generate error based on code variable
createErrorRecord(code,item,field)
}
}
}
function searchItems(type, searchid) {
//defining some useful variables that we will use later
var inventoryArray = [];
var count = 0;
//loading the saved search, replace the id with the id of the search you would like to use
var inventoryItemSearch = nlapiLoadSearch(type, searchid);
//run the search
var inventoryItemResults = inventoryItemSearch.runSearch();
//returns a js array of the various columns specified in the saved search
var columns = inventoryItemResults.getColumns();
//use a do...while loop to iterate through all of the search results and read what we need into one single js object
do {
//remember the first time through the loop count starts at 0
var results = inventoryItemResults.getResults(count, count + 1000.0);
//we will now increment the count variable by the number of results, it is now no longer 0 but (assuming there are more than 1000 total results) will be 1000
count = count + results.length;
//now for each item row that we are on we will loop through the columns and copy them to the inventoryObject js object
for (var i=0; i<results.length; i++){
var inventoryObject = {};
for (var j=0; j<columns.length; j++){
inventoryObject[columns[j].getLabel()] = results[i].getValue(columns[j]);
}
//then we add the inventoryObject to the overall list of inventory items, called inventoryArray
inventoryArray.push(inventoryObject);
}
//we do all of this so long as the while condition is true. Here we are assuming that if the [number of results]/1000 has no remainder then there are no more results
} while (results.length != 0 && count != 0 && count % 1000 == 0);
return inventoryArray;
}
function checkURL(url) {
var response = nlapiRequestURL(url);
var code = response.getCode();
return code;
}
function createErrorRecord(code,item,field) {
if (code == 404){
//create error record
var errorRecord = nlapiCreateRecord('customrecord_item_url_error');
errorRecord.setFieldValue('custrecord_url_error_item', item);
errorRecord.setFieldValue('custrecord_url_error_image_field', field);
}
}
Here I can see searchResults variable will be empty while looping. As your call to searchItems function is async. Which will take some time to execute because I guess it will fetch data from API. By the time it returns value, your loop also would have bee executed. You can test this by putting an alert(searchResults.length) or console.log(searchResults.length). For that you need to use callback function
Also even if you get the results in searchResults. The loop you are doing is wrong. The array you will get is like [{},{},{}] i.e. array of objects.
To access you'll need
for (var i = 0, i > searchResults.length, i++) {
var inventoryObject = searchResults[i] // your inventoryObject
for(var key in inventoryObject){
item = inventoryObject[key]; // here you will get each item from inventoryObject
//loop through fields in item
for (var f = 2, f > item.length, f++) {
field = item[f];
//check URL via item field's value
var code = checkURL(item[field].getvalue([field]));
//generate error based on code variable
createErrorRecord(code,item,field)
}
}
}
And yes welcome to Javascript

Trouble removing duplicates from list

//get email from test area
var emailList = document.getElementById("emailTextarea").value;
var emailListArray = emailList.split("\n");
//Remove yahoo and duplicates from the list
var usernamesArray = emailListArray.map(function(val, index, arr) {
return val.slice(0, val.indexOf('yahoo.com'));
});
Assuming:
emailListArray = ['123#gmail.com','123#yahoo.com','123#gmail.com','123#hotmail.com']
You can do something like this:
var usernamesArray = [];
emailListArray.forEach(function(item) {
if(usernamesArray.indexOf(item) < 0 && item.indexOf('yahoo.com') < 0) {
usernamesArray.push(item);
}
});
First condition checks if the element in turn is not already in the array of results, second condition checks if the element doesn't contain the substring yahoo.com, if both are true, the element is added to the results.
After that, usernamesArray should have:
[ '123#gmail.com', '123#hotmail.com' ]

getElementsByName: control by last partial name

I can get div elements by id and using only partial name "first"
html
<div id="first.1.end">first.1.end</div>
<div id="first.2.end">first.2.end</div>
<div id="two.3.end">two.3.end</div>
<div id="first.4.end">first.4.end</div>
js
function getElementsByIdStartsWith(selectorTag, prefix) {
var items = [];
var myPosts = document.getElementsByTagName(selectorTag);
for (var i = 0; i < myPosts.length; i++) {
if (myPosts[i].id.lastIndexOf(prefix, 0) === 0) {
items.push(myPosts[i]);
}
}
return items;
}
var postedOnes = getElementsByIdStartsWith("div", "first");
alert(postedOnes.length);
It counts 3 div elements (alert).
But how can I use end-partial name for search? For example using "end"?
From MDN Attribute selectors:
[attr^=value] Represents an element with an attribute name of attr and
whose value is prefixed by "value".
[attr$=value] Represents an element with an attribute name of attr and
whose value is suffixed by "value".
So you can use [id^="first"] to find elements with id start with "first". and use [id$="end"] to find elements end with "end".
Like
// This find all div which id ends with "end".
var divs = document.querySelectorAll('div[id$="end"]');
or use jQuery:
$('div[id$="end"]');
Also, you can combine multiple attribute selectors altogether to find a more specific element:
// As we only use querySelector, it find the first div with id starts with "two" and ends with "end".
var divStartAndEnd = document.querySelector('div[id^="two"][id$="end"]');
See demo on jsfiddle
Here I am allowing user to pass all three parameters.
suppose user doesn't pass midmatch so it will return only match of first and last.
Below is the working code:
It will return 1 count:
function getElementsByIdStartsWith(selectorTag, firstmatch, midmatch, lastmatch) {
var items = [];
var myPosts = document.getElementsByTagName(selectorTag);
for (var i = 0; i < myPosts.length; i++) {
var firstmatchIndex = firstmatch?myPosts[i].id.indexOf(firstmatch)>-1?true : false : true;
var midmatchIndex = midmatch?myPosts[i].id.indexOf(midmatch)>-1?true : false : true;
var lastmatchIndex = lastmatch?myPosts[i].id.indexOf(lastmatch)>-1?true : false : true;
if (firstmatchIndex && midmatchIndex && lastmatchIndex ) {
items.push(myPosts[i]);
}
}
return items;
}
var postedOnes = getElementsByIdStartsWith("div", "first", "2", "end");
alert(postedOnes.length); // now it will show only one in alert.
It will return 3 count:
function getElementsByIdStartsWith(selectorTag, firstmatch, midmatch, lastmatch) {
var items = [];
var myPosts = document.getElementsByTagName(selectorTag);
for (var i = 0; i < myPosts.length; i++) {
var firstmatchIndex = firstmatch?myPosts[i].id.indexOf(firstmatch)>-1?true : false : true;
var midmatchIndex = midmatch?myPosts[i].id.indexOf(midmatch)>-1?true : false : true;
var lastmatchIndex = lastmatch?myPosts[i].id.indexOf(lastmatch)>-1?true : false : true;
if (firstmatchIndex && midmatchIndex && lastmatchIndex ) {
items.push(myPosts[i]);
}
}
return items;
}
var postedOnes = getElementsByIdStartsWith("div", "first", "", "end");
alert(postedOnes.length); // now it will show only three in alert.
if you don't want to consider any parameter just pass empty string( "" ) while calling the function.
Hope this will help you :)
I guess this kind of selection can be possible by using jQuery + regex. Have a look to this
How can I select an element by ID with jQuery using regex?
Might be some what on the line that you want.

How to serialize a form into an object (with tree structure)?

I have a form
<form>
<input type="text" name="Name" />
<input type="checkbox" name="Feature.Translate" />
<input type="checkbox" name="Feature.Share" />
<input type="submit" value="Convert into an object" />
</form>
I want to convert it in an object
{
Name: "John Connor's Terminator",
Feature:
{
Translate: true // if checked
// Share wasn't checked
}
}
How can I map the form to an object that has this tree structure?
Add this method to help you build the tree
// add keys to an object as a tree
// ["a", "b", "c"] will generate
// a { b: { c: def } }
// def is the value of the leaf node
var AddToTree = function(obj, keys, def)
{
for (var i = 0, length = keys.length; i < length; ++i)
obj = obj[keys[i]] = i == length - 1 ? def : obj[keys[i]] || {};
};
Create a function for a jQuery selector that will convert the form in an object
$.fn.serializeObject = function()
{
var o = {}; // final object
var a = this.serializeArray(); // retrieves an array of all form values as
// objects { name: "", value: "" }
$.each(a, function() {
var ns = this.name.split("."); // split name to get namespace
AddToTree(o, ns, this.value); // creates a tree structure
// with values in the namespace
});
return o;
};
With these two functions define you can set an event on the submit button:
$(":submit").click(function(e){
// contains the object from the form
// respecting element namespaces
var obj = $("form").serializeObject();
});
Something like the following should work:
function serializeData() {
//this is where we'll store our serialized data
var serializedData = {};
//iterate over input, select, and textarea elements
jQuery("input, select, textarea").each(function(index) {
var $element = jQuery(this);
var name = $element.attr("name");
//we only want to serialize the element if it has a 'name' attribute
if(typeof name != "undefined") {
//split on the . to get an array
var parts = name.split(/\./);
//start building the serialized data
var currentPart = serializedData;
for(var i = 0; i < parts.length; i++) {
//if this particular element doesn't already exist in our hash, create it
//and initialize it to an empty hash
if(typeof serializedData[parts[i]] == "undefined") {
currentPart[parts[i]] = {};
}
//if we're currently looking at the very last element in the array then
//it means that we need to set its value to the value of the corresponding
//input element. Otherwise, it means that there are still keys within the
//array and so we set `currentPart` to the new hash that we just created
if(i == parts.length - 1) {
//if the element is a checkbox or a radio, we need to see if it's checked
//instead of looking at its value
if($element.attr("type").toLowerCase() == "checkbox" || $element.attr("type").toLowerCase() == "radio") {
currentPart[parts[i]] = $element.is(":checked");
}
else {
currentPart[parts[i]] = $element.val();
}
}
else {
currentPart = currentPart[parts[i]];
}
}
}
});
console.log(serializedData);
}
Check out the fiddle.
All you need to do now is to bind serializeData to the submit event on the form.

Categories

Resources