SwiftUI Checkbox Is Not Displaying The Check Mark When Clicked - checkbox

I generate a dynamic checkbox list
struct DemoStatusSearchView: View {
#ObservedObject var myObject = myObject ()
var body: some View {
VStack(alignment:.leading, spacing:20) {
Text("My Check Box List")
.font(.system(size: 16))
.bold()
.foregroundColor(.black)
ForEach(myObject.checkBoxList, id:\.id) { item in
CheckboxField(
id: item.checkboxDesc ,
label: item.checkboxDesc ,
callback: self.checkboxSelected
)
}
}.padding(20)
}
But when I click on the checkbox, the checkmark is not displayed.

I looked into my code that the view is being refreshed multiple times based on the multiple calls from the view model class. I clearly don't have an idea how the object state is working in the Combine and SwiftUI, this is the root caused of this issue.
Thank you #pawello2222 for posting me to the right direction.

Related

Scroll to bottom of a list populated with CoreData in SwiftUI

I'm trying to scroll to the bottom of List when a button is tapped. I have tried placing the List in a ScrollViewReader and this seems to work only when the List is populated using an array. When I populate the List using CoreData's FetchedResults the List doesn't scroll for some reason.
var array = Array(0...100)
private var items: FetchedResults<Item>
NavigationView {
ScrollViewReader { (proxy: ScrollViewProxy) in
List{
ForEach(items) {item in
Text(item.text!)
}
}
Button("Tap to scroll") {
proxy.scrollTo(10, anchor: .top)
}
}
}
Here if i use items it doesn't scroll but when I replace items with array the list scrolls as expected.
scrollTo() works by receiving an identifier, not an index.
Using array works because 10 is contained in array, but 10 cannot match item.
I would suggest you add an ID String property to your objects (I think you could even use object.uriRepresentation()) tag your views with that identifier, and now you'll be able to use scrollTo.
private var items: FetchedResults<Item>
NavigationView {
ScrollViewReader { (proxy: ScrollViewProxy) in
List{
ForEach(items) {item in
Text(item.text!)
.id(item.id)
}
}
Button("Tap to scroll") {
proxy.scrollTo(items[10].id, anchor: .top)
}
}
}
}

Bind the values of a grid record to a form and a window

Although there are several ways to load the values of a record into a form within a window, in the specific case of using binding from a grid to a form (for example, to display the detail of the record) how to bind the same values to a form within a window (for example: to edit the record)?
FIDDLE: https://fiddle.sencha.com/#view/editor&fiddle/1stv
Pass the record in as part of the VM data:
var janela = Ext.create('APP.MyWindow', {
animateTarget: btn.getEl(),
viewModel: {
data: { users: selectedRow }
}
}).show();

Drag and Drop stops working for an item which is once dragged

I have an ExtJS treepanel in Container A on page and there's another Container B.
The treepanel is initialized with items via Ajax call. In the viewConfig of treepanel, I've added itemadd event listener, in which I register added items as DragSource. Following is the itemadd event listener within viewConfig of treepanel.
'itemadd': function(records, node){
// Iterate over each child record of parent node in treepanel.
Ext.each(records, function(record){
var dragSource,
field,
fieldId;
field = Ext.query('[id='+record.data.listId+']')[0]; // I've manually added 'listId' which has unique value gained from Ext.id() for each record item.
fieldId = field.id;
dragSource = new Ext.dd.DragSource(field, {
isTarget : false
});
dragSource.dragData = {
record: record
};
});
}
And in the items of Container B, I have added a View named MyView which extends Ext.container.Container internally. So in the afterrender of Container B, I'm registering itself as a DropTarget. Here's how I do that;
'afterrender': function(containerMain) {
var dropZone,
myView = Ext.ComponentQuery.query("myview")[0];
dropZone = new Ext.dd.DropTarget(containerMain.getEl()); // Register Container B as DropTarget.
dropZone.notifyDrop = function(source, event, params) {
myView.doSomething(params.record); // This method will handle data of dropped record and internally show something on UI.
};
}
Now the here's problem described in step-by-step usage.
I drag an item from treepanel into Container B for first time and it works fine as intended.
I don't allow to add duplicate items again into MyView, I have a Remove button for each item added to remove it from MyView.
I remove the item which I added.
I try to drag it again from treepanel but it is no longer a draggable item.
Though I can still drag another item from same treepanel and add it, but not the first one which I added and removed earlier (and same thing would happen for all items which I once add to MyView. Note that removing of item is not necessary to reproduce the issue, only adding it causes this.
So what is getting wrong here?
Any help would be great.
I suggest to use the Ext.tree.plugin.TreeViewDragDropView (ptype: treeviewdragdrop) plugin for the tree instead of handling it manually.
Example for the treepanel:
var treePanel = Ext.create('Ext.tree.Panel', {
(...),
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
ddGroup: "sameGroup",
enableDrop: false
}
}
});
For the panel:
var panel = Ext.create('Ext.panel.Panel', {
(...),
listeners: {
'afterrender': function(component) {
var dropZone = Ext.create('Ext.dd.DropTarget', component.body.dom, {
ddGroup: 'sameGroup',
notifyDrop: function(source, event, params) {
var myView = panel.up('myview');
myView.doSomething(source, event, params);
return true;
}
});
}
}
});

How to set combox value on form from grid with nested data? Extjs 4.2 Mvc

I have a grid that pops up an edit form with combobox. Before I show the view I load the combobox store. Then I set the values of the form using form.loadRecord(record);. This loads the primary record ok. But how do I load the associated data value that is tied to the combobox so the combobox's value is set correctly.
I know I can use setValue manually, but I guess I was thinking could be handled via a load form.
If my form has 3 fields lets say firstName lastName and then a combobox of ContactType. The firstName and lastName are in my primary record with ContactType being the associated record. If I change values in fields lastName or firstName a change is detected and the record is marked as dirty. If I change the combobox value the record is not marked as dirty. I am guessing because they are two different models. How to make it one record. I would think having a combobox on a form that has its values set from a record in a grid is common but I can't find any examples of best way to accomplish this.
Here is some code.
My json looks like this. Primary record has firstName lastName hasOne associated record is ContactType
{
"__ENTITIES":[
{
"__KEY":"289",
"__STAMP":12,
"ID":289,
"firstName":"a",
"middleName":"",
"lastName":"asd",
"ContactType":{
"__KEY":"2",
"__STAMP":4,
"ID":2,
"name":"Home"
}
}
]
}
Controller list function,edit function and updatefunction, fires when grid row is clicked
list: function () {
var mystore = this.getStore('Contacts')
mystore.proxy.extraParams = { $expand: 'ContactType'};
mystore.load({
params: {
},
callback: function(r,options,success) {
// debugger;
} //callback
}); //store.load
editContact: function (grid, record) {
//load store for combobox
var store = this.getStore('ContactTypes');
store.load({
params: {
},
callback: function(r,options,success) {
// debugger;
} //callback
}); //store.load
var view = Ext.widget('contactsedit');
var form = view.down('form')
//load primary record
form.loadRecord(record);
//load associated record
form.loadRecord(record.getContactType());
updateContact: function (button) {
var win = button.up('window'),
form = win.down('form'),
record = form.getRecord(),
values = form.getValues(),
store = this.getStore('Contacts')
if (form.getForm().isValid()) {
if (this.addnew == true) {
store.add(values);
} else {
record.set(values);
}
store.sync();
win.close();
}
}
The loadRecord(record.getContactType) is a getter to the associated data. I am able to get the associated data but not sure how to make it set the value in the combobox or how to get it to act as one record and detect changes automatically.
My Contacts Model
Ext.define('SimplyFundraising.model.Contact', {
extend : 'Wakanda.model',
requires:[
'SimplyFundraising.model.ContactType'
],
fields: ['firstName', 'middleName','lastName','ContactType.name'],
associations: [
{
type: 'hasOne',
model: 'SimplyFundraising.model.ContactType',
name: 'ContactTypes',
getterName: 'getContactType',
associationKey: 'ContactType'
}
]
});
ContactType model
Ext.define('SimplyFundraising.model.ContactType', {
extend : 'Wakanda.model',
fields: ['__KEY','name',]
});
Is this the proper way to set a value for a combobox in a form with nested data?
Should I not use associations and just put all fields in my Contact Model ie add all ContactType fields to Contact model, then data should be in the same record and change tracking would work. But this seems counter to the MVC pattern and counter to the reason for associations.
How do you guys handle this scenario, any examples would be great!
Thanks,
Dan
if your form is loading the values correctly, then all you need to do is this:
Extjs4, How to set displayField in combo editor?

show dynamic data using checkbox in extjs

I have a combo box in which the user selects a value, that value is passed to the checkbox data store and it is populated dynamically from database (oracle). I tried the code below. It seems that the selected parameter is being passed to checkbox and I can see the data being populated on the console. I just can't render the checkbox on form. The error I get is: typeError: this.items[0] is undefined.
testArray = new Array();
var testStore = new Ext.data.JsonStore({
proxy:new Ext.data.HttpProxy({
method:'GET',
prettyUrls:false,
url:'kiu.htm',
listeners:{
'loadexception':{
fn:test.form.data.loadException
}
}
}),
fields:["id", "display"],
reader:new Ext.data.JsonReader({
id:'id',
root:'results',
totalProperty:'totalCount',
fields:new Ext.data.Record.create([
{name:'id',type:'int'},
{name:'display',type:'string'}
])
}),
listeners:{
load: function(t, records, options, success) {
for(var i=0; i<records.length; i++) {
testArray.push({name:records[i].data.id, boxLabel: records[i].data.display});
alert(testArray[i].id);
}
}
}
});
{
xtype:'combo',
id:'comboid3',
store:combostore,
displayField:'display',
valueField:'id',
tabIndex:1,
loadingText:'Loading combo...',
listeners :{
select:function(event){
testStore.baseParams = {
"comboid":Ext.getCmp('comboid3').getValue()
};
testStore.load();
}
}
},
{
xtype:'checkboxgroup',
fieldLabel:'Check',
items:testArray
}
Help will be appreciated!
Specifying the Ext JS version is always going to be helpful. It appears this must be 2.x or 3.x and not the current version.
The issue is timing, load calls are asynchronous so by attempting to utilize testArray in this fashion you are likely referencing an empty array by the time it parses the items property of your checkboxgroup. You have a couple options around this... one is to grab a reference to the checkbox group and add the items into it, the other is to not put the checkbox group in the form at all until the call returns and then add it with the populated items array. In either case it is likely that you will need to look up a component reference to either the FormPanel or the CheckboxGroup from within the load handler function and call the 'add' method to add child items.

Resources