I am using SweetAlert2, and have a Select List. My challenge is that the values in the select list are added programmatically. While my code runs, the dropdown has the right NUMBER of values, the text says [object Object] rather than what I added. What am I doing wrong? Code is below.
var outputStr = [];
for (var i = 0; i < data.rows.length; i++) {
// If here, we have data, so show the information....
var vREGISTRY_ID = data.rows[i].REGISTRY_ID ? data.rows[i].REGISTRY_ID : '-';
var vNN_NAME = data.rows[i].NN_NAME ? data.rows[i].NN_NAME : '-';
var vACCOUNT_NAME = data.rows[i].ACCOUNT_NAME ? data.rows[i].ACCOUNT_NAME : '-';
var vSITE_DUNS_9DIG = data.rows[i].SITE_DUNS_9DIG ? data.rows[i].SITE_DUNS_9DIG : '-';
var vPRIMARY_CITY = data.rows[i].PRIMARY_CITY ? data.rows[i].PRIMARY_CITY : '-';
var vPRIMARY_STATE_PROVINCE = data.rows[i].PRIMARY_STATE_PROVINCE ? data.rows[i].PRIMARY_STATE_PROVINCE : '-';
outputStr.push({
value:vREGISTRY_ID,
label: vACCOUNT_NAME
}) ;
}; // end of FOR loop
swal({
title: 'Select Account Name or Division',
input: 'select',
inputOptions: outputStr ,
inputPlaceholder: 'Select from dropdown',
showCancelButton: true,
inputValidator: function(value) {
return new Promise(function(resolve, reject) {
if (value === 'abc') {
resolve();
} else {
reject('You need to select abc :)');
}
});
}
}).then(function(result) {
swal({
type: 'success',
html: 'You selected: ' + result
});
})
You have to add dynamical properties to the JavaScript object
Like this: data[propertyName] = propertyValue;
var inputOptions = {}; // Define like this!
// Instead of sample variables,
// your data handling here
var vREGISTRY_ID = "500";
var vACCOUNT_NAME = "Peter";
// Add the Variables like this
// This will create '500' : 'Peter',
inputOptions[vREGISTRY_ID] = vACCOUNT_NAME;
inputOptions["455"] = "Martin";
// Note that the options will get sorted by their value
swal({
title: 'Select Account Name or Division',
input: 'select',
inputOptions: inputOptions,
inputPlaceholder: 'Select from dropdown',
showCancelButton: true,
inputValidator: function(value) {
return new Promise(function(resolve, reject) {
if (value == "500") {
resolve();
} else {
reject('You need to select Peter :)');
}
});
}
}).then(function(result) {
swal({
type: 'success',
html: 'You selected: ' + result
});
})
<link href="https://cdn.jsdelivr.net/sweetalert2/4.1.5/sweetalert2.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/sweetalert2/4.1.5/sweetalert2.js"></script>
Let's say your 'data' is the response from an Api call and you can change the response format.Then, you can return a dictionary of this form Dictionary<int,string> and bind directly the response: inputOptions: data.
Related
Because Netsuite's native CPN does not let people use spaces in the CPN my company made a custom suitescript to use a custom record type for the CPN. The script below is used to cross reference the customer and the item to generate a list of possible CPNs then it chooses the first and only option in that list. At first we had it routed to the child company, but now we think it might be a better idea to have them connected to the parent company.This way if a company has 12 child companies we only have to upload the CPN one time. Would someone review the code below and let me know why I cant get the code to use the parent customer instead of the child? Or rather it wont populate at all.
define(["N/search", "N/log"], function(Search, _Log) {
var TAG = "pi_cs_so_v2";
function Log() {};
Log.log = function (tag, msg) {
console.log(tag + " : " + msg);
};
Log.debug = function(tag, msg) {
_Log.debug(tag, msg);
Log.log(tag, msg);
};
Log.error = function(tag, msg) {
_Log.error(tag, msg);
Log.log(tag, msg);
};
function fieldChanged(context) {
PartNumber.fieldChanged(context);
}
/**
* Static object, contains customizations relevant to EURO-3
* #constructor
*/
function PartNumber () {}
function cusParent (){}
/**
* Handle the native field changed NetSuite call
* #param context
* #returns {boolean} True if CPN is updated, else false
*/
PartNumber.fieldChanged = function(context) {
var nr = context.currentRecord;
if (context.sublistId !== "item" || context.fieldId !== "item") return false;
Log.debug(TAG, "fieldChanged, executing CPN extension");
var item = nr.getCurrentSublistValue({sublistId: context.sublistId, fieldId: "item"});
var customer = nr.getValue("entity");
var parent = nr.getValue({
join: "entity",
fieldId: "parent",
name: "name"
});
Log.debug(TAG, "Item, customer: " + JSON.stringify([item, parent]));
if (!parent || parent === "" || !item || item === "") return false;
var cpn = PartNumber.find(parent, item);
if (!cpn) return false;
nr.setCurrentSublistValue({sublistId: context.sublistId, fieldId: "custcol_cpn_transaction", value: cpn});
nr.setCurrentSublistValue({sublistId: context.sublistId, fieldId: "custcol24", value: parent});
Log.debug(TAG, "Found CPN: " + cpn);
return true;
};
/**
* Search for the customer part number, assumes there is only ever a single result
* #param customer
* #param item
* #returns {number | undefined} InternalID of the True Customer Part Number record
*/
PartNumber.find = function(customer, item) {
var searchObj = Search.create({
type: "customrecord_true_cpn",
filters:
[
["custrecord_cpn_customer","anyof",customer],
"AND",
["custrecord_cpn_item","anyof",item]
],
columns: []
});
var ans = -1;
searchObj.run().each(function(result){
// .run().each has a limit of 4,000 results
ans = result.id;
return false;
});
return ans !== -1 ? ans : undefined;
};
return {
postSourcing: fieldChanged,
};
});
Assuming a company that has a hierarchy may have a tree and not just a straight line you need a way to efficiently query the hiearchy from top level to the current customer and get the best matched CPN.
We can make use of how Netsuite contatenates names and infer that the longest fully qualified customer name that has a matching CPN is the best one to use.
Although the code below is untested it is based on hierachical searches I've done in other contexts. Note that I found a lot of your pseudo object style to be pretty obfuscatory and does not add anything to code readabilty or type safety. It's just one self contained script.
define(["N/search", "N/log"], function(Search, _Log) {
var TAG = "pi_cs_so_v2";
function hasConsole(){
return typeof window == 'object' && window.console && window.console.log;
}
var Log = {
debug : function(tag, msg) {
hasConsole ? window.console.log(tag, msg) : _Log.debug(tag, msg);
},
error : function(tag, msg) {
hasConsole ? window.console.error(tag, msg) : _Log.error(tag, msg);
}
};
function fieldChanged(context) {
var nr = context.currentRecord;
if (context.sublistId !== "item" || context.fieldId !== "item") return; //return false <- fieldChanged is void
Log.debug(TAG, "fieldChanged, executing CPN extension");
var item = nr.getCurrentSublistValue({sublistId: context.sublistId, fieldId: "item"});
var customer = nr.getValue("entity");
if(!customer || !item) return;
//if (!parent || parent === "" || !item || item === "") return false; the === "" will never be evaluated
// var parent = nr.getValue({ // this call doesn't exist
// join: "entity",
// fieldId: "parent",
// name: "name" // where did you get this field id from?
// });
const custInfo = Search.lookupFields({
type:'customer',
id:customer,
columns:['internalid', 'entityid', 'parent']
});
// should have fully qualified customer name parent : sub-parent : customer
var cpn = findPartNumber(custInfo.entityid, item);
if (!cpn) return;
nr.setCurrentSublistValue({sublistId: context.sublistId, fieldId: "custcol_cpn_transaction", value: cpn.id});
nr.setCurrentSublistValue({sublistId: context.sublistId, fieldId: "custcol24", value: cpn.customer});
Log.debug(TAG, "Found CPN: " + JSON.stringify(cpn));
return; // field changed is void; no return value
}
/**
* Search for the customer part number, assumes there is only ever a single result
* #param customer
* #param item
* #returns {id: cpn record id, customer: customerId owning the cpn} | null
*/
function findPartNumber(custInfo, item) {
var cpnFilters = null;
var commonColumns = [
Search.createColumn({'name': 'entityid', join:'custrecord_cpn_customer'}),
Search.createColumn({'name': 'custrecord_cpn_customer'})
];
if(custInfo.parent && custInfo.parent.length){
cpnFilters = [
["custrecord_cpn_item","anyof",item], 'AND',
[
["custrecord_cpn_customer","anyof",custInfo.parent[0].value], 'OR', // the top level
getCustHierarcyClauses(custInfo)
]
];
}else{
cpnFilters = [
["custrecord_cpn_customer","anyof",custInfo.internalid],
"AND",
["custrecord_cpn_item","anyof",item]
];
}
var bestCPN = null;
Search.create({
type: "customrecord_true_cpn",
filters:cpnFilters,
columns: commonColumns
}).run().each(function(result){
if(!bestCPN) {
bestCPN = {
id:result.id,
entity: result.getValue({name:'entityid', join:'custrecord_cpn_customer'}),
customer:result.getValue({name:'custrecord_cpn_customer'})
};
} else{ // need to get the closest defined CPN; assumes lower level of company could have their own preferred CPN.
var testCPN = {
id: result.id,
entity: result.getValue({name:'entityid', join:'custrecord_cpn_customer'}),
customer:result.getValue({name:'custrecord_cpn_customer'})
};
if(testCPN.entity.length > bestCPN.entity.length) bestCPN = testCPN;
}
return true;
});
return bestCPN;
}
function getCustHierarcyClauses(custInfo){
var fullNames = custInfo.entityid.split(' : ').slice(0, -1); // last name is the direct company name and no inference needed
var filters = ["custrecord_cpn_customer","anyof",custInfo.internalid];
var topParentId = custInfo.parent[0].value;
if(fullNames.length == 1){ // shouldn't have gotten here if only 1
return filters;
}
for(var i = 1; i< fullNames.length; i++){
filters.push('OR', [
["custrecord_cpn_customer.parent","anyof",topParentId], 'AND',
["custrecord_cpn_customer.entityid","is",fullNames.slice(0,i).join(' : ')] // need to qualify by name because we only want direct line of hierarchy
]);
}
return filters;
}
return {
postSourcing: fieldChanged
};
});
I'm making a simple note app. Each note has a title, a body and a complete status. I want to create it so that if a note is not completed, it creates a button under the note. Upon clicking the button it should change the boolean value of complete to true and repopulate the list.
The problem I'm experiencing is that if the title has a space in it, I get an error:
This only happens when there is a space in the title(clicked on Family time). Does anyone know what the issue is? I've tried to create note.title as a variable then add it in. I've also tried to note.title.toString() with no luck. Here is the function:
function populateList(theList)
{
let divList = document.querySelector('#ListDiv');
divList.innerHTML = "";
theList.forEach(function(note)
{
let element = document.createElement('p');
let titleName = note.title.toLowerCase();
element.innerHTML = `Title: ${note.title}<br>Body: ${note.body}<br>Completed:${note.completed}`;
if(note.completed == false)
{
element.innerHTML += `<br><button onclick=completeNote("${note.title}")>Complete</button>`;
}
divList.appendChild(element);
});
}
Here you can use encodeURIComponent & decodeURIComponent like below:
function populateList(theList)
{
let divList = document.querySelector('#ListDiv');
divList.innerHTML = "";
theList.forEach(function(note)
{
let element = document.createElement('p');
let titleName = note.title.toLowerCase();
element.innerHTML = `Title: ${note.title}<br>Body: ${note.body}<br>Completed:${note.completed}`;
if(note.completed == false)
{
element.innerHTML += "<br><button onclick=completeNote('" + encodeURIComponent(note.title) + "')>Complete</button>";
}
divList.appendChild(element);
});
}
function completeNote(title){
theList.forEach(x=>{if(x.title == decodeURIComponent(title)){x.completed =true}});
populateList(theList);
}
You should add a note ID to your objects and when you click the button, pass the ID to the function to find the node and set it's status to completed.
After you change the status, re-render the list.
const notes = [
{ id: 1, title: 'Morning', body: 'Get out of bed', completed: true },
{ id: 2, title: 'Day', body: 'Work', completed: false },
{ id: 3, title: 'Evening', body: 'Go to bed', completed: false }
];
populateList(notes);
function completeNote(noteId) {
notes.find(note => note.id === parseInt(noteId, 10)).completed = true;
populateList(notes);
}
function populateList(theList) {
const divList = document.querySelector('#ListDiv');
divList.innerHTML = "";
theList.forEach(note => {
let element = document.createElement('p');
let titleName = note.title.toLowerCase();
element.innerHTML = `Title: ${note.title}<br>Body: ${note.body}<br>Completed: ${note.completed}`;
if (note.completed == false) {
element.innerHTML += `<br><button onclick=completeNote("${note.id}")>Complete</button>`;
}
divList.appendChild(element);
});
}
<div id="ListDiv"></div>
I want to push a Boolean value at a specific index in an array. Whenever I ran the code I get this error, ERROR TypeError: Cannot read property 'push' of undefined
This is my code:
var check_ins = [];
for (var i = 0; i < this.employees.length; i++) {
// let check = check_ins[i];
if (check_ins[i] === true) {
let alert = this.alertCtrl.create({
title: 'Sorry,',
subTitle: 'ur already checked in',
buttons: ['OK']
});
alert.present();
break;
} else if (check_ins[i] === false || check_ins[i] === undefined) {
let checkInTime = new TimeInModel(in_timing.date, emp_id, in_timing.time_in);
this.employeesService.pushTimeIn(checkInTime)
.subscribe(checkInTime => {
},
error => this.errorMessage = <any>error);
console.log("Successfully checked-in!");
check_ins[i].push(true);
break;
}
What could be the problem? Is there another alternative to using an array to achieve the same output?
You don't need to push the value true into check_ins[i], you can just set it: check_ins[i] = true or push true to the array: check_ins.push(true)
When you use push, the pushed value gets added as a new element to the array. I suggest you do the following instead :
var check_ins = [];
for (var i = 0; i < this.employees.length; i++) {
// let check = check_ins[i];
if (check_ins[i] === true) {
let alert = this.alertCtrl.create({
title: 'Sorry,',
subTitle: 'ur already checked in',
buttons: ['OK']
});
alert.present();
break;
} else if (check_ins[i] === false || check_ins[i] === undefined) {
let checkInTime = new TimeInModel(in_timing.date, emp_id, in_timing.time_in, true);
this.employeesService.pushTimeIn(checkInTime)
.subscribe(checkInTime => {
},
error => this.errorMessage = <any>error);
console.log("Successfully checked-in!");
check_ins[i]=true;
break;
}
In my javascript i am trying to check an array if empty.If there is no item in <li> then array will be empty and this should throw error but it is not working. Here is my code
var phrases = [];
$('#listDiv #hiddenItemList').each(function () {
var phrase = '';
$(this).find('li').each(function () {
var current = $(this);
phrase += $(this).text() + ";";
});
phrases.push(phrase);
});
if (phrases === undefined || phrases.length == 0 )
{
$.alert("Please select rate type, high rate and low rate", {
title: "Rates Info",
type: "danger"
});
return false;
}
You have to check that you're not just pushing an empty string into the array. This will make the array phrases have length and not be undefined but won't be what you're looking for.
var phrases = [];
$('#listDiv #hiddenItemList').each(function () {
var phrase = '';
$(this).find('li').each(function () {
var current = $(this);
phrase += $(this).text() + ";";
});
if ( phrase != '' ) {
phrases.push(phrase);
}
});
if (phrases === undefined || phrases.length == 0 )
{
$.alert("Please select rate type, high rate and low rate", {
title: "Rates Info",
type: "danger"
});
return false;
}
I'm new to Javascript, come from Java, this is less intuitive for me.
I would like to check for duplication of the title value and concatenate to the duplicated title the producer name
My idea is to sort the values and then check each one with is next for duplication
Can you suggest me how to implement this kind of solution?
function getItems(itemKeys, itemSortOrders, itemsMap)
{
var items = _.map(itemKeys, function(itemKey, index) {
var item = itemsMap[itemKey];
return _.extend({
key: itemKey,
title: item.title,
imageURL: item.imageURL,
formattedPrice: utils.formatMoney(item.price),
producerKey: item.producerKey,
producerTitle: item.producerTitle,
allowOrder: true,
sortOrder: itemSortOrders[index]
}, calculateItemDetails(item.deliveryDayAvailable, item.deliveryDayStatus, item.deliveryDayUsageCount));
});
items = _.compact(items);
return items;
}
Thanks
You can test if item have duplicates with this function, it use filter to find the same items and check if the length is larger then 1.
function haveDuplicates(itemKeys, itemsMap, itemKey) {
var item = itemsMap[itemKey];
var dups = itemKeys.filter(function(key) {
return itemsMap[key] == item;
});
return dups.length > 1;
}
var itemsMap = {
'foo': 'Lorem',
'bar': 'Lorem',
'baz': 'Ipsum',
'quux': 'Dolor'
};
var output = document.getElementById('output');
var itemKeys = Object.keys(itemsMap);
itemKeys.map(function(key) {
output.innerHTML += itemsMap[key] + ' ' +
(haveDuplicates(itemKeys, itemsMap, key) ? 'have' : 'don\'t have') + '\n';
});
<pre id="output"></pre>
SO this is what i did eventually and this worked
var duplicateMap = {};
_.each(itemsMap, function(item) {
var title = item.title.trim();
if (duplicateMap[title]) {
duplicateMap[title] = 2;
}
else {
duplicateMap[title] = 1;
}
});