PDA

View Full Version : Ext.Ajax.request - form submission with checkboxgroup



HTK
14 Oct 2013, 2:26 AM
Hello,
I have a problem with doing a form submit using a checkbox or radiogroup in ExtJs 4.2.2. All my checkboxes inside my CheckboxGroup have the same name and I am using an inputValue for them.

I recognized that my params object inside Ajax.request does have the right structure (i.e. field name = array with many inputValues of the selected checkboxes).

Iīve found out that inside the setOptions function of Ext.Ajax.request a call to Ext.Object.toQueryString is done. My problem is, that this call is done without the recursive parameter set. That means my query string which should contain array values contains values like : days=1&days=2&days=3 where it should be days[0]=1&days[1]=2 etc.

Isnīt the Ext.Object.toQueryString function meant to be called with the recursive parameter here? Using this parameter I got the correct query string, but I have to override the core.

What is the idea behind calling Ext.Object.toQueryString without recursive param true?

Thank you for your suggestions.

Arg0n
14 Oct 2013, 11:20 PM
So, what your are doing is: You ask your backend with Ext.Ajax.request for the data. And it would send back something like:



return array(
'days' => array(1, 2, 3)
);


So you are sending the data via GET and the QueryString stuff messes up some stuff. Do you need to send it via GET or could you also use POST? Because sending deep arrays via GET isn't so good xD

HTK
14 Oct 2013, 11:30 PM
Thank you for your answer. No it is a POST request form submission, but because of the structure of the query string my value at the PHP backend is array ('days' => 3), where 3 is the last selected value. In HTML I would use a name like days[] for my checkbox field.

But in all of their examples Sencha is using a name like : days. Using the HTML conform name days[] would in my opinion be kinda dirty if I am using a model with this field. For the model - form mapping I would have to name my model field : days[]. In my opinion this would lead to rare names in my models.

So what is right then? I would like to give a name like "days" and then the function that creates the queryString should see if I am using array values. And it does, but only if I am using the true parameter (for the recursive call) which is not used in Senchaīs core right now. So the queryString gets generated wrong in my opinion.

Arg0n
15 Oct 2013, 12:06 AM
It would be great if you could show some of your code. Your form view and how you do the Ajax stuff would be nice =D

HTK
15 Oct 2013, 12:12 AM
Sorry, this is somehow impossible. I am working on a CMS which is too complex to show simple examples here. Maybe I can write a testcase. But this moment there is no time for that.

HTK
15 Oct 2013, 1:28 AM
Here is my simple testcase:

<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="http://cdn.sencha.com/ext/commercial/4.2.1/resources/css/ext-all.css"/>
<script type="text/javascript" src="http://cdn.sencha.com/ext/commercial/4.2.1/ext-all.js"></script>
<script type="text/javascript">
Ext.onReady(function() {
var form = Ext.create('Ext.form.Panel', {
title: 'Testcase',
renderTo: Ext.getBody(),
height: 400,
width: 400,
items: [{
xtype: 'checkboxgroup',
columns: 2,
items: [{
xtype: 'checkbox',
boxLabel: 'Monday',
name: 'days',
inputValue: 1
}, {
xtype: 'checkbox',
name: 'days',
boxLabel: 'Tuesday',
inputValue: 2
}, {
xtype: 'checkbox',
boxLabel: 'Wednesday',
name: 'days',
inputValue: 3
}]
}],
buttons: [{
text: 'Submit',
handler: function() {
form.submit({
url: 'index.php'
});
}
}]
});
});
</script>
<body></body>
</html>

In my index.php I am just doing this:

<?php
var_dump($_POST);
?>

Now you can see that the last submitted value of the checkboxgroup is used. It is not submitted as array values. Naming the checkbox like that "days[]" works. But I think this would be confusing using model with form binding because the model than would need a field called days[] which would lead to function calls like model.get('days[]'). This is not really nice.

Arg0n
16 Oct 2013, 1:14 AM
To be clear what happens on submit:

The submit action will call getSubmitData on each element in the form. So the getSubmitData of a checkboxgroup looks like this (http://docs.sencha.com/extjs/4.2.2/source/CheckboxGroup.html#Ext-form-CheckboxGroup-method-getSubmitData).

So it's returning null. Great!! Or wait.. so it will call the getSubmitData for each checkbox then. Because of the fact, that every checkbox has the same name it will overwrite the data each time and the last value will be submitted then.

I don't think that this should be the behavior of a checkbox group...

What you could do:
Override the getSubmitData() from the original checkboxgroup class
Build your own checkboxgroup class which extends the original
Change the name of each checkbox into the real name of the day and making the inputValue 1 or true:


items: [{
xtype: 'checkbox',
boxLabel: 'Monday',
name: 'monday',
inputValue: true
}, {
xtype: 'checkbox',
name: 'tuesday',
boxLabel: 'Tuesday',
inputValue: true
}, {
xtype: 'checkbox',
boxLabel: 'Wednesday',
name: 'wednesday',
inputValue: true
}]

Override it with your own data:


handler: function() {
var data = form.getForm().getValues();

form.getForm().submit({
url: 'data.php',
params: {
data: Ext.JSON.encode(data)
}
});
}




<?php
require_once '../lib/ChromePhp.php';
$data = json_decode($_POST['data']);
ChromePhp::log($data);
?>


$data now contains an array with all selected days ^^
Alt + F4

HTK
16 Oct 2013, 1:37 AM
Thank you for your response. I already got a solution. But I think this should be fixed by Sencha.
Try to do a console.log of the params in Ext.Ajax.doRequest method in an override (at the end). You can see that the params will be in the right format. So the getValues function of the form delivers the correct params object. days will be an array of values.

But the Ext.Ajax.request interrnally uses setOptions function. In this function they call Ext.Object.toQueryString. This is where it goes wrong. This function has a second param. A boolean to do this conversion recursive. Doing an override of the setOptions function at this place and calling the toQueryString with param true solves the issue. The queryString will then contain array values for days.

Do a console log. You will recognize this: params correct, queryString wrong. And queryString gets submitted then.
I would like to hear someone from Sencha about this.

Arg0n
16 Oct 2013, 1:42 AM
You could open a bug :P

HTK
16 Oct 2013, 1:43 AM
If I would be sure it is a bug.

Arg0n
16 Oct 2013, 2:11 AM
Hmmm... and if you are lucky it will be fixed in version 9.2.3 in 2021 =D