I am implementing a project picker for a Rally custom app and would like to select a projects children automatically when the parent is selected from the picker. I was able to get the ObjectID and Name of the objects I want to select but can't seem to get them to be selected from the picker. I attempted this using the "fireEvent" method but had no success. Here's what I have so far:
var teamPick = this.down('#filterPanel').add({
xtype: 'rallymultiobjectpicker',
id: 'teams',
modelType: 'project',
fieldLabel: 'Teams',
listeners: {
select: function(field, selected) {
Ext.create('Rally.data.WsapiDataStore', {
autoLoad: true,
fetch: [ 'Name', 'ObjectID' ],
filters: [
{ property: 'Parent.ObjectID', value: selected.ObjectID }
],
model: 'Project',
listeners: {
load: function(store, data) {
Ext.Array.each(data, function(child) {
console.log(child.get('Name')); //Logs the child name
});
}
}
});
},
scope: this
}
});
Are you using 2.0p3? There was a known issue with events not being correctly fired in the MultiObjectPicker. This should be resolved in 2.0p4. I ran your code in a 2.0p4 app and it functioned as expected.
As a side note your child project query can be written like this as well:
filters: [
{ property: 'Parent', value: '/project/' + selected.ObjectID }
]
The 2.0p4 version of the component also added a new event called selectionchange which gives you an array of the currently selected values (since it is a multi select picker). There are individual select and deselect events that fire when a specific item is selected/deselected.
I was able to accomplish this without the use of the fireEvent method. Instead, I used the getValue and setValue methods and added the child projects to the state manually:
this.down('#filters').add({
xtype: 'rallymultiobjectpicker',
id: 'teams',
modelType: 'project',
listeners: {
blur: function() { this.down('#teams').collapse(); },
select: function(field, selected) {
Ext.create('Rally.data.WsapiDataStore', {
autoLoad: true,
fetch: [ 'Name', 'ObjectID' ],
filters: [
{ property: 'Parent.ObjectID', value: selected.ObjectID }
],
model: 'Project',
listeners: {
load: function(store, data) {
var selected = this.down('#teams').getValue();
Ext.Array.each(data, function(child) {
selected.push(child.data);
});
this.down('#teams').setValue(selected);
},
scope: this
}
});
}
scope: this
}
});
Related
How can I change textbox height and width in a popup on devexpress mvc datagrid? I am using
#(Html.DevExtreme().DataGrid().Columns(c => {
c.Add().DataField("MyField").Visible(true).AllowGrouping(true);
}
I tried c.Add().DataField("Myfield").Width(100) but it is only working in datagrid; it does not work in popup element
First of all you need to know that you are treating with a Form and not with a simple grid, so you basically have to configure the form EditorOptions
So in jQuery it would be like this
$("#datagrid").dxDataGrid({ ,
"editing": {
"form": { items: [{dataField:"yourField",editorOptions:"width:100%"}]}
}
});
The previous answer is a little old and doesn't work now so I'll give an updated answer.
This would change the width for a field in the popup form:
$("#datagrid").dxDataGrid({ ,
"editing": {
"form": {
items: [{
dataField:"yourField",
editorOptions: {
width: "100%"
}
]}
}
});
Also if you wanted to have more control and use groups and set things, like height, you could use:
$("#datagrid").dxDataGrid({
editing: {
mode: "popup",
allowUpdating: true,
popup: {
showTitle: true,
title: "Message",
labelLocation: "top"
},
form: {
items: [
{
itemType: "group",
caption: "My Fields",
items: [
{
dataField: "Field1",
editorOptions: {
height: 200
}
},
{
dataField: "Field2",
editorOptions: {
value: true
}
}
]
}, {
itemType: "group",
caption: "My other fields",
items: [
{
dataField: "field3",
helpText: "Example: +1(111)111-1111"
}
]
}
]
}
}
});
Notice that with and without grouping both use the editorOptions to control each field.
I am trying to figure out how to bind a data model to a custom control. I have searched a number of similar questions here but they don't seem to match what I am trying to do. Maybe my method is wrong.
Anyway, I have created a Plunkr (https://plnkr.co/edit/UghwOObcDn1oRndOpCeJ) to demonstrate. Two input fields are created, one of which is on a custom control which extends a sap.m.Panel. I am attempting to bind the name and enabled properties to both input fields. No problem with the simple sap.m.Input on the page but the one in the custom control MyPanel no such luck. The name and enabled properties for both input fields should change when the button is pressed.
For the custom control I am trying to pass the bind properties to the value and enabled properties of the embedded input field as can be seen in App.view.xml.
If I change the following in MyPanel.js:
value: mSettings.value,
enabled: mSettings.enabled
to
value: '{/name}',
enabled: '{/editing}'
all works fine.
Any help or direction would be appreciated.
You will have to define the 'value' and 'enabled' properties in your custom control. To get the binding working you need to have custom setter/getter methods in your extended control. These methods are called on binding updates.
Here is the updated link
sap.m.Panel.extend('my.App.MyPanel', {
constructor: function(mSettings) {
sap.m.Panel.apply(this, arguments);
this.ef = new sap.m.Input({
width: '100px',
value: mSettings.value,
enabled: mSettings.enabled
});
this.setAggregation('_ef', this.ef);
},
metadata: {
properties: {
enabled: { type: 'boolean', defaultValue: true },
value: { type: 'String', defaultValue: "" }
},
events: {
},
aggregations: {
_ef: { type: 'sap.m.Input', multiple: false, visibility: 'hidden' }
}
},
init: function() {
},
renderer: function(oRM, oControl) {
oRM.renderControl(oControl.getAggregation('_ef'));
},
setValue: function (sValue) {
this.ef.setValue(sValue);
},
setEnabled: function (bValue) {
this.ef.setEnabled(bValue);
},
getValue: function(){
return this.ef.getProperty("value");
},
getEnabled: function(){
return this.ef.getProperty("enabled");
}
});
I use Angular and Breeze in my app and I use "hasChangesChanged" event for handling a state of entities stored in EntityManager. I have a problem when I have entity with property that is complexType and isScalar=false.
The problem occurs when I make request twice (without changing any entity) and get the same entity. On second request "hasChangesChanged" event is fired with hasChanges=true.
In moment when this event is fired my entity has state "Modified", but after data are loaded that state is changed to "Unchanged".
I've wrote a (Jasmine) unit test. In comments are information which assertion throws error.
var entity,
hasChanges = false,
listeners = {
onChange: function (event) {
console.log('change', event.hasChanges);
}
};
spyOn(listeners, 'onChange');
$httpBackend.expectGET('json/SampleEntity?').respond(200, [
{
id: 1,
name: 'some name',
data: {},
$type: 'SampleEntity',
elements: [
{
etype: 'el1'
}
]
}
]);
manager.hasChangesChanged.subscribe(function (event) {
hasChanges = event.hasChanges;
});
var query = new breeze.EntityQuery('SampleEntity');
manager.executeQuery(query).then(function (data) {
entity = data.results[0];
});
$httpBackend.flush();
expect(hasChanges).toBe(false); // OK
expect(entity.entityAspect.entityState.isUnchanged()).toBe(true); // OK
$httpBackend.expectGET('json/SampleEntity?').respond(200, [
{
id: 1,
name: 'some name',
data: {},
$type: 'SampleEntity',
elements: [
{
etype: 'el1'
}
]
}
]);
manager.executeQuery(query).then(function (data) {
entity = data.results[0];
});
$httpBackend.flush();
expect(hasChanges).toBe(false); // ERROR
expect(entity.entityAspect.entityState.isUnchanged()).toBe(true); // OK
Is this expected behavior? And if not how I can fix it?
I'm pulling my hair out on this one...
I have a view with some grids, a store and a viewModel. I need different filtered versions of the store in different grids, so I'm trying to bind each filtered store to a grid. Now I can't even get a store to load in a grid in the first place...
Here's what my code looks like:
Store:
Ext.define('My.store.Admin.Kinder', {
extend: 'Ext.data.Store',
model: 'My.model.Kind',
storeId: 'adminKinderStore',
alias: 'store.adminKinder',
proxy: {
type: 'ajax',
method: 'post',
url: '/getKinder',
reader: {
type: 'json',
rootProperty: 'kinder'
}
}
});
ViewModel:
Ext.define('My.model.kindViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.kindViewModel',
requires: [
'My.model.Kind',
'My.store.Admin.Kinder'
],
view: 'kindView',
stores: {
warteliste: {
type: 'adminKinder'
}
}
});
View:
Ext.define('My.view.Admin.kinder', {
extend: 'Ext.panel.Panel',
alias: 'widget.kindView',
id: 'kinder-panel',
requires: [
'My.view.Admin.kindController',
'My.model.kindViewModel'
],
controller: 'kind',
border: false,
maxWidth: 960,
session: My.session,
viewModel: {
type: 'kindViewModel'
},
initComponent: function() {
this.activeTab = 'warteliste-tab';
this.callParent();
},
items: [
{
xtype: 'grid',
id: 'warteliste-grid',
bind: {
store: '{warteliste}'
},
border: false,
margin: '0 0 20px 0',
selModel: {
allowDeselect: true
},
columns: [
// some grid columns
],
listeners: {
afterRender: function(grid) {
grid.store.load();
}
}
}]
});
I get an error message "Cannot modify ext-empty-store", which must mean that the store is not (yet) bound when store.load() is called in the afterRender listener.
Strange thing is, when I console.log the grid, the store is there. When I console.log grid.store, an empty store is returned.
I got the same issue in afterRender event and solved it by not getting the store from the grid like
grid.store.load();
but from the ViewModel (ViewController scope):
this.getViewModel().getStore('{warteliste}').load();
Check if the store is created as expected in viewmodel. Normally, we do not have store definition files in ./store directory but we place their configurations in viewmodel.
See an example of that here: http://extjs.eu/ext-examples/#bind-grid-form - MainModel::stores
The solution to your original problem
I need different filtered versions of the store in different grids
are chained stores.
See an example of how to implement them here: http://extjs.eu/on-chained-stores/
for me it was
myGrid.getViewModel().getStore('myStoreName').load();
The project uses marionette-rails, backbone-on-rails, select2-rails and this port to BackboneForms to provide a multiselect form field. The select options are available to the user. They are retrieved from the collection containing the total list of options:
MyApp.module("Products", function(Products, App, Backbone, Marionette, $, _) {
Products.CustomFormView = Products.CustomView.extend({
initialize: function(options) {
this.model.set("type", "Product");
Products.EntryView.prototype.initialize.apply(this, arguments);
},
schemata: function() {
var products = this.collection.byType("Product");
var productTypes = products.map(function(product){
return {
val: product.id,
label: product.get("name")
};
});
return {
productBasics: {
name: {
type: "Text",
title: "Name",
editorAttrs: {
maxLength: 60,
}
},
type: {
type: 'Select2',
title: "Product type",
options: {
values: productTypes,
value: [3, 5],
initSelection: function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({id: this, text: this});
});
callback(data);
}
},
editorAttrs: {
'multiple': 'multiple'
}
}
}
};
}
});
});
Do I initialize the value correctly in options.value? How comes initSelection is never called? I copied the function from the documentation - it might be incomplete for my case. None of the products with the IDs 3 and 5 is displayed as the selection.
initSelection is only used when data is loaded asynchronously. My understanding is that there is no way of specifying the selection upon initialization if you are using an array as the data source for a Select2 control.
The best way of initializing the selection is by using setValue after the form is created. Here is a simplified example based on the code in your example.
var ProductForm = Backbone.Form.extend({
schema: {
type: {
type: 'Select2',
title: "Product type",
options: {
values: productTypes,
},
editorAttrs: {
'multiple': 'multiple'
}
}
});
var form = new ProductForm({
model: new Product()
}).render();
form.setValue("type", [3, 5]);
You can use value function (http://ivaynberg.github.io/select2/#documentation) in setValue. I personally recomend you to use this backbonme-forms plugin: https://gist.github.com/powmedia/5161061
There is a thread about custom editors: https://github.com/powmedia/backbone-forms/issues/144