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

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

Related

exjs6 label render value upon databinding

In extjs6 label with databinding, how do I convert the bound value everytime it changes?
Right now I am using a viewmodel with formula, but it only hits this method on creation of the panel, I want it to hit the formula everytime I have an incoming change of the label value.
can someone see what I am doing wrong?
here is my label in view
columnWidth: 0.5,
xtype: 'label',
itemId: 'labelDateStatementId',
cls: 'myLabelCRM2',
bind: {
text: '{convertDateStatement}'
}
here is my formula in viewmodel
formulas: {
convertDateStatement: function (get) {
var me = this;
var myView = me.getView();
var label = myView.queryById('labelDateStatementId');
debugger;
}
it does hit the formula on view creation... but I need it to change everytime I change the source of the bind value of label.
maybe this solution will be good for You (setting data on view model directly):
Check example on fiddle
After 2 seconds change label on field.
Or You can bind a record to view model like this:
Check example 2 on fiddle

How to prevent Kendo MultiSelect from losing values after editing in a grid template?

I have a grid that displays a comma-separated list of values, and it has an array that gets used in a template editor for the grid. (On the server, I transform the comma-separated list to an array for the Kendo multiselect AngularJS directive). I have almost everything working: display, edit, and adding values in the multiselect.
There's just one weird thing happening: after I add a value in the multiselect, click Save in the editor, and reopen the editor, the multiselect then only displays one of the most-recently entered values. I know that the values are there and going through the pipeline, because the values make it into the database. I can refresh the page, open the editor, and all the values display in the multiselect correctly, including the one I just added.
It's as if kendo "forgets" most of the values when I reopen the editor. How can this be prevented? Does the MultiSelect need to be rebound to the values? If so, how?
I have tried adding this onChange event, but it had no effect. I've added valuePrimitive to no effect. I tried specifying k-rebind, but it caused an error.
Here's the directive being used in the text/x-kendo-template:
<select kendo-multi-select
id="zipCode"
k-placeholder="'Enter zip codes...'"
style="width: 225px"
k-on-change="dataItem.dirty=true"
k-auto-bind="false"
k-min-length="3"
k-enforce-min-length="true"
k-data-source="options.zipCodeDataSource"
k-data-text-field="'text'"
k-filter="'startsWith'"
k-filtering="options.zipCodeFiltering"
k-no-data-template="'...'"
k-ng-model="dataItem.zipArray"
k-highlight-first="true" />
And this is the DataSource:
options.zipCodeDataSource = new kendo.data.DataSource({
severFiltering: true,
transport: {
read: {
url: serviceUrl + "ZipCode/Get",
type: "GET",
dataType: "json",
contentType: jsonType,
data: function (e) {
// get your widget.
let widget = $('#zipCode').data('kendoMultiSelect');
// get the text input
let filter = widget.input.val();
// what you return here will be in the query string
return {
filter: filter
};
}
},
},
schema: {
data: "data",
total: "Count",
model:
{
id: "text",
fields: {
text: { editable: false, defaultValue: 0 },
}
},
parse: function (response) {
return response;
}
},
error: function (e) {
}
});
If I display {{dataItem.zipArray}} in a <pre> all of the expected values are there.
I wonder if something needs to be added to the edit event handler in the kendo grid definition, but I'm not sure what it would be. I've had to do binding like that for the dropdownlist directive.
edit: function (e) {
if (e.model.marketId === 0) {
e.container.kendoWindow("title", "Add");
} else {
e.container.kendoWindow("title", "Edit");
}
// re-bind multi-select here??
// These two lines actually cause the multiselect to lose pre-existing items in dataItem.zipArray
// var multiselect = kendo.widgetInstance(angular.element('#zipCode'));
// multiselect.trigger('change');
}
...
Update:
This dojo demonstrates the issue.
Run the dojo
Edit the first record in the Contracts grid
Add a zip code such as 22250
Click Save
Then click Edit on the first row again
Only zip code 22250 is displayed in the editor
Also, I notice that if I change k-min-length="3" to k-min-length="1", then the issue goes away. But in the scenario I'm working on, it needs to be 3.
This seems to be an issue with kendo itself. Back then this issue was reported here.
Ok based on the reply from telerik, this issue has been fixed in 2017 R3 SP1 release (2017.3.1018). You can verify it by using this updated dojo example:
http://dojo.telerik.com/IREVAXar/3

How to implement Kendo UI Custom validator on grid level

I have a Kendo UI Grid with is configured for batch editing. What I wish to achieve is a grid level custom validation before the grid's CRUD functions are invoked. So assuming the grid displays a list of employees, and user adds two employees with the same EmployeeID; then on clicking 'Save Changes', the grid should invoke the custom validator rules(say we have a one rule to check whether all the employee id's are unique). Based on the validation result, the grid should decide whether to invoke it's create/update/destroy functions.
I would greatly appreciate if someone can respond to my concern.
My Kendo Grid:
<div id="allocGrid" kendo-validator="ctrl.allocationGridValidatorRules" kendo-grid k-options="ctrl.allocationGridOptions(dataItem)"></div>
Validation Rules:
ctrl.allocationGridValidatorRules = {
rules: {
customRule1: function (input) {
// this rule may check if all the employee Id's in the grid are unique
}
},
messages: {
customRule1: "Enter a unique Employee Id"
}
};
I was referring to the below links:
http://jsfiddle.net/davidsalahi/qMRBc/
http://demos.telerik.com/kendo-ui/validator/angular
If you are doing batch edit and u want to check for duplicates I suggest you to use saveChanges event where u can do your check on e.sender.dataSource and stop saving changes if needed
saveChanges: function(e) {
if (!confirm("Are you sure you want to save all changes?")) {
e.preventDefault();
}
In this case, you need to create the custom validations in the DataSource bound to your grid. For example, you can do something like this:
employees = new kendo.data.DataSource({
schema: {
model: {
fields: {
EmployeeID: {
validation: {
employeeidvalidation: function(input){
if(input.is('[name="EmployeeID"]'){
//Implement custom validation here...
}
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