collectionView, didSelectItemAtIndexPath issue - ios6

I have an interesting issue with collectionView, specifically, didSelectItemAtIndexPath.
My app has one particular view with a background image, which is accessed via an SQL. Within that view is a popover, with a collectionView, to change the parent view's background, and access other "sets" available for purchase.
My issue is with the changing of the background. All items display correctly in the collection view and the parent's background will change as it should. The problem is that the item selected is not the one that displays, even though via NSLog, I can see that the correct image is being selected and passed back to the parent. There is a corresponding NSLog in the parent, which shows the same image id as the popover's NSLog.
The first item in the collectionView, when tapped, will change the background of the parent to white, as if there was no image available. Tapping the second cell will display the first cell's image. Tapping the third cell will display the second cell's image... and so on. There are 15 images available to select from.
This is the didSelect method:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if ([_currentView isEqualToString:#"New_Journal"])
{
MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication.sharedApplication delegate];
// to get the variable back to the parent
appDelegate.loadBackgroundID = indexPath.row;
// interact with the SQL via _settingsDao
[_settingsDao updateJournalBackgroundId:_journalId withBackgroundId:appDelegate.loadBackgroundID];
NSLog(#"Selected background: %d", indexPath.row);
// notification to let EntryView know the background has changed
[NSNotificationCenter.defaultCenter postNotificationName:#"aBackgroundChanged" object:self];
}
}
Edit to show SQL interaction method:
-(void)updateJournalBackgroundId:(int)journalID withBackgroundId:(int)newBackgroundId
{
NSString *query = #"UPDATE BgIconBorderSettings SET background_id = ? WHERE journal_id = ?";
FMDatabase *db = [dbUtils sharedDB];
[db executeUpdate:query,[NSNumber numberWithInt:newBackgroundId],[NSNumber numberWithInt:journalID]];
if([db hadError])
{
NSLog(#"Error %d: %#",[db lastErrorCode],[db lastErrorMessage]);
}
}
Anyone have any ideas on how to get the correct image of the tapped cell to display? Thanks for any assistance in solving this issue.
As jhilgert pointed out... it was the SQL database. It started at 1 and not 0. Changed the ids and it works as expected.

Related

NSArrayController: Doesn't update bold attribute

I have a tableview bound to a NSArrayController. The ArrayController gets it´s data from an array [NSObject]:
class Fruits : NSObject {
var name:String
var price:Double
// If I set 'isBold = true' here manually,
//the font in my tableview becomes bold (from start of the application).
dynamic var isBold = false {
didSet {
print(isBold)
}
}
override init() {
name = "name"
price = 0.0
}
init(name:String, price:Double) {
self.name = name
self.price = price
}
}
So everything works fine as long as I set the ìsBold`value manually.
If I call in ViewController:
Fuits.init().isBold = true
tableView.reloadData()
The correct ìsBold`value is printed, but in the tableview nothing changes. Any ideas why the ArrayController doesn't notice the updated value?
EDIT:
I found a way how it is working. But maybe just a hint why it is not working like above. This solution works with iteration, I don´t think it is how it's supposed to be.
func changeBold(bold: Bool) {
if bold == false {
self.dataArray.forEach { fruit in
fruit.isBold = false
} else {
self.dataArray.forEach { fruit in
fruit.isBold = true
}
}
}
Edit: I misinterpreted what you had written. I thought the bindings settings panel was for the table view, not the table cell view. The rest of what you wrote makes more sense to me.
Your line Fruits.init().isBold = true is a bit odd syntax-wise, but the bigger point is that you're creating a new instance of Fruits and setting its bold attribute but not doing anything with the instance, so it goes away once it's out of scope. You need to change the property of the instance stored in the cell view's objectValue property (because that's the instance that's set by the bindings mechanism, which your cell view represents).
Also, be aware that "editing an object behind the controller's back" will also usually cause the symptom of changes not appearing in the UI. Example: if you remove an instance of Fruits from your array directly, you'd have to tell the array controller to refresh to see the changes (which can lose selection and scroll information in a table or some other UI state). Instead, you should access the array controller's arrangedObjects property and remove / add / insert there so the array controller is "aware" of the changes. You'll need to read a lot more on the bindings mechanism to understand when / why to make changes through a controller vs. directly, but it's an aspect of Cocoa Bindings of which you must be aware.

How do I get a LazyComboBox to select an item from another page in Vaadin?

I am using Vaadin 7.5.5 and Viritin 1.35. I have implemented a LazyComboBox that is backed by a Spring Data JPA service call and repository.
My basic setup for the LazyComboBox is:
initList(
Site.class,
new FilterablePagingProvider() {
#Override
public List findEntities(int index, String name) {
return sitesService.findByName(name);
}
},
new FilterableCountProvider() {
#Override
public int size(String name) {
return sitesService.countByName(name);
}
},
PAGE_SIZE
);
This works great when I am typing in the combo box.
If I pick an item from the first page (page 0) I can then leave the combo box, come back to it, and click the drop down arrow again and the previously selected item is still selected.
However, if I choose an item from any page other than 0, then clicking the drop down arrow causes the selected item to become null and the user has to find the original item again.
I can post the details of the service and repository if needed but it isn't anything more complicated than a select * from table where name like '%' + name + '%'.
How do I keep the selected value in the combo box no matter what page was chosen?
Thank you.
I think you should call setNullSelectionAllowed(false); on this combo box.
Also, a solution to keep selected value after navigation can be to store it in a session value, then you'll be able to retreive it wherever you are. See Session wiki page

ExtJS: Added grid rows wont de-highlight

When adding a rows to a grid, and then clicking on it, it gets selected (and highlighted). Then, clicking elsewhere but the new row remains highlighted (so now there are to highlighted rows).
Please, does anyone know what the problem could be? How to make it behave normally, i.e. clicking a row deselects (de-highlights) the other one?
After I reload the page (so the new row is not new anymore), everything works as expected.
Edit: Here's the code for adding rows:
var rec = new store.recordType({
test: 'test'
});
store.add(rec);
Edit 2: The problem seems to be listful: true. If false, it works! But I need it to be true so I'm looking at this further... It looks like as if the IDs went somehow wrong... If the ID would change (I first create the record and then the server returns proper ID, that would also confuse the row selector, no?)
(Note, correct as ExtJS 3.3.1)
First of all, this is my quick and dirty hack. Coincidentally I have my CheckboxSelectionModel extended in my system:-
Kore.ux.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.CheckboxSelectionModel, {
clearSelections : function(fast){
if(this.isLocked()){
return;
}
if(fast !== true){
var ds = this.grid.store,
s = this.selections;
s.each(function(r){
//Hack, ds.indexOfId(r.id) is not correct.
//Inherited problem from Store.reader.realize function
this.deselectRow(ds.indexOf(r));
//this.deselectRow(ds.indexOfId(r.id));
}, this);
s.clear();
}else{
this.selections.clear();
}
this.last = false;
}
});
And this is the place where the clearSelections fails. They try to deselect rows by using ds.indexOfId(r.id) and it will returns -1 because we do not have the index defined remapped.
And this is why we can't find the id:-
http://imageshack.us/photo/my-images/864/ssstore.gif/
Note that the first item in the image is not properly "remapped". This is because we have a problem in the "reMap" function in our Ext.data.Store, read as follow:-
// remap record ids in MixedCollection after records have been realized. #see Store#onCreateRecords, #see DataReader#realize
reMap : function(record) {
if (Ext.isArray(record)) {
for (var i = 0, len = record.length; i < len; i++) {
this.reMap(record[i]);
}
} else {
delete this.data.map[record._phid];
this.data.map[record.id] = record;
var index = this.data.keys.indexOf(record._phid);
this.data.keys.splice(index, 1, record.id);
delete record._phid;
}
}
Apparently, this method fails to get fired (or buggy). Traced further up, this method is called by Ext.data.Store.onCreateRecords
....
this.reader.realize(rs, data);
this.reMap(rs);
....
It does look fine on the first look, but when I trace rs and data, these data magically set to undefined after this.reader.realize function, and hence reMap could not map the phantom record back to the normal record.
I don't know what is wrong with this function, and I don't know how should I overwrite this function in my JsonReader. If any of you happen to be free, do help us trace up further for the culprit that causes this problem
Cheers
Lionel
Looks like to have multi select enabled for you grid. You can configure the selection model of the grid by using the Ext.grid.RowSelectionModel.
Set your selection model to single select by configuring the sm (selection model) in grid panel as show below:
sm: new Ext.grid.RowSelectionModel({singleSelect:true})
Update:
Try reloading the grid using the load method or loadData method of the grid's store. Are you updating the grid on the client side? then maybe you can use loadData method. If you are using to get data from remote.. you can use load method. I use load method to update my grid with new records (after some user actions like add,refresh etc). Or you could simply reload as follows:
grid.getStore().reload();

ExtJS window dynamically add GridPanel items and show it

I want to show only one GridPanel,which I dynamically add by switch click button event, in window.
var event_menu = new Ext.menu.Menu( {
id : "event_menu",
items : [ {
text : 'record1',
handler : function() {
win.add(item_list_panel);//dynamica add GridPanel to show server data
win.doLayout();
item_list_store.load();
}
}, {
text : 'record2',
handler : function() {
win.remove(item_list_panel);//I want to remove it inorder to show the item_list_panel2 and only show one panel.
win.add(item_list_panel2);
win.doLayout();
item_list_store.load();
}
} ]
});
and this menu belong to my window tbar.
when I click record win will show item_list_panel and I want to when I click record2 the item_list_panel2 will show in win and item_list_panel will hide.
If I win.remove(item_list_panel) will have an error :
c.getPositionEl().dom is undefined
How can I do it,Thanks
I can barely understand your question, but if I understand correctly you can do it several ways.
you can destroy the component directly
item_list_panel.destroy()
you can go through your items and select it by id
win.items.item('item_id').destroy()
There are also ways to remove it without completely destroying it, depends what you want to do

Filtering combobox based on value member

I have two list that I load when my app starts. The first one loads a complete set of data from the database, the second one independently loads a set of associated data from file.
Each list is loaded into a BindingSource and set as the DataSource for their respective combobox. The data is loading just fine.
The issue is that I need to have the second comboBox only display the elements of its list that correspond with the selected value of the first list.
I have attempted to set the value members to the referential bit of data, but cant figure out how to get the comboBoxSettings to only show the the items whose EventID matches the selected item's EventID from the EventList comboBox.
//Event List comboBox
comboBoxEventList.DataSource = _eventSimPresenter.BindingSourceEventList;
comboBoxEventList.DisplayMember = "DisplayName";
comboBoxSettings.ValueMember = "EventID";
//Settings combobox
comboBoxSettings.DataSource = _eventSimPresenter.BindingSourceUserSettings;
if (_eventSimPresenter.BindingSourceUserSettings.Count > 0)
{
comboBoxSettings.DisplayMember = "EventName";
comboBoxSettings.ValueMember = "EventID";
}
thanks!
You can reate a method in _eventSimPresenter that return a BindingSourceUserSettings by eventId. When the 1st comboBox changes, take the selected eventId and update 2nd comboBox datasource:
...
comboBoxSettings.DataSource =
_eventSimPresenter.GetBindingSourceUserSettings(selectedEventId)
if (_eventSimPresenter.BindingSourceUserSettings.Count > 0)
{
comboBoxSettings.DisplayMember = "EventName";
comboBoxSettings.ValueMember = "EventID";
}
In other terms, the filtering should be applied to the datasource since it's not possible to do it via the comboBox.

Resources