Update CodenameOne sidemenu command when a property value changes - codenameone

I want to be able to change the title of my Side menu command based on the size of a ListProperty which is dynamically updated. I have tried to do this via a changeListener, but i can not get this to work.
Command cmdWishlist = tb.addMaterialCommandToRightSideMenu("Wishlist(" + Shop.getInstance().wishList.size() + ")", FontImage.MATERIAL_FAVORITE, e -> {
....
});
Shop.getInstance().wishList.addChangeListener(pl -> {
tb.revalidate();
});
If however, I open another form, and check the sidemenu, the change that I need is reflecting. How can I get this to work? By the way, I get the desired behavior if i put, say a label on the toolbar and setText("Wishlist(" + Shop.getInstance().wishList.size() + ") in the change listener.
Please point me in right direction

When we add a command to the side menu or a button we extract its values but don't automatically reflect updates as that can cause a potential memory leak by binding commands to components. The workaround is to modify the original underlying component too e.g.:
Button ui = tb.findCommandComponent(cmd);
ui.setText(newLabelForCommand);

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().

Show custom pop up warning message when user changes any value (text box/LOV) on page

I have requirement to show custom pop up warning message when user changes any value (text box/LOV) on page and close tab/cancel button by mistake.
Option I tried are:
a) Within application we are using a complex task flow/RegionModel for 7 different scenario's. Also requirement is to display custom message - Hence could not use approach "unsaveddatawarning"
http://www.oracle.com/technetwork/developer-tools/adf/unsaveddatawarning-100139.html
b) Second option I tried was to have custom region controller:
CustomRegionController implements RegionController
Inside validateRegion(RegionContext regionContext) thought to find if page data is dirty
AdfFacesContext.getCurrentInstance().getDirtyPageHandler().isDataDirty();
or
DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
DCDataControl cDataControl = dcBindings.getDataControl();
boolean dirtyFlag = cDataControl.isTransactionModified();
In both scenario it always gives true (seems due to common set of VO/View Link application module always gets dirty when data is being rendered on page load).
Last option I am left with is to invoke valueChangeListener for each element (textbaox, LOV, Check box). I do not like this option at all. Please suggest if there can be better way to handle this scenario.
Why is using a value change listener a problem? Have each input component call the same VCL method in the backing bean. If necessary you can get the component id from the vcl event object.

Adding listener to Ext.Grid.panel in EXTJS 4

I am trying to add a listener to a Ext.grid.panel
listeners: {
itemclick:function( grid, record, item, index, event){
alert(index);
var record = grid.getStore().getAt(index);
alert("Edit " + record.get('data'));
alert("Type " + record.get('type'));
}
I suppose to get the index value of the row I clicked. So when I click the row for the first time I get : [object Object] in the alert box with index in it. The second two alerts don't appear at all.
So when I again click the same row. it shows the correct index and then "data" and then " type" in an alert box.
How can I get the right values on the first click only?
When I add your listener to a grid panel of my own, I get the same behavior every time. For example:
4/"Edit undefined"/"Type undefined".
That you are seeing different behaviors depending on if it is the first time you click an item or not likely has something to do with how the grid is created/rendered.
The content of the Object passed as "index" to your listener function might give you a clue. If you log it to the console you'll be able to inspect it. (At least that's how Chrome handles logging of objects).
While this is not a solution to your problem, I hope it helps in your debugging.

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