Oracle APEX Compare Two Items Values to Fire a Dynamic Action - oracle-apex

I want to create a Dynamic Action thats when my page item P2014_BALANCE < P2014_CURRENT_PRICE then P2014_CURRENT_PRICE gets the static value 0.
The problem is that i can't compare these two page items. I try to when section in my Dynamic Action to use Javascript expression like this:
if(apex.item( "P2014_CURRENT_PRICE " ).getValue() < apex.item( "P2014_CURRENT_PRICE " ).getValue()){
alert('Wrong Number');
};
but when my page loads gets an error (even Fire on Initialization = False).
I also try this:
still nothing.

This is a web application. All page items contain string values. So if you want to do number comparison, make them numbers:
if (Number(apex.item( "P2014_BALANCE" ).getValue()) < Number(apex.item( "P2014_CURRENT_PRICE" ).getValue())) {
alert('Wrong Number');
};
Note that in your example you have P2014_CURRENT_PRICE twice - that will always yield false anyways.
This is how you would implement this in a dynamic action. Note that I tried on 21.1 but it should be similar in 5 (consider upgrading):
Dynamic Action on Change of Item P2014_CURRENT_PRICE with client Side Condition of type Javascript Expression
Source:
apex.locale.toNumber(apex.item( "P2014_CURRENT_PRICE" ).getValue()) > apex.locale.toNumber(apex.item( "P2014_BALANCE" ).getValue())
True Action with Action Set Value
Set Type Static Assignment
Value "0"
Affected Element Item P2014_CURRENT_PRICE

Related

Add empty option to List Validator

I'm trying to add the option to my users that, on a List Validator, to allow select any of the options or a blank option. Spreadjs has the IgnoreBlanks setting, which I use, so when the user uses the delete key or the backspace and deletes the cell it validates correctly.
However, I would love to use the same functionality as in Excel, which allows blank options in the list validator, in part of the list.
I've tried to target the <select> element that holds the list and programmatically add the empty element, however, it crashes after the user selects the empty option.
I've also tried to add different escaped characters to the list. If I select a character that represents an empty string or a tab, it won't add a new option to the list. If I use any strange character, or even the null character \0 you get a new option to select, but the content is that typical rectangle you see when your font doesn't have the character you're trying to display.
I've also tested using a regular ListValidator like in the example pages, not our custom functionality and doesn't work either.
https://www.grapecity.com/demos/spread/JS/TutorialSample/#/demos/basicDataValidator
I have also tried creating a FormulaListValidator, and if my range has empty cells I could then get an empty option on my list, however, because the range may have duplicates, I get duplicated options.
After researching a little bit I found a workaround in a different language which I adapted to Typescript (Angular 6)
export const getListValidatorFromArray = (spread: GC.Spread.Sheets.Workbook, data: any[]) => {
// saving validation list values in a hidden sheet
spread.addSheet(spread.getSheetCount());
const sheet = spread.getSheet(spread.getSheetCount() - 1);
sheet.visible(false);
for (let i = 0; i < data.length; i++) {
sheet.setValue(i, 0, data[i]);
}
// create validator based on the values
const dv = GC.Spread.Sheets.DataValidation.createFormulaListValidator(
'=' + sheet.name() + '!$A$1:' + sheet.name() + '!$A$' + data.length
);
return dv;
};
Note: This creates an extra sheet for each validator you create. Makes sure you reuse them as much as possible (i.e. assigning it to a variable when it's created, and reusing the variable for other columns/rows that use the same one).

AppleScript : keep word only from list

How can I only keep words / numbers from list?
I use the follow script and I want to count unique payment methods, but I have unwanted values on my list
I also tried to use "word of item" but this is not working
I try different version of the script but always having an issue
set PaymentMethods to {}
set UniquePaymentMethods to {}
set walletPayement to {}
set mobilePayemnt to {}
tell application "Safari"
set PaymentMethods to do JavaScript "var outPut=[]; var arr=document.getElementsByClassName('sortable Summary');for (var i in arr) {outPut.push(arr[i].innerHTML)};outPut;" in current tab of window 1
end tell
repeat with x from 1 to count of items of PaymentMethods
set n to item x of PaymentMethods
if n is in PaymentMethods and n is not in UniquePaymentMethods and n does not contain "<a href=\"/finance/Support.ok" and n does not contain "Safari" and n does not contain "None" then set end of UniquePaymentMethods to n
end repeat
e.g of the result :
{"
PayPal
", "
MasterCard (999)
", "
MasterCard (888)
", application "Safari"}
It's good that you're generally mindful about supplying a sample of the input, as you've done here with the list that I presume relates to PaymentMethods. But don't forget to also provide the output you want to get back at the end. It took me a while to realise "keep words / numbers from list" was actually referring to items of class text (or string), which was about my fifth interpretation of what was being asked.
Your solution appears to do what you want, but it doesn't really because you've had to use that very case-specific set of conditionals, i.e.:
if n is in PaymentMethods ¬
and n is not in UniquePaymentMethods ¬
and n does not contain ("<a href=\"/finance/Support.ok") ¬
and n does not contain ("Safari") ¬
and n does not contain "None" then ¬
set end of UniquePaymentMethods to n
Without that, the item application "Safari", for instance, would simply be coerced into class text, which would return "Safari" in your resulting list.
So, while your request was to filter a list's data types to contain only text class items, your proposed fix, i.e.:
set n to item x of PaymentMethods as text
doesn't isolate text items; it coerces items of any class into text.
The way to filter a list by class type is to use this syntax:
get every [class] in [list]
where [class] is the AppleScript class you want to keep (discarding any items not of this class), and [list] is the list (or variable that references a list), e.g.:
every text in {1, "Hello", true, missing value, "2", text, number, pi}
--> {"Hello", "2"}
every number in {1, "Hello", true, missing value, "2", text, number, pi}
--> {1, 3.14159265359}
every application in {"PayPal", "MasterCard (999)", "MasterCard (888)", application "Safari"}
--> {application "Safari"}
every text in {"PayPal", "MasterCard (999)", "MasterCard (888)", application "Safari"}
--> {"PayPal", "MasterCard (999)", "MasterCard (888)"}
But, there's a lot you can do to simplify your script by having the initial JavaScript code do the heavy lifting so it returns a cleaner list of items that will be simpler for AppleScript to process, or eliminate any need for additional processing.
Your list items have a lot of whitespace in them. In JS, use trim().
Your AppleScript conditionals reference "innerHTML property without ever wanting to use any actual HTML. You've been consistently interested only in the text that gets printed on your webpage. Therefore, in JS, experiment with innerText applied to the right HTML element and you'll probably be able to isolate the payment methods text straight away.
You appear to want your list to contain unique items. In JS, use sets, which are basically arrays with unique items.
Implementing these three recommendations, together with the above method of filtering by text class, would look something like:
tell application "Safari" to tell document 1 to tell (do JavaScript "
[...new Set( document.getElementsByClassName('sortable Summary') )]
.map( x => x.innerText.trim() );") ¬
to set PaymentMethods to every text
As I don't know what your webpage source looks like, you may need to make slight adjustments to how you want to transform innerText besides trim(), and/or consider whether getElementsByClassName('sortable Summary') is the best way to get access to the parts of the HTML DOM tree you require. querySelectorAll() is a much more powerful method to use, which I have mentioned before.
Found it, need to add the kind for each item
set n to item x of PaymentMethods as text

COM IContextMenu::InvokeCommand - matching LPCMINVOKECOMMANDINFO::lpVerb to item

I have created a shell extension for windows with COM, however I seem to fail to properly match the ids of items I add in the overload of IContextMenu::QueryContextMenu with what I receive in the overload of IContextMenu::InvokeCommand. In my code I use InsertMenu and InsertMenuItem (as far as I understood they do the same, but the latter has some more features?). However I'm not sure which arguments passed to InsertMenu/InsertMenuItem correspond to what I must be looking for in LPCMINVOKECOMMANDINFO::lpVerb. I need some way to easily know that when I add items x, y, z to a context menu, I can then know exactly which one of x, y or z has been clicked.
EDIT: It seems that the verb equals the number from top to bottom of the item in the current menu/submenu. However I have two sub-menus each with x amount of items, so they have the same IDs of 1,2,3. How do I set custom IDs or something?
Firstly you should define an enum that holds the command IDs for your menu items, e.g.
enum {
CMDID_FIRST = 0,
CMDID_DOSOMETHING = CMDID_FIRST,
CMDID_DOSOMETHINGELSE,
CMDID_LAST,
};
These ID values need to start from 0.
In your IContextMenu::QueryContextMenu implementation:
when you add your menu items you need to give each of them an ID by setting the MIIM_ID flag in the MENUITEMINFO.fMask field, and setting the MENUITEMINFO.wID value.
give each of your menu items an ID derived from its command ID as defined above, plus the value of idCmdFirst which is passed into QueryContextMenu. E.g. the "Do Something" menu item would have MENUITEMINFO.wID set to idCmdFirst + CMDID_DOSOMETHING, and "Do Something Else" would have MENUITEMINFO.wID set to idCmdFirst + CMDID_DOSOMETHINGELSE.
the return value from QueryContextMenu needs to be MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, x) where x is the ID of the highest-numbered item you added plus 1 (alternatively, if all items were sequentially numbered, the total number of items). Basically, you're telling the host which menu item ID values are now in use so that no other context menu extensions add items that clash with yours. In the above example, you'd return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, CMDID_LAST).
In IContextMenu::InvokeCommand:
test if lpVerb (or lpVerbW) is an integer value using the IS_INTRESOURCE macro.
if so, the command ID can be found in the low word. E.g, if the user selected "Do Something Else", you would find that LOWORD(lpVerb) == CMDID_DOSOMETHINGELSE.

Ionic permanently removing items from tab list

Having an issue with actually clearing out and refreshing list items within a tab view.
A) Within the service, refresh sets the return object to null (verified) calls for fresh data (verified) and returns it to the controller (verified).
B) Within the controller, before refresh is called, i validate the length of the previously returned object(verified as length of 6), then set the object to null (verified as null), refresh the data and then validate the returned object (verified as length of 6 again).
My expectation is for the original list of 6 items to clear out and be replaced with the new list of 6 items. However, the html template list of 6 items grows to a list of 12, basically duplicating the original list. Further more, the new list of 12 seems to be sorted so the duplicates are listed in order as pairs - which seems like its being sorted. I don't understand this behavior and I can't figure out how to get displayed list to actually clear out.
.controller:
$scope.doRefresh = function() {
alert(Object.keys($scope.prods).length) ; // (6)
$scope.prods= {} ;
alert(Object.keys($scope.prods).length) ; // (0)
$scope.prods= Prods.refresh();
alert(Object.keys($scope.prods).length) ; // (6)
}
.service:
refresh: function() {
prods= [] ;
getProds() ;
return prods;
},
I fixed the issue. It was my own code. in "getProds()" I wasn't setting the return object to null, Every time I hit refresh the object was simply adding all the new data onto existing object, and returning back to the controller twice the previous size.

python try-except, exception handling

I have 10 links in a list, upon clicked,which will open a new window. Different links would yield different set of pages, however i have 3 common elements for all 10 links.
Following is the function example.
def handle_window(self):
self.driver.go_to_new_window()
try: # block 1
elements = ["element1", "element2", "element3"]
for element in elements:
try: #block 2
self.assertEqual(True, is_exist_in_new_window(element)))
except:
continue
except:
# in 'try block 2' if assert yields true at least once,
print 'passed'
# if it fails for all 3 elements,
print 'failed'
self.driver.close_current_window()
self.driver.go_to_main_window()
I am not sure how do i evaluate the results of 'try block 2', so that to do some action in block 1.
Any possible solutions ?
If "element1", etc. are meant to be CSS selectors, the most efficient way would be:
elements = ["element1", "element2", "element3"]
self.assertTrue(exists_in_new_window(",".join(elements)))
(I've renamed is_exist_in_new_window to exists_in_new_window.) The , operator in CSS means "or". So the CSS selector passed to exists_in_new_window means you are looking for "element1" or "element2" or "element3". Doing it this way will need one round-trip between the Selenium client and the browser, no matter what. Note that the code above is not meant to handle meaningfully the case where elements is a zero-length list.
With XPath selectors you could use the | operator to perform a similar transformation. In this case, I would want to additionally use parentheses to preserve semantics of the individual selectors so something like "(" + ")|(".join(elements) + ")". (I believe the semantics issue does not arise in CSS due to CSS' very rigid syntax.)
In the more general case where it is not possible to combine the search criteria into one expression, one can fall back onto alecxe's suggestion:
elements = ["element1", "element2", "element3"]
self.assertTrue(any((exists_in_new_window(element) for element in elements)))
This method causes a minimum of min(1, len(elements)) round-trips between the Selenium client and the browser and a maximum of len(elements) depending on what is present on the page.
You can use any() to check if at least one element existed on a page:
elements = ["element1", "element2", "element3"]
value = any((is_exist_in_new_window(element) for element in elements))
self.assertTrue(value)
This code assumes is_exist_in_new_window() returns True or False.
Hope that helps.