Extjs form.submit() call changing field value - forms

I can see what are the values of the fields just before the submit:
var itemsForm = '';
function mostraItems(item, index, length) { itemsForm += item.id + ':' + item.name + ':' + item.value + ':' + index + '\n'; }
myForm.form.items.each(mostraItems);
alert (itemsForm);
myForm.form.submit({...
The problem I have is that the submitted values are different from what I can see before the form.submit() call. One of the fields is a ComboBox:
var myCombo = new Ext.form.ComboBox({
//autoWidth: true,
width: 250,
displayField: 'theFieldText',
editable: false,
emptyText: 'Select something ...',
fieldLabel: 'Some text',
listeners: { 'select': { fn: theOnSelect, scope: this} },
mode: 'local',
selectOnFocus: true,
store: theStore,
triggerAction: 'all',
typeAhead: true,
valueField: 'theFieldValue',
name: 'fieldName'
});
What is going in the request is the sum of the valueField and the displayField. Say the value field contains "1" and the displayField contains "some text" then what goes in the request is "1 (some text)" in instead of just the value "1".
There is something happening after or during the form.submit() call and I can't find what it is.
Using Ext 2.3

There isn't anything unusual happening during form submit call.
First of all, check the form values just before the form is submitted (but not the way you do it now). Do you use Firebug (I hope yes)?
myForm.getValues();
gives you key/value pairs as they will be submitted.
So type into console
Ext.getCmp('your-form-id').getForm().getValues();
or put into your code
console.log(myForm.getValues());
instead of alert() and see an output. Then, when you submit the form in a standard way
myForm.submit({url: 'submit-url'})
there is no chance your values will be different. How do you submit the form?

As Igor described, you should always use form.getForm().getValues() to see what Values are being submitted.
And if for any particular field you are not happy with the way your data is being formatted or displayed or calculated, you can always override the getSubmitData method for that field.

Related

ag-grid: Need to aggregate multiple fields into a table within a cell

I'm wondering what the best practice is for displaying a table (with data from multiple fields) within a cell in ag-grid?
I think I can get it to work with formatting the entire table as an html string and passing that to the grid as the field and using a cellRenderer, however I'd rather not have that kind of view logic on the server-side.
I'd really like for the column definition to be able to take in more than one field, but it doesn't seem like that's possible.
Any ideas? Thanks.
You can define a valueGetter for the desired column in column def.
Here is a sample -
valueGetter:
function sumField(params) {
return params.data.a + params.data.b
}
Value getters example
In your ColDef for the column, you can pass data and then destructure the values you're looking for off of that object, which comes through props in ag-grid.
For example...
In your ColDef array:
{
field: 'data',
headerName: 'Name',
cellRendererFramework: NameDescriptionRenderer
}
Then, in your NameDescriptionRenderer:
export default class NameDescriptionRenderer extends React.Component {
public render() {
const { description, name } = this.props.data;
return <React.Fragment>{`${name}: ${description}`}</React.Fragment>;
}
}
function fullNameGetter(params) {
return params.data.Title + ' ' + params.data.FirstName + ' ' + params.data.MiddleName + ' ' + params.data.LastName;
}
.....
{
headerName: 'Full Name',
field: 'Title&FirstName&MiddleName&LastName',
filter: true,
width: 225,
valueGetter: fullNameGetter,
},

Angular2 validator which relies on another form field

I am trying to create a validator in angular2 where I need to check the value of another form field. I have two scenarios I have tried where I have attempted to do this.
Scenario 1, form field looks like this:
Form = this._fb.group({
ansat: ['', [<any>Validators.required]],
helbred: ['', this.someValidator('ansat')],
});
I have the two fields above, and I would like to be able to check the value of "ansat" in the validator function "someValidator". someValidator looks like this:
someValidator(key: string) {
return (group: FormGroup) => {
console.log(group);
console.log(group.controls[key].value);
}
}
In my function, group includes all the correct information for my formgroup, but "controls" is undefined, which means I cannot get to the value of "ansat.
Scenario 2, form field looks like this:
this.myForm = this._fb.group({
ansat: ['', [<any>Validators.required]],
helbred: ['', c => Validators.compose([
this.someValidator(c,
group => group.controls['ansat'].value === 0
),
])]
});
And this is my someValidator function:
conditional(c, conditional) {
console.log(conditional);
console.log(c);
if(c.parent != undefined || c._parent != undefined){
if(c._parent.controls['ansat'].value === 0){
console.log(c._parent.controls['ansat'].value);
}
}
return null;
}
In this case, the control "c", has the correct information and includes a parent which is the group it is allocated in, but I cannot access it to try and get it's brother in the same group.
And in the case of conditional parameter, I tried sending the group through a function which I cannot make to get working either.
QUESTION: I would like to be able to access the value of "ansat" inside of a validator that I call on "helbred". How do I do this?
Any help is greatly appreciated!
Have a look at this plunker.
You're on the right track, you must pass the actual ansat control in the helbred control's validator, instead of only passing ansat control's value.
ansat: AbstractControl = new FormControl('', Validators.required);
helbred: AbstractControl = new FormControl('', Validators.required, this.someValidator(this.ansat));
this.myForm = this.formBuilder.group({
ansat: this.ansat,
helbred: this.helbred
});

Password Validation on Dynamically Generated Form

So I'm just learning Angular and I have basic routing setup and a partial for setting up a basic page with a form (theoretically any form), and based on the controller I load it loads that form from a fields array in the controller.
One of those forms is a registration form where I want to verify that the passwords match.
So in the partial I have (a mode complicated version of) this
<input ng-repeat="field in fields" ng-model="field.model" mustEqual="fields.mustEqual">
I found a directive which does password comparison:
taskDivApp.directive('mustEqual', function() {
return {
restrict: 'A', // only activate on element attribute
require: '?ngModel', // get a hold of NgModelController
link: function(scope, elem, attrs, ngModel)
{
if(!ngModel) return; // do nothing if no ng-model
// watch own value and re-validate on change
scope.$watch(attrs.ngModel, function()
{
validate();
});
// observe the other value and re-validate on change
attrs.$observe('equals', function (val)
{
validate();
});
var validate = function()
{
// values
var val1 = ngModel.$viewValue;
var val2 = attrs.mustEqual;
// set validity
ngModel.$setValidity('equals', val1 === val2);
};
}
}
});
So basically all I want to do is be able to load a literal string into ng-model from the controller so that I can pair up the model and the must equal, so the data for the form would look like:
$scope.fields = [
{
'type':"Email",
'placeholder':"Email Address",
'req': true,
'focus':true
},
{
'type':"Password",
'placeholder':"Password",
'model': "password",
'mustEqual': "passwordConf"
},
{
'type':"Password",
'placeholder':"Comfirm Password",
'model':"passwordConf",
'mustEqual': "password"
}
];
However what happens now is that the main password field gets bound to the "model" field of its index in the array and similar for passwordConf (ie inital values literally "password" and "passwordConf")
The fact that this isn't easy makes me think I have the wrong mindset - is this not a good way to do forms, should I just have them hard coded?
If this is okay then any ideas on how I could accomplish it would be appreciated!

Why does Ext.form.ComboBox remove all the values automatically when selected any item in the list?

I've made a combo box and its working fine except when I select one of the items in the combobox, it removes all other values in it. Here is a piece of code:
var comboitemarray = new Array();
for(var comboitems=0;comboitems<listitems.length;comboitems++){
comboitemarray[comboitems] = listitems[comboitems].item;
}
dynamicformfield = new Ext.form.ComboBox({
id: fieldname,
fieldLabel: fieldlabel,
name: fieldname,
editable: false,
autoSelect : true,
store: comboitemarray,
queryMode: 'local',
});
Any idea? Or am I missing anything here?
You gave an Array as store :
store: comboitemarray
Where it expects an Ext.data.Store. Implement an Ext.data.ArrayStore() from that comboitemarray array . Check the documentation of ArrayStore and always test in firebug for the errors.
I behaves that way because it's not a select-box, it's a combo-box.
If you had the following items:
a
aa
aaa
and you selected "aa", there would then be two options in the box: 'aa', and 'aaa'.
If you think carefully about how you'd like it to work, you'll realize that to get what you want will break ability to have any sort of meaningful type-ahead functionality.

JQGrid Dynamic Select Data

I have utilised the example code at Example Code at this link
and I have got my grid to show a dynamically constructed select dropdown on add and edit. However when it is just showing the data in the grid it shows the dropdown index instead of its associated data. Is there a way to get the grid to show the data associated with the index instead of the index itself.
e.g. the data on my select could be "0:Hello;1:World"; The drop down on the edit/add window is showing Hello and World and has the correct indexes for them. If the cell has a value of 1 I would expect it to show World in the grid itself but it is showing 1 instead.
Here is the row itself from my grid:
{ name: 'picklist', index: 'picklist', width: 80, sortable: true, editable: true,
edittype: "select", formatter: "select", editrules: { required: true} },
I am filling the dynamic data content in the loadComplete event as follows:
$('#mygrid').setColProp('picklist', { editoptions: { value: picklistdata} });
picklist data is a string of "0:Hello;1:World" type value pairs.
Please can anyone offer any help. I am fairly new to JQGrids so please could you also include examples.
I know you have already solved the problem but I faced the same problem in my project and would like to offer my solution.
First, I declare a custom formatter for my select column (in this case, the 'username' column).
$.extend($.fn.fmatter, {
selectuser: function(cellvalue, options, rowdata) {
var userdata;
$.ajax({
url:'dropdowns/json/user',
async:false,
dataType:'json',
cache:true,
success: function(data) {
userdata = data;
}
});
return typeof cellvalue != 'undefined' ? userdata[cellvalue] : cellvalue ;
}
});
This formatter loads up the mapping of id and user in this case, and returns the username for the particular cellvalue. Then, I set the formatter:'selectuser' option to the column's colModel, and it works.
Of course, this does one json request per row displayed in the grid. I solved this problem by setting 10 seconds of caching to the headers of my json responses, like so:
private function set_caching($seconds_to_cache = 10) {
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");
}
I know this solution is not perfect, but it was adequate for my application. Cache hits are served by the browser instantly and the grid flows smoothly. Ultimately, I hope the built-in select formatter will be fixed to work with json data.
If you save in jqGrid ids of the select elements and want to show the corresponding textes then you should use formatter:'select' in the colModel (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter#formatter_type_select) together with the edittype: "select".
The Usage of stype: 'select' could be also interesting for you if you plan to support data searching.