Equivalent of StructKeyList() for struct value - forms

StructKeyList() will give me list of struct key with comma delimited. Now I need to get struct value with comma delimited. Right now this is what I'm doing to get value
<cfloop collection="#form#" item="key" >
#form[key]#,
</cfloop>
How can I get list of value from struct without loop? Thanks in advance.

I go through your problem. As per my knowledge is not possible to get list of value in structure within single functions. We have to loop the key and get the value of each. But I can give a solution for to get struct value with comma delimited.
<cfset strNew = {"a":"10","b":20,"c":30}>
Here strNew is my sample structure.
<cfset myList = ''>
<cfloop collection="#strNew#" item="key" >
<cfset myList = listappend(myList,structfind(strNew,key))>
</cfloop>
<cfdump var="#myList#" />
Here I've loop over the structure keys and find the value of an particular key and append that in to and list by using listappend and structfind functions.
So you no need to put like #structure[key]#,In your end of comma(,) is also added the last value of key too. For example your code should return 10,20,30,.
So you no need to do like that. use structfind and listappend you can avoid end of the comma also. Hope it's help you.

Since you're using CF2016, if you want to avoid a loop, you can always use one of the higher-order functions like reduce().
fields = formScope.reduce( function(result, key, value) {
result.append(value) ;
return result ;
}, [] ) ;
This takes the struct of your form scope (formscope) and uses reduce() to step through it and take it down to a single value (which is the struct values turned into an array). Then we make the returned array into a list.
writeDump( fields.toList() )
My full test code is at https://trycf.com/gist/f00cc62cd4631f44070faf8008e6788f/acf2016?theme=monokai
<cfscript>
formScope = {
empty1 : "" ,
fieldl : "text1" ,
field2 : "text2" ,
empty2 : "" ,
field3 : "text3" ,
field4 : "text4" ,
empty3 : ""
} ;
fields = formScope?.reduce( function(result, key, value) {
len(value) ? result.append(value) : "" ;
return result ;
}, [] ) ;
writeDump( fields?.toList() ?: "Form doesn't exist." ) ;
</cfscript>
Giving us: text2,text3,text4,text1.
formScope is my simulated version of the form fields that would be passed to this page. I use mostly the member function versions of StructReduce, ArrayAppend and ArrayToList. I also use the initialVal optional parameter to initialize the reduction's result value as an array. I check that the value has a length (I could also trim if needed) before I insert a row in the array, allowing me to remove empty elements from my final list. I also use the safe navigation operator (?.) to do some basic validation to make sure the elements exist (like if the form didn't pass or the reduction produced invalid results) and to make it more error-resistant.
NOTE: I believe that can be taken back to be compatible with CF11, when ArrayReduce was introduced.
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-s/structreduce.html
http://ryanguill.com/functional/higher-order-functions/2016/05/18/higher-order-functions.html
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arraytolist.html

Related

How to override Ag Grid QuickFilter to receive exact match results?

By default Ag Grid Quick Filter function return rows that contains search string. For example if I type "30 June" in the searchbox, quick filter will also return rows that contains "30 cars were sold by 2 June" text. How can I override default behavior to receive only rows that exactly match my search string?
What I did was the following:
In the search itself, I removed the spaces from the search criteria:
this.gridApi.setQuickFilter(event.toLowerCase().replace(" ", ""));
In each column that I wanted an exact match, I added this code in the column definition:
getQuickFilterText: (params) => { return params.value && params.value.toLowerCase().replace(" ", "");}
(That is the override method for search. See here for more details: https://www.ag-grid.com/angular-data-grid/filter-quick/)
It seems to be working for me.
To achieve the exact match results column wise, You have to do these two things :
Remove cacheQuickFilter property from your default column definition object in gridOptions as caching convert all the columns data into a string separated by backward slash. That's the reason it will not be able to search column by column.
Add getQuickFilterText function in each column definition and add a condition for a exact match else return an empty string.
getQuickFilterText: params => {
return (params.value === <quick filter value>) ? params.value : ''
}
Now the tricky part here is how to access quick filter value inside getQuickFilterText function. You can achieve this in two ways :
Assign an id to quick filter search element and then access it's value using document.getElementById('quick-filter').value
Store the quick filter search value on change and put into a store state or service and then access that inside getQuickFilterText function.

Is it possible to change the field name in user storage with a string?

If you write conv.user.storage.something = "test" I understand that, but can you change the field name "something" in this example. Say you had an array of values named Fruit ["Banana", "Apple"] can you read the array and then assign those values to the field name value. It seems like you can only set the field name manually such as conv.user.storage.Banana but what if I am getting those names from an array?
Yes you can iterate through the array and directly assign the keys.
for (const element of array) {
conv.user.storage[element] = "text"
}

I would like to store the values in array list after iterating the select options , is it possible in Watir

I am trying to store the values of select list in an array variable
a = b.options.each {|option| puts option.attribute_value "value" }
Output :
IN PROGRESS
UPCOMING
FINAL
POSTPONED
CANCELLED
a.to_i
Is it possible to store all values which getting from attribute and store in An array
The element collections in Watir include the Enumerable module, which gives a lot of useful methods for iterating. In particular, it includes a map method that will perform a block on each element and collect the result in an array.
To store the value of all options, you can simply do:
total_list_values = #browser.options.map(&:value)
#=> ["IN PROGRESS", "UPCOMING", "FINAL", "POSTPONED", "CANCELLED"]
I coded it like this and its worked, posted if anyone wanted this
total_list_values = Array.new
body = #browser.options
body.options.each do |option|
total_list_values << option.value
end

Apex form condition

Can we have a condition clause in APEX form :
Value of Item / Column in Expression 1 = Expression 2,
where expression1 is a form variable like P19__ROW_last_update_ts and
the second expression2 is a sql query like select max(date_max) from table
Please help me on this.
You can do this by adding a property on your form controller that executes the query and returns the result. The property will look something like:
public String getExampleProperty {
get {
return [/*some query in here*/].someProperty;
}
}
And then in your form, you'll reference the value like:
{!exampleProperty}
Note that you don't use the 'get' prefix in your visual force markup.
Hope this helps!

How to use dot in field name?

How to use dot in field name ?
I see error in example:
db.test2.insert({ "a.a" : "b" })
can't have . in field names [a.a]
You can replace dot symbols of your field name to Unicode equivalent of \uff0E
db.test.insert({"field\uff0ename": "test"})
db.test.find({"field\uff0ename": "test"}).forEach(printjson)
{ "_id" : ObjectId("5193c053e1cc0fd8a5ea413d"), "field.name" : "test" }
See more:
http://docs.mongodb.org/manual/faq/developers/#faq-dollar-sign-escaping
http://docs.mongodb.org/manual/core/document/#dot-notation
Actualy you may use dots in queries. See: http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29
Because of this special dot symbol mean you cannot use it in field names. Like you cannot use dot symbol in identifiers in most of programming languages.
You may write query db.test2.find({ "a.a" : "b" }) but if you want to be able to write such a query you need to insert your object like so: db.test2.insert({"a": {"a": "b"}}). This will create document with the field named "a" with the value of embeded document containing the field named "a" (again) with the value "b".
You can also write a SONManipulator using the pymongo library that transforms the data going to and back out of mongodb. There are downsides; there is a performance hit (impact depends on your use case) and you have to transform your keys when you do searches using find.
Here's code with an example of how to use it in the comment for the KeyTransform class:
from pymongo.son_manipulator import SONManipulator
class KeyTransform(SONManipulator):
"""Transforms keys going to database and restores them coming out.
This allows keys with dots in them to be used (but does break searching on
them unless the find command also uses the transform).
Example & test:
# To allow `.` (dots) in keys
import pymongo
client = pymongo.MongoClient("mongodb://localhost")
db = client['delete_me']
db.add_son_manipulator(KeyTransform(".", "_dot_"))
db['mycol'].remove()
db['mycol'].update({'_id': 1}, {'127.0.0.1': 'localhost'}, upsert=True,
manipulate=True)
print db['mycol'].find().next()
print db['mycol'].find({'127_dot_0_dot_0_dot_1': 'localhost'}).next()
Note: transformation could be easily extended to be more complex.
"""
def __init__(self, replace, replacement):
self.replace = replace
self.replacement = replacement
def transform_key(self, key):
"""Transform key for saving to database."""
return key.replace(self.replace, self.replacement)
def revert_key(self, key):
"""Restore transformed key returning from database."""
return key.replace(self.replacement, self.replace)
def transform_incoming(self, son, collection):
"""Recursively replace all keys that need transforming."""
for (key, value) in son.items():
if self.replace in key:
if isinstance(value, dict):
son[self.transform_key(key)] = self.transform_incoming(
son.pop(key), collection)
else:
son[self.transform_key(key)] = son.pop(key)
elif isinstance(value, dict): # recurse into sub-docs
son[key] = self.transform_incoming(value, collection)
return son
def transform_outgoing(self, son, collection):
"""Recursively restore all transformed keys."""
for (key, value) in son.items():
if self.replacement in key:
if isinstance(value, dict):
son[self.revert_key(key)] = self.transform_outgoing(
son.pop(key), collection)
else:
son[self.revert_key(key)] = son.pop(key)
elif isinstance(value, dict): # recurse into sub-docs
son[key] = self.transform_outgoing(value, collection)
return son
def remove_dots(data):
for key in data.keys():
if type(data[key]) is dict: data[key] = remove_dots(data[key])
if '.' in key:
data[key.replace('.', '\uff0E')] = data[key]
del data[key]
return data
this recursive method replaces all dot characters from keys of a dict with \uff0E
as suggested by Fisk
I replaced the key value using myString.replace(".","\u2024") before inserting it into the JsonObject.
Initially I used a simple recursion to replace all "." characters with its unicode equivalent but figured it out that even the dots in the values was getting replaced. So I thought that we should replace the dots only from keys and made the changes accordingly in case "if isinstance(input, dict)".
I thought it should be a sufficient condition to do the magic but I forgot that dict value can also be a dict or a list and then I finally added that check that if value of a dict was not string then, go inside recursively and was finally able to come up with this solution which eventually did the trick.
def remove_dots(data):
if isinstance(data, dict):
return {remove_dots(key): value if isinstance(value, str) else remove_dots(value) for key,value in data.iteritems()}
elif isinstance(data, list):
return [remove_dots(element) for element in data]
elif isinstance(data, str):
return data.replace('.','\u002e')
else:
return data
I've only really come across this problem when trying to serialize Dictionaries and such where the offending dot can appear as a key name.
Edited to show the references.
The quick and dirty C# approach:
using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
public static T Sanitize<T>(T obj)
{
var str = JObject.FromObject(obj).ToJson();
var parsed = Regex.Replace(str, #"\.(?=[^""]*"":)", "_"); //i.e. replace dot with underscore when found as a json property name { "property.name": "don't.care.what.the.value.is" }
return JObject.Parse(parsed).ToObject<T>();
}