BINDING between Form and Grid Extjs - javascript

So what I'm trying to achieve is to populate the Form with the selected row records and/or to edit the rows through form, via the ViewModel so it's two-way binding, I have done soo in the states field but I'm having trouble with the other fields, I have tried formulas but that didn't work either.
Here is a handler that did console the records but I can't bind them with the form fields.
store = this.getView().getStore();
var records = record.getSelected().items[0].data;
//var record = records[0];
console.log('showChart',records)
if (records) {
this.getView().getDialog().loadRecord(records);
}
console.log(records.name);
Here is my Fiddle example

You need to transport the selected record to the form and also set the bind (bind: {value: ''}) property of the form fields.
A simple way is to pass the selected grid record to the Test.main.Form's viewModel. Look:
mainController.js:
...
showChart: function (record, selModel) {
var form = Ext.create({
xtype: 'testform'
});
//selModel is actually an array of selected records.
form.getViewModel().set('record', selModel[0]);
form.show();
},
...
form.js:
...
items: [{
label: 'First Name',
name: 'first',
bind: {
//record that was set in the showChart function.
value: '{record.name}'
}
...
Try with the other fields.
I hope this helps. Any questions, let me know.

Related

Dynamically create UI elements via Controller and bind them to a specific properties in Model

I've been trying to add dynamic content to my dialog based on specific object in my JSONmodel, which is an array of objects.
My model has the following structure, I've set it like this(dummy data):
Note: I have multiple models active in this controller's view, each of which has its own model data.
this.setData( emp: [
{
col1: "1.4",
col2: "2.0",
col3: "3.1"
},
{
col1: "4.1",
col2: "5.3",
col3: "6.5"
}
]);
So I've set the model data successfully and now I am able to access it via:
var modelData= this.oView.getModel("myModel").oData;
What I want now is to dynamically create sap.m.Dialog and dynamically fill it with multiple sap.m.Input elements which have values based on a single object from my model:
var getDialogContent = function(modelData){
var arr = [];
var keys = Object.keys(modelData[0]); // property names. I hard-coded first obj for test.
// I want to use these properties and bind a new input on dialog for each property.
jQuery.each(keys, function(i, key) {
// 'myModel>/emp/0/'+key is a supposed full path to property...
// according to this link:
// https://sapui5.hana.ondemand.com/1.36.6/docs/guide/91f0ed206f4d1014b6dd926db0e91070.html
newInput.bindProperty("value", 'myModel>/emp/0/' + key); //key is col1 the first time
newInput.setProperty("description", key);
newInput.setProperty("type", sap.m.InputType.Number);
arr.push(newInput);
});
return arr;
};
I call getDialogContent() in the content property of the dialog to set its content.
Now, everything works save for the binding newInput.bindProperty("value", 'myModel>/emp/0/' + key);, the input fields that are displayed are just empty and show no sign of binding, also newInput.getBindingContext("myModel"); returns undefined.
var dialog = new sap.m.Dialog({
title: 'Dynamic dialog: ',
type: 'Message',
content: getDialogContent(modelData),
buttons: new sap.m.Button({
text: 'Cancel',
press: function () {
dialog.close();
}
}),
afterClose: function() {
dialog.destroy();
}
});
Does anyone have any idea what is wrong here and why can't I bind my property to the input element? I basically just want to bind values of my dynamic input fields to arbitrary object from object array in my JSON Model. Any suggestion is welcome.
Edit(Solution):
On the var keys = Object.keys(modelData[0]); line I replaced modelData[0] with modelData["emp"][0] as I was accessing specific object form JSONModel. Now it works.
Did you add the dialog to the dependents of your view? When I remove that step in our app, the result is exactly as you described: The fields are empty and getBindingContext() returns undefined.
One of the best way to implement a dialog in a reusable manner is the one described in this link. You have to add the dialog as dependent to the "parent" view in order to retrieve the models set on that view.
onDialogOpen: function () {
if (!this.oDialog) {
this.oDialog = new sap.m.Dialog({
title: 'Dynamic dialog: ',
type: 'Message',
content: getDialogContent(modelData),
buttons: new sap.m.Button({
text: 'Cancel',
press: function () {
this.oDialog.close();
}.bind(this)
}),
afterClose: function() {
this.oDialog.destroy();
}.bind(this)
});
//to get access to the view models
this.getView().addDependent(this.oDialog);
}
this.oDialog.open();
},

In xtype tagfield, the values sent to the server appear as a single combined line. Extjs

In the Ext.form.Panel component, I use the field:
....
{
xtype: 'tagfield',
fieldLabel: 'Установить сотрудников',
name: 'survey_users',
store: {
type: 'usertreestore'
},
reference: 'UserTreeStore',
displayField: 'text',
valueField: 'id',
filterPickList: true,
queryMode: 'remote',
publishes: 'value'
},
....
I set the values for this field and send it to the update in the store.
The value of the field survey_users looks like one combined string "survey_users": 469473475463
but the right kind of values is 469,473,475,463
Below is the full form data when you submit.
[{"text":"\u0414\u0430\u0432\u044b\u0434\u043e\u0432 \u0410\u043b\u0435\u043a\u0441\u0435\u0439","id":"75","survey_users":469473475463,"survey_cofficient":2,"parentId":"73"}]
In the controller, the save method looks like this:
...
saveUserData: function(button, e) {
var values;
var form = button.up('form');
record = form.getRecord();
store = this.getUserTreeStoreStore('UserTreeStore');
values = form.getValues();
id = form.getRecord().get('id');
values.id=id;
record.set(values);
console.log(record)
store.sync();
},
...
Before setting the values ​​in the record, it is clear that the values ​​are and they are in the correct format, but after setting the values ​​in the record field survey_users: NaN
I bring a screen output in the console
How to make sure that when submitting a form, the values of the survey_users field were sent in the correct format?
Try encodeSubmitValue
Here's the FIDDLE
Network:

How to render a form in a grid row

I'm trying to render a form within a custom row grid without success.
handler: function (button, record, pressed, eOpts) {
var grid = this.up('grid');
var store = grid.getStore();
var innerPanel = Ext.widget('form', {
//renderTo: record,
title: 'Title Test',
name: 'test',
items: [{
xtype: "textfield",
name: "testfield",
fieldLabel: "FooTest"
}]
});
// store.add(record);
store.add(innerPanel);
}
Any idea how to do this?
Fiddle: https://fiddle.sencha.com/#fiddle/183e
Thanks.
EDITED with taubi19 sugestion.
I think you don't quite understand the concepts yet. The form is a part of the view, the store is an object, that takes care of the data. You want to have a column in which each row is a form. This means you need a column whose xtype is not textfield, but something custom. I found out on senchas kitchen sink, that we need a 'widgetcolumn ' . In your fiddle, change the columns array with the following code and you will have a form in each new row.
columns:[
{
header:'Name',
dataIndex:'name',
flex:1,
xtype:'widgetcolumn',
widget:{
width:400,
xtype:'form',
items:[
{
xtype:"textfield",
name:"testfield",
fieldLabel:"FooTest"
},
{
xtype:"textfield",
name:"testfield1",
fieldLabel:"FooTest1"
}
]
}
}
]
And I suggest you remove adding the form to the store. You add records/data to stores. The store.add method takes a model instance as a parameter (Ext.data.Store.add).

KnockoutJS losing previous value when loading options after value

I'm feeding my options off an AJAX request, while the value is in the selection initially. However Knockout seems to delete values that aren't in the options on binding.
Example: http://jsfiddle.net/EVzrH/
Knockout seems to use selectExtensions (line 1699 of v3) to read and write the selected option. In this new values are matched to indexes, and returned by again getting the index and matching to data.
How can I save my data from being lost?
Generally, I handle this by prepopulating the observableArray with the current value (no need for the text, since you wouldn't likely know it yet).
Like:
var viewModel = {
val: ko.observable(1),
opts: ko.observableArray([{ Id: 1 }])
};
Then, let the observableArray get populated with the actual values when it returns.
For a more generic solution, you could use a custom binding as described in the second part of this answer: Knockout js: Lazy load options for select
This would pre-populate the observableArray for you and take into account that you may or may not have optionsValue set.
I can see 2 possible options here. First is to fill opts arrray before applying bindings:
var viewModel = {
val: ko.observable(1),
opts: ko.observableArray([])
};
viewModel.opts([
{ Id: ko.observable(1), Text: ko.observable("abc") },
{ Id: ko.observable(2), Text: ko.observable("someVal") },
{ Id: ko.observable(3), Text: ko.observable("other") }
]);
ko.applyBindings(viewModel);
Here is fiddle: http://jsfiddle.net/EVzrH/1/
Or if for some reason you cannot populate it before applying bindings you can just save value and them assign it again:
var viewModel = {
val: ko.observable(1),
opts: ko.observableArray([])
};
var value = viewModel.val();
ko.applyBindings(viewModel);
viewModel.opts([
{ Id: ko.observable(1), Text: ko.observable("abc") },
{ Id: ko.observable(2), Text: ko.observable("someVal") },
{ Id: ko.observable(3), Text: ko.observable("other") }
]);
viewModel.val(value);
Here is a fiddle: http://jsfiddle.net/EVzrH/2/
Either set the value after populating the options, or subscribe to the options:
viewModel.opts.subscribe(function() {
viewModel.val(1);
});
http://jsfiddle.net/gCyP6/
I've managed to get it working the way I wanted by commenting out some of the knockout code to avoid ko.dependencyDetection.ignore.
http://jsfiddle.net/EVzrH/3/
ko.bindingHandlers['value']['update'] = function (element, valueAccessor) {
ko.bindingHandlers['options']['update'] = function (element, valueAccessor, allBindings) {
Only problem is that it isn't minified, so switching to the minified library does not work.

AngularUI select2 AJAX set via model

I'm using AngularUI's ui-select2 directive with AJAX.
Here's what I've got in my view:
<label>Group: <input ng-model="group" ui-select2="select2GroupConfig"></label>
Here's what I have in my model:
$scope.select2GroupConfig = {
ajax: {
url: 'theURL',
data: function (term, page)
{
return { q: term };
},
results: function (data, page)
{
return { results: data };
}
}
};
This works as expected.
My question: How can I update the value via the model?
I tried:
$scope.group = 'some group';
I also tried using an object:
$scope.group = { id: 32, text: 'some group'};
but that doesn't either work.
How do you update a select2 that uses AJAX, via the model?
Turns out you can set it to an object, but only after ui-select2 runs; I was trying to give it an initial value.
So, instead of using the regular model, you have to use select2's initSelection function:
$scope.group = 'Dummy Content';
$scope.select2GroupConfig.initSelection = function ( el, fn ) {
fn({ id: 2, text: 'Some group' });
}
Note that you have to give the input an initial value, otherwise initSelection is never called. That's why I'm just setting it to some dummy content.
This works, but it feels like a hack.
Does anybody have any better ideas?
If you have initSelection setup, you can pass just the ID and the directive will pull up the entire row object.
This will also allow you to set the value when the page loads to just the ID too.
If you don't want to use initSelection you can set the entire row (object) as the value and select2 will update accordingly. It all depends on your use-case however.

Categories

Resources