Codename One - Start editing in the search bar programmatically - codenameone

I need to start editing in the search bar programmatically when the Form is shown. Because I didn't find any API for that, I wrote this code inside the Form:
addShowListener(l -> {
for (int i = 0; i <= getToolbar().getComponentCount(); i++) {
if (getToolbar().getComponentAt(i) instanceof Button) {
Button btn = (Button) getToolbar().getComponentAt(i);
if (btn.getUIID().equals("TitleCommand")) {
btn.pressed();
btn.released();
}
if (btn.getUIID().equals("BackCommand")) {
btn.addActionListener(ev -> {
backForm.showBack();
});
}
}
}
});
The problems of this code:
it relies on the current implementation of the method Form.getToolbar().addSearchCommand, that created in the toolbar a button with UIID TitleCommand (the search icon on the right) and another button with UIID BackButton (the arrow on the left).
my listener added to the back button doesn't work: instead of show the backForm, it shows the toolbar without the search bar.
So... my question is how to implement what I need with a better coding. Is it necessary to do an RFE to expose an API like Toolbar.startSearchEditingAsync()? And how can I change the default actionListener of backButton?

If you need to initiate it before it's shown you might need something more elaborate similar to Form.setEditOnShow().
This seemed a bit simpler in my head when I started it but once I started I had to finish so I implemented this here: https://github.com/codenameone/CodenameOne/commit/86fea99196dd5a453988ede8217e0809e529469a
It should work, let me know if it has issues.

Related

Creating dynamic buttons on codenameone

I am trying to make it so when i click a button another is created, and you can do this as many times as you want too. But I haven't been able to find a way to make it work, any ideas? I have tried creating a for loop but that just ends up overwriting the other buttons and deleting the tags.
Try something like this:
Form f = new Form(BoxLayout.y());
f.add(createButton("Click Me"));
f.show();
Then the method createButton():
private Button createButton(String title) {
Button b = new Button(title);
b.addActionListener(e -> {
Container c = b.getParent();
c.add(createButton(title));
c.revalidate();
});
return b;
}
I'm guessing the thing you missed is the call to revalidate() which must be invoked when you change a Form after it was already shown. Notice the first addition occurs before the form is shown and doesn't invoke revalidate().

How to 1. detect url in textarea event, 2: convert to url. Using AngularJS

We have a simple control (textarea), where we would like to detect user input of 'proper' urls and:
1. Visually convert these 'proper' urls to links and
2. Trigger an event we can hook on to detect a 'proper' link has been entered.
Of course the contents of textareas cannot be styled. As far as we see, though, TinyMCE (via AngularUI) might be the solution along with its 'autolink' plugin. However, other than whitelisting, it is not clear how 1. we can control/manage what a 'proper' link is (for example bit.ly or deliciou.us, etc are common domains now) or 2. how we can detect an event that a proper url has been entered other than using TinyMCE's 'onChange' and using our own custom regular expressions.
Although we can imagine solutions, this is a common requirement nowadays and we're having difficulty finding pre-built solutions to achieve this. BTW, we are using AngularJS.
Any help or pointers greatly appreciated!
Thanks,
Mo
We have a very similar situation where we have a textArea where the user can enter anything and any urls are supposed to be converted and displayed as clickable links. We solved it as follows.
Display the textarea value in a div. Prior to display we translate the value with a small function like this:
$scope.transformHrefsInAnswer = function(value) {
var retval = value;
if(retval != null) {
var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
retval = value.replace(urlRegex, function (url) {
return '' + url + '';
});
}
return retval;
};
When the user clicks on the div we switch it to be a editable textarea with the actual value bound to the proper ng-model. They can then put in anything they want. When the area loses focus it switches back to a DIV and we call the transform function again so it displays as a valid, clickable link.
If all you want to do is validate you can use the transform function with minor mods to check for matches.
Hope this helps.

ionic + android back button + sidemenu isOpen detection - not working reliably

I have an odd situation. I am writing an angular + ionic app with a left slide menu and here is what I am trying to do:
1) Trap the Android back button
2) When you tap the back button, if the menu is not open, take you to the menu (open it)
3) If the menu is open and you hit the back button, exit the app
To trap the back button, I have this code in app.run (also tried relocating to a base controller and injecting it with $controller into other controllers, did not make a difference)
What I am noticing is that if I actually tap the 'menu icon' of the menu, the "isOpen" reliably prints true/false alternately as a I open and close the menu
But, when I tap the Android back button, it works the first time (prints true or false), but every subsequent tap does not change the isOpen state, while the menu actually toggles.
This therefore makes it impossible for me to programmatically detect if the menu is open or close within the android back button handler.
It's confusing me why this is only a problem within the android back handler, and not a problem when I tap the menu item. It's the same code that is called in both cases, which is
$ionicSideMenuDelegate.toggleLeft();
My Android handler code:
$ionicPlatform.registerBackButtonAction(function (event) {
$ionicSideMenuDelegate.toggleLeft();
$ionicSideMenuDelegate.$getByHandle('sideMenu').toggleLeft();
$timeout ( function() {
console.log ("Status of SIDE MENU IS : " + $ionicSideMenuDelegate.$getByHandle('sideMenu').isOpen());
},1000);
}, 100);
I've also set up a codepen, though not sure how one can test it on and android device, because every time I try and hit the backbutton on a codepen or jsfiddle, it makes the browser go back a page.
Any insight into what is going on? I've asked in the ionic forum, but haven't been able to find out why (yet) --> hence the post to the SO community in the hopes it reaches a wider audience.
registerBackButtonAction needs a priority to override the other actions:
The priorities for the existing back button hooks are as follows:
Return to previous view = 100 Close side menu = 150 Dismiss modal =
200 Close action sheet = 300 Dismiss popup = 400 Dismiss loading
overlay = 500
Your back button action will override each of the above actions whose
priority is less than the priority you provide. For example, an action
assigned a priority of 101 will override the 'return to previous view'
action, but not any of the other actions.
I've tested this code and it works as expected:
.run(function($ionicPlatform, $ionicSideMenuDelegate, $ionicPopup) {
$ionicPlatform.registerBackButtonAction(function(e) {
e.preventDefault();
if (!$ionicSideMenuDelegate.isOpenLeft()) {
$ionicSideMenuDelegate.toggleLeft();
} else {
navigator.app.exitApp();
}
}, 1000);
});
As you can see I've used priority 1000 to make sure that I override all the default actions.
I've also used preventDefault(). I don't think you need this but, just in case.
This bit of code only works for the left-side menu as I only check:
$ionicSideMenuDelegate.isOpenLeft()
and only open the left one:
$ionicSideMenuDelegate.toggleLeft()
but you can change it to work with the right menu as well.
UPDATE:
If someone is interested to find out more about Android and Back Button this is the best article I've read so far.

ExtJS form creating help

I'm using extJS 4.
I have a form pop up every time you click edit profile.
The problem is that every time you click edit Profile another form pops up so you can just keep clicking.
Is there a way to make the form only pop up if there isn't one already up.
Thanks for the help!!!
The problem sounds like you are creating a new window on every click of the "edit profile" button/link.
What you need to do is put a check in at the beginning of your form code to check to see if it exists first. If it doesn't, create the window and .show() it... Otherwise, you will just need to .show() it. Be sure to also reset the form if need be. You will also want to try and hide the window instead of destroying it. Otherwise, you will be creating new objects every time.
You can make your form modal, so to block entire interface until you close it, or you can use something like this to your controller to create form:
editProfile: function(button) {
var me = this;
if (!me.win) {
me.win = Ext.widget('editProfile');
// delete the me.win reference if the window gets destroyed
me.win.on('destroy', function() {
delete me.win;
return;
});
}
me.win.show();
}

Help wrap onClick toggle checkbox into a function

I have a page with 50 hidden checkboxes, and I want to be able to toggle each checkbox by clicking on a visible link. The actual checkboxes have to stay hidden...so... Is there a better way to do this, with a JS function so I don't have to include the entire onclick in each link? And I use mootools, not jQuery.
This works to activate a checkbox:
Select
But to toggle it, this works:
onclick="if (event.target.tagName != 'INPUT') document.getElementById('field_select_temp_professional_10').checked = !document.getElementById('field_select_temp_professional_10').checked"
None of what you posted is actually mootools code, you may as well not use mootools...
Markup:
Select
js in your domready:
document.getElements("a.add_app").addEvents({
click: function(e) {
if (e.target.get("tag") != 'input') {
var checkbox = document.id("field_select_p" + this.get("data-id"));
checkbox.set("checked", !checkbox.get("checked"));
}
}
});
If you have 100+ then I suggest you look at using event delegation from mootools-more and add just one event to the parent instead of creating 100 events and storing 100 functions that deal with it.
This is coding to patterns, and it involves changing your markup to make things work. You can also make the change based upon walking the DOM in relation to the clicked item, e.g. this.getParent().getElement("input[type=checkbox]"), or something can mean you don't need to store a relative id in the element itself.

Resources