QML Strings in BlackBerry Cascades - string

I am trying to build a custom button in newest BlackBerry 10 platform.
The button should change background image when it is clicked and then change it back when it is clicked the second time.
The button logic is fairly simple: once clicked, I check for the type of image currently in the button and change the image source.
I started with a basic QML custom control which looks like this (stripped of labels and other unimportant things):
import bb.cascades 1.0
Container
{
id: root
layout: DockLayout
{
}
function clickMe()
{
var source = myImage.defaultImageSource.toString();
console.log(source);
if (source.endsWith("image.png"))
{
myImage.defaultImageSource = "asset:///images/image_pushed.png";
}
else
{
myImage.defaultImageSource = "asset:///images/image.png";
}
}
ImageButton
{
id: myImage
defaultImageSource: "asset:///images/image.png"
}
onCreationCompleted:
{
myImage.clicked.connect(root.clickMe);
}
}
ImageButton click event is connected to JavaScript function clickMe. The function fires and the URL is logged to console correctly.
The problem is the IF clause, because the image_pushed.png is never set. Why is this the problem and how can I implement this button?
I am looking around for a only QML solution for this problem and I found this information:
the defaultImageSource property is of type QUrl, which does contain
toString() method.
toString() method returns QString, which indeed has function endsWith.
my QML reference: http://qt-project.org/doc/qt-4.8/qstring.html#endsWith
Thanks.

Within QML QString instances appear to be a normal JavaScript strings. This mapping is done automatically. And Javascript strings don't have a endsWith method. You can use the search method with an regular expression to achieve the same.
if (source.search(/image\.png$/ !== -1) { /* ... */ }

I think you can create more simple way by using property
for example:
Control{
id : myControl
property bool state
ImageButton{
defaultImageSource : state ? "firstImageAsset.png" : "secondImageAsset.png"
onClick :{
myControl.state = !myControl.state
}
}
}

Related

Dynamically added menu (PXAction + MenuAutoOpen + AddMenuAction) gets hidden in some screens, but not others

I am trying to dynamically add a menu and related actions through a graph extension. The code I have written works in some screens but not in others. I can see the menu appear during post-back but it gets hidden right away: http://recordit.co/T5KSEz7QJv
I have spent a few hours investigating the problem and here's what I found so far:
If I don't add my action to a menu, it works in every cases. The issue is only when using AddMenuAction. I see that there's some logic inside PXAction to show/hide the menu based on visibility of the items inside the menu, but I couldn't figure the problem out.
If the menu itself is directly declared in the graph extension (using public PXAction... and attributes), it works as expected. It is not an option in my case because I am trying to create a generic mechanism that will allow me to add actions to any graph type.
The two following graph extensions highlight this problem - the first one is for Sales Orders entry, and the other for Business Account maintenance. They are identical, except for the graph type parameter:
//This extension works fine, button displays as expected
public class TestButtonsSO : PXGraphExtension<SOOrderEntry>
{
public override void Initialize()
{
base.Initialize();
Type primaryViewItemType = Base.Views[Base.PrimaryView].Cache.GetItemType();
var myMenu = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu", "My Menu",
a => a.Get(),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { MenuAutoOpen = true } });
var action = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu$Test", "Test",
a => throw new PXException("Clicked!"),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { } });
myMenu.AddMenuAction(action);
}
}
//The menu will appear during post-back but gets hidden right away
public class TestButtonsBAccount: PXGraphExtension<BusinessAccountMaint>
{
public override void Initialize()
{
base.Initialize();
Type primaryViewItemType = Base.Views[Base.PrimaryView].Cache.GetItemType();
var myMenu = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu", "My Menu",
a => a.Get(),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { MenuAutoOpen = true } });
var action = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu$Test", "Test",
a => throw new PXException("Clicked!"),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { } });
myMenu.AddMenuAction(action);
}
}
Upon the investigation, this issue seems to be caused by PXGridWithPreview corrupting ToolBarItemCollection in the DataSource. Your approach above will perfectly work on all Acumatica screens, which do not contain a PXGridWithPreview control. For screens already utilizing PXGridWithPreview, we'll have to wait until a fix is realised by Acumatica Engineering Team (will keep this item on my radar and post an update once the fix is available)

How to get the text of /html/head/title element using Geb framework?

Using the Page Object pattern, I'd like to implement some "at" verifications based on the text of /html/head/title element.
How do I get the text of the title?
I know Geb doesn't support XPath expressions.
#Tim_Yates is right, but you specifically asked about the Page Object model.
You setup the rules for your successful page load, like so:
class GoogleHomePage extends Page {
static url = "http://google.com/"
static at = { title == "Google" } // the bit you asked about
}
Then, your actual test:
Browser.drive {
to GoogleHomePage // goes to GoogleHomePage and verifies by calling at().
}
(if you don't want at() checking, use via() instead of to().)
The documentation shows:
Browser.drive {
go "http://google.com/ncr"
// make sure we actually got to the page
assert title == "Google"
....

How to get selected text from DevTools code editor?

I'm trying to get selected text from codeeditor of DevTools. I can get selectionInfo in onSelectionChanged handler, but I dont know how to get text.
Also how to get selectionInfo (current selection) before onSelectionChanged fired?
chrome.devtools.panels.sources.createSidebarPane(
"title",
function(sidebar) {
function update(selectionInfo) {
//alert([selectionInfo.url, selectionInfo.startLine, selectionInfo.endLine, selectionInfo.startColumn, selectionInfo.endColumn]);
sidebar.setObject(JSON.parse(JSON.stringify(selectionInfo)));
// How to extract text using data from selectionInfo ???
}
update(/*selectionInfo should be there*/);
chrome.devtools.panels.sources.onSelectionChanged.addListener(update);
}
);
The callback of chrome.devtools.panels.elements.onSelectionChanged.addListener doesn't take any argument, cf the API documentation. That means that your selectionInfo will always be undefined.
To get the selected element, you can use the $0 variable. Your code would therefore look like this:
chrome.devtools.panels.elements.createSidebarPane(
"title",
function(sidebar) {
function update() {
sidebar.setExpression("$0");
}
update();
chrome.devtools.panels.elements.onSelectionChanged.addListener(update);
}
);
Note: I replaced chrome.devtools.panels.sources, which doesn't exist, by chrome.devtools.panels.elements.

Add a MediaPicker to the General Site Settings

The current project I'm on is utilizing tenant sites. With each site, we want the ability to change the logo through out the tenant site by modifying the its settings (on the admin page, settings > general).
I've added two text fields to the site settings by following this well documented tutorial. However, I'd like the user to be able to pick the logos using the media picker instead of typing in the path.
Currently I have a LogoBarSettings part with its record, driver and handler. I'm not sure how to add the media picker to the my LogoBarSettings and even if I did, must I also create another handler, driver, and record for it? I can't imagine I would but I'm pretty stuck at this point.
Can someone provide some direction on this?
Here is my LogoBarSettings
public class LogoBarSettings : ContentPart<LogoBarSettingsPartRecord>
{
public string ImageUrl
{
get { return Record.ImageUrl; }
set { Record.ImageUrl = value; }
}
public string ImageAltText
{
get { return Record.ImageAltText; }
set { Record.ImageAltText = value; }
}
}
The MediaPicker is invoked through Javascript, so you shouldn't need to change any of your model classes. When the MediaPicker is loaded for a page, it sets up a jQuery event handler for all form elements on the page. Triggering the event orchard-admin-pickimage-open will open the MediaPicker. Supply a callback function to capture the picked media.
Here is a quick example that you can run in Firebug or Chrome Developer Tools from a page which has the MediaPicker loaded, such as a Page editor:
$('form').trigger("orchard-admin-pickimage-open", {
callback: function(data) {
console.log(data);
}})
This should print something similar to this:
Object {img: Object}
img: Object
align: ""
alt: ""
class: ""
height: "64"
html: "<img src="/Media/Default/images/test.jpg" alt="" width="64" height="64"/>"
src: "/Media/Default/images/test.jpg"
style: ""
width: "64"
__proto__: Object
__proto__: Object
The BodyPart editor integrates Orchard's MediaPicker with TinyMce, so you can start looking at that module for a more complete example, specifically Modules\TinyMce\Scripts\plugins\mediapicker\editor_plugin_src.js.

Using a Textfield to switch to a displayable in Java Me

I'm working with java me, I built an app using forms displayables. I'm trying to switch to other forms, based on the user's input in a textfield item. For example, I want the user to be able to type in the number "1" in the textfield and then be taken to form1 or type in "2" and be taken to form2 etc.
What's the code to do this?
Here's what I did but it's not working as expected:
form.setItemStateListener(new ItemStateListener() {
public void itemStateChanged(Item item) {
if (item == TextField) {
if ("1".equals(TextField.getString())) {
switchDisplayable(null, form1);
}
}
}
I've done as adviced. I added a command to the textfield item and listen on it to read textfield contents and then compare the contents as a string, to switch forms. See my code below, still not working. I think maybe there's something I'm missing or my logic is not right.
form.setCommandListener(new CommandListener() {
public void commandAction(Command command, Displayable displayable) {
if (command == getTextFieldItemCommand()) {
if ("1".equals(TextField.getString())) {
switchDisplayable(null, form1);
} else if ("2".equals(TextField.getString())){
switchDisplayable(null, form2);
}
}
}
It looks like you expect method itemStateChanged to be invoked when it feels convenient to you, like at every character entry in the text field.
Above expectation is wrong, specified behavior is explained in API javadocs:
It is up to the device to decide when it considers a new value to have been entered into an Item... In general, it is not expected that the listener will be called after every change is made...
Given above, using itemStateChanged the way you want makes very little sense, consider changing design of your MIDlet.
I for one would probably just add a command Go and command listener to the form or text field and read text field contents when user invokes that command to find out which displayable they want to switch to.

Resources