Possible to use placeholders in sys_properties? - javascript

Is it possible to create a sys_property value such as:
This incident has been picked up by {person_name} for further investigation
And then in the code use something like:
var assignee = "John Doe";
var prop = gs.getProperty('my_property_name');
// and now replace person_name with the value of assignee variable?

You can use the RecordToHTML API, traditionally it's used for using the fields from a record as the replacement values for the string fields, however, with the help of .setValue(), you can bypass the record arguments and specify your own values. Note for this to work your "variables" in your string need to be wrapped in ${} and not {}:
var prop = gs.getProperty('my_property_name'); // "This incident has been picked up by ${person_name} for further investigation";
var assignee = "John Doe";
var rth = new RecordToHTML(null, null, prop);
rth.setValue("person_name", assignee); // replaces ${person_name} with "John Doe"
var result = rth.toString(); // "This incident has been picked up by John Doe for further investigation"
The above is a little hacky, as it bypasses the record arguments. If you want to go for another appraoch you can create your own function for this. You can firstly put assignee into an object that holds the key person_name and points to your assignee value, then use a function to replace values within {<key>} using the key as the key to index your object:
function interpolate(str, obj) {
return str.replace(/{([^}]+)}/g, function(match, key) {
return obj[key] || match; // if we can't find the key, return the original `{key}`
});
}
var variableMap = {
"person_name": "John Doe" // assignee
};
var prop = gs.getProperty('my_property_name');
var msg = interpolate(prop, variableMap); // "This incident has been picked up by John Doe for further investigation"
There are some other options that you can use that may do what you're after that are also worth looking into. One being using the first arguments of RecordToHTML() and another being gs.getMessage(). RecordToHTML can also be good if you have a particular record that contains the fields you want to replace from your string (note that your fields need to be wrapped in ${}):
var rth = new RecordToHTML("incident", incidentSysId, "This incident has been picked up by ${assigned_to} for further investigation", false);
var result = rth.toString();
There is also gs.getMessage(), which comes close, but it doesn't allow for named "variables" within your string and requires you to use indexes. It also performs a table query / lookup in the sys_ui_message table each time it is called which may be overkill:
// prop = This incident has been picked up by {0} for further investigation
var msg = gs.getMessage(prop, [assignee]);

Related

Find a string within a jQuery array that has multiple elements per object

I've got an array of employee's and assigned to each employee are a few elements.
Sample of array below:
var employees = [
{"name":"Johhny Test","salary":"1","email":"abc#123.com"},
{"name":"Mike Milbury","salary":"10","email":"184895#hdsjhfs.com"}
];
I've got a means of gathering the employee's last name and I'm storing it in a variable. I'd like to be able to search for the indexOf the last name housed in this variable so that I know at which position within the array that match is made.
So for instance, this array could be 100 items in size. Ideally I want to know that someone with the last name of "johnson" is in position 50 of this array. That way, I can go in and get the salary and email associated with their record from position 50 in the array.
The code I've got so far is this:
var lname = "Test";
var lnameMatch = employees.indexOf(lname);
console.log(lnameMatch);
This isn't working though - my console is logging -1, suggesting that it doesn't exist in the array. Is there a way that I can specify a element of that array to search against?
Almost like employees(name).indexOf(lname) where it is searching against the name element?
Or am I going about this all wrong and there is perhaps an easier less messy way to accomplish this?
You can use .findIndex:
const employees = [
{"name":"Johhny Test","salary":"1","email":"abc#123.com"},
{"name":"Mike Milbury","salary":"10","email":"184895#hdsjhfs.com"}
];
const lastName = "Test";
const index = employees.findIndex(employee => {
const { name = '' } = employee;
const nameParts = name.split(' ');
const lname = nameParts[nameParts.length-1];
return lastName === lname;
});
console.log(index);
console.log(employees[index]);

How can I use underscore in name of dynamic object variable

Website that I'm making is in two different languages each data is saved in mongodb with prefix _nl or _en
With a url I need to be able to set up language like that:
http://localhost/en/This-Is-English-Head/This-Is-English-Sub
My code look like that:
var headPage = req.params.headPage;
var subPage = req.params.subPage;
var slug = 'name';
var slugSub = 'subPages.slug_en';
var myObject = {};
myObject[slugSub] = subPage;
myObject[slug] = headPage;
console.log(myObject);
Site.find(myObject,
function (err, pages) {
var Pages = {};
pages.forEach(function (page) {
Pages[page._id] = page;
});
console.log(Pages);
});
After console.log it I get following:
{ 'subPages.slug_en': 'This-Is-English-Sub',
name: 'This-Is-English-Head' }
Is you can see objectname subPages.slug_en is seen as a String insteed of object name..
I know that javascript does not support underscores(I guess?) but I'm still looking for a fix, otherwise i'll be forced to change all underscores in my db to different character...
Edit:
The final result of console.log need to be:
{ subPages.slug_en: 'This-Is-English-Sub',
name: 'This-Is-English-Head' }
Insteed of :
{ 'subPages.slug_en': 'This-Is-English-Sub',
name: 'This-Is-English-Head' }
Otherwise it does not work
The reason you are seeing 'subPages.slug_en' (with string quotes) is because of the . in the object key, not the underscore.
Underscores are definitely supported in object keys without quoting.
Using subPages.slug_en (without string quotes) would require you to have an object as follows:
{ subPages: {slug_en: 'This-Is-English-Sub'},
name: 'This-Is-English-Head' }
Which you could set with the following:
myObject['subPages']['slug_en'] = subPage;
Or simply:
myObject.subPages.slug_en = subPage;

combining text into a variable name in javascript

i have looked for an answer to this, but im also not sure im using the correct wording to give me a good search result. So without further adoo.
I am trying to make a random name generator in JavaScript, and I don't want a 300 line switch if it can be avoided. No Jquery if it can be avoided, mainly as i want to learn how to code in JS, for no other reason than that. But if i have to use Jquery, so be it. Learning and all.
The idea is that the script will take the race, gender, then randomly select the first name, surname and proffesion from an array. I can get this to work in IF statements and switches. But I want to try it on as little code as possible. The example below is for humans, but the idea is to pretty much use any fantasy race... dwarves, elves... yes its for dungeons and dragons. Maybe later on use JSON for the array data, but that's later.
var HumanFemale = ["Diane","Laura","Amy"];
var HumanMale = ["Steve","Dave","Tony"];
var HumanS = ["Druss","Hale","Taylor"];
var Proff = ["Theif","Mercenary","Soldier"];
function chargen(race,gender){
var x = race.concat(gender);
var xs= race.concat('S');
document.getElementById("OutputR").innerHTML= race;
document.getElementById("OutputG").innerHTML= gender;
document.getElementById("OutputF").innerHTML= x[Math.floor(Math.random()*x.length)];
document.getElementById("OutputS").innerHTML=xs[Math.floor(Math.random()*xs.length)];
document.getElementById("OutputJ").innerHTML=Proff[Math.floor(Math.random()*Proff.length)];
}
Maybe I need dynamic variables, but i'm not sure how to convert text into a var name.
Thanks
I think an object probably makes your life a little easier, but the idea is generally the same as what you appear to have.
In JavaScript you can reference a property of an object like an array. This means that if you have a property name that can be variable, you can use the array convention to fetch the property instead of the "." convention.
Here's an example:
var example = {
"first": "hello",
"second": "world"
}
//Using dot-notation
alert(example.first); //alerts "hello"
alert(example.second) //alerts "world"
//Using array-notation
alert(example["first"]); //alerts "hello"
alert(example["second"]); //alerts "world"
Now, if the property we want is variable, we can't use the dot-notation, but we can use the array-notation:
var prop_name = "second";
//Using dot-notation
alert(example.prop_name); //throws an error (undefined property)
//Using array-notation
alert(example[prop_name]); //alerts "world"
So, if you create essentially a dictionary object, you may find it's easier/more concise to complete your task:
var dict = {
"Human": {
"Male": ["Steve", "Dave", "Tony"],
"Female": ["Diane", "Laura", "Amy"],
"Surname": ["Druss", "Hale", "Taylor"]
},
"Elf": {
"Male": [/* names */],
"Female": [/* names */],
"Surname": [/*names */]
}
}
function rand_attributes(race, gender) {
var first_name_index = Math.floor(Math.random() * dict[race][gender].length),
last_name_index = Math.floor(Math.random() * dict[race]["Surname"].length),
first_name = dict[race][gender][first_name_index],
last_name = dict[race]["Surname"][last_name_index];
//Now first_name and last_name each contain random values
//Do what you need to with those values from here
}
That code is untested, but it should at least conceptually work out.
Here's what I crudely chucked together.
var Proff=["Theif","Mercenary","Soldier"];
var CharacterName={};
CharacterName['human']={};
CharacterName['human']['female'] = new Array('Diane','Laura','Amy');
CharacterName['human']['male'] = new Array('Steve','Dave','Tony');
CharacterName['human']['surname'] = new Array('Druss','Hale','Taylor');
//just add more stuff here!
document.getElementById('OutputR').innerHTML= 'boo';
function chargen(race,gender){
document.getElementById('OutputR').innerHTML= race;
document.getElementById('OutputG').innerHTML= gender;
document.getElementById('OutputF').innerHTML= grabrandom(CharacterName[race][gender]);
document.getElementById('OutputS').innerHTML= grabrandom(CharacterName[race]['surname']);
document.getElementById('OutputJ').innerHTML= grabrandom(Proff);
}
function grabrandom(arrayofvalues){
return arrayofvalues[Math.floor(Math.random()*arrayofvalues.length)];
}
chargen('human','female');
It's nothing special and a couple of bits could be sharpened, but it's functional and gives you the idea on how it could be done.
The solution i got, heavily based on xjstratedgebx's responce.
var names = {
"Human": {
"Female": ["Diane","Laura","Amy"],
"Male": ["Steve","Dave","Tony"],
"Surname": ["Hall","Young","Taylor"]
}
}
function namegen(race,gender){
var firstname = names[race][gender][Math.floor(Math.random() * names[race][gender].length)];
var lastname = names[race]["Surname"][Math.floor(Math.random() * names[race]["Surname"].length)];
document.getElementById("OutputR").innerHTML= "Human";
document.getElementById("OutputG").innerHTML= "Female";
document.getElementById("OutputF").innerHTML= firstname;
document.getElementById("OutputS").innerHTML= lastname;
}

resolving a javascript and database table logic situation

When I query a database table, I get back values "yes" or "no" for records that represent whether an item is present or not (the item is the column name). I want to create a string that represents the products that are available by name (rather than what I am doing now "kitchen table =" + kitchenTable;
I am thinking this can be solved (poorly) by a series of if statements setting variables to either the product name or to "" and then include all variables in the string
var kt;
if (kitchenTable == yes) kt = "kitchen table";
else kt = "";
if (kitchenCabinet == yes) kc = "kitchen cabinet";
else ka = "";
output = kt + ', ' + kc;
There are about 50 items that can be presented to the user, is there a more efficient way of accomplishing this task?? One option is to change how values are entered into the datbase table such that instead of yes, its the item name but this seems like a poorer way to resolve the issue
Of course you don't give all the details about how do you make query so that is an imaginary mockup of a function simulating query
var available = [];
var result = query("kitchen table");
result === "yes" && ( available.push("kitchen table") );
......
var output = available.join();
What you want is actually built into javascript itself.
I would say using an object literal will really simply your life in this situation by organizing your code and turning it into a more readable format.
I would also recommend turning your server data into true and false as this is a standardized way to communicated a Boolean and allows for the method below to work as it does:
// From server response
var results = {
kitchenCabinet: true,
kitchenTable: true
}
// Use this for your storage of all related items
var kitchenProps = {
kitchenCabinet: 'kitchen cabinet',
kitchenTable: 'kitchen table'
}
// Reuse this function for each time your need a new category (masterBathroomProps...)
function getItemDataIfExists(results, hashTable){
'use strict';
var output = 'Your total is: ';
for (var item in results) {
if (!results.hasOwnProperty(item)) return;
if (results[item]) output += 'A '+hashTable[item]+' ';
}
return output;
}
getItemDataIfExists(results, kitchenProps);
Explanation:
You loop through a result set of an object containing keys names and true false values. In the loop, if the keyname's value is true, then use that keyname to access the properties (in this case a string of your choice. The "key" here is that the key names in each object must line up.
Here is a live demo:
http://codepen.io/nicholasabrams/pen/JXXbYz?editors=0010

Text search - filter two words in two different objects/arrays

I'm using angularJS for my webapp and I have the following problem. When I use angularjs' filter to search for, let's say "John Smith", my object, which is built as follow ({firstname: 'John', lastname: 'Smith'}), won't be recognized because the first name and the last name are not part of the same key.
Any idea how to make the space to be either a space or a search in other keys (or arrays)?
EDIT:
Per your requirements, I came up with this:
$scope.compFunc = function(actual, expected) {
var expectedSplit = expected.split(' ');
var fullActual;
//Search people for the person the name belongs to
$scope.names.forEach(function(person){
angular.forEach(person, function(name){
if (name === actual) {
fullActual = person;
}
})
})
//create an array from the names object for comparison
var fullActualArray = [];
angular.forEach(fullActual, function(name, key){
if (key != '$$hashKey')
fullActualArray.push(name = name.toLowerCase());
})
fullActualArray.sort();
expectedSplit.sort();
return actual.toLowerCase().indexOf(expected.toLowerCase()) > -1||
fullActualArray.join(',') === expectedSplit.join(',');
};
This should work just how you expect.
FIDDLE
Note: I used forEach for the sake of clarity, but if you have large amounts of data you may want to change it to for loops, which are 90% faster and can break when a match is found.
Previous solutions:
It's very simple, checks if either the value entered in the search (expected) exists in either firstname or lastname (actual), or the opposite. So entering "Robert Downy" should work, but so will "Robert blargh" or "abcDownyefg". Checking against the whole thing (firstname + lastname) is something that you have to do outside the comparison function, and is not supported out of the box with angular as far as I know.
I've also used the following to create a new array for comparison using the full names:
$scope.fullnames = $scope.names.map(function(name){
return {
firstname: name.firstname,
lastname: name.lastname,
fullname :name.firstname + " " + name.lastname
}
})
While extending the original array can be done like this:
$scope.names.forEach(function(name){
angular.extend(name,{fullname:name.firstname + " " + name.lastname});
})
This is simple and effective, and is what I would do.
You can create your own custom filter, and have it search whatever you want.

Categories

Resources