I created a form with nested container, fieldset and there a few checkbox on the form too.
as far as the form.getValues() can do it extract all values except the checkboxes so I want to extract the fields value manually. However the code sample I found so far
var values = {};
form.items.each( function(f) {
values[f.getName()] = f.getValue();
});
not work because the loop can get only the container, fieldset etc but not the actual field (textfield, combo etc). Could someone show me how to proper recursively extract all the field value?
Thanks.
It's because checkboxes dont hava a getSubmitData() which getValues() uses.
Try yourForm.getFieldValues() instead.
In ExtJs 4.0 you can use:
var fieldValues = Ext.getCmp('yourForm').form.getFieldValues();
Related
I wrapped my gridview with Pjax widget like this
\yii\widgets\Pjax::begin();
gridview
\yii\widgets\Pjax::end();
in order to make the gridview make ajax request when I click on each pagination.
I also use ['class' => 'yii\grid\CheckboxColumn'], in column as well.
and I find that when I'm on first pagination I checked some rows and then go to second page and check some rows but when I go back to first page what I've checked is gone.
My question is how can I keep all checkedrow for all pagination
With current conditions (Pjax, multiple pages, yii\grid\CheckboxColumn) it's impossible because of the way it works.
When you click on the pagination links all GridView html content is replaced by new one that comes from the AJAX response.
So obviously all selected checkboxes on the previous page are gone.
Few possible ways to solve that:
1) Write custom javascript and server side logic.
As one of the options, you can send AJAX request to server with parameter meaning that user has chosen to select all data for the bulk delete operation (or use separate controller action for bulk deletion). In this case actually we don't need to get the selected data from user, because we can simply get them from database (credits - Seng).
2) Increase number of displayed rows per page.
3) Use infinite scroll extension, for example this.
4) Break desired action in several iterations:
select needed rows on first page, do action (for example, delete).
repeat this again for other pages.
You can get selected rows like that:
$('#your-grid-view').yiiGridView('getSelectedRows');
[infinite scroll] : http://kop.github.io/yii2-scroll-pager/ will work good if you do not have any pjax filters. If you have filters also in play, do not use this plugin as it does not support pjax filters with it. For rest of the applications it is perfect to use.
Update1 : it seems to be straight forward than expected, here is the how I accomplished it
Add following lines to the checkbox column
'checkboxOptions' => function($data){
return ['id' => $data->id, 'onClick' => 'selectedRow(this)'];
}
Now add following JS to the common js file you will have in your project of the page where this datagrid resides
var selectedItems=[]; //global variable
/**
* Store the value of the selected row or delete it if it is unselected
*
* #param {checkbox} ele
*/
function selectedRow(ele){
if($(ele).is(':checked')) {
//push the element
if(!selectedItems.includes($(ele).attr('id'))) {
selectedItems.push($(ele).attr('id'));
}
} else {
//pop the element
if(selectedItems.includes($(ele).attr('id'))) {
selectedItems.pop($(ele).attr('id'));
}
}
}
Above function will store the selected row ids in the global variable array
Now add following lines to pjax:end event handler
$(document).on('pjax:end', function () {
//Select the already selected items on the grid view
if(!empty(selectedItems)){
$.each(selectedItems, function (index,value) {
$("#"+value).attr('checked',true);
});
}
});
Hope it helps.
I just solved this problem and it works properly with Pjax.
You may use my CheckboxColumn. I hope this can help. The checked items are recorded with cookies.
You can read the part with //add by hezll to understand how to fix it, because I didn't provide a complete general one.
Hope it works for you.
https://owncloud.xiwangkt.com/index.php/s/dGH3fezC5MGCx4H
I want to create a dropdownlist which have three static values: Select All, Text Only, Numeric only. After that I like to add a line with some padding (just to separate these options) and then add some dynamic options.
I am not sure how to do this, Can some body please help?
So far I have created a List<SelectListItem> in my view model, and populated the static values from BLL. But I am not sure how to add a divider line in the middle now, and append some dynamic options after that.
Thanks
The normal select tag will not work like that, you will have to create custom dropdown using spans or divs.
See some examples here:
http://tympanus.net/codrops/2012/10/04/custom-drop-down-list-styling/
I have a grouped Checkbox, and it has 4 checkboxes in it.
When the user selects a checkbox I need to filter a data store based on the value of the text box. When i select 2 textboxes, I get the output of ["Albert","Francis"], and when I select only the 1st textbox I get ["Albert"] and so forth.
Now, i need to know how to filter this ?
onCheckBoxGroupChange : function (field,newValue,oldValue,options) {
var chkv=newValue.chb;
console.log (chkv);
var st= Ext.getStore('People');
st.on('load', function() {
st.filter({
filterFn: function(rec) {
return rec.get('name') == chkv;
The problem I am having is, when I select both the CheckBoxes, chkv becomes ["Albert","Francis"] (Like an array), therefore I am unable to return the value since rec.get('name') == chkv; doesn't look for an array.
Can someone help me?
what about:
filterFn: function(rec) {
return Ext.Array.contains(chkv, rec.get('name'));
}
I want to make sure you know that you do not have to reload the store if you want to filter it. It looks like that is what you are doing in the snippet you provided above.
There are other problems actually, what your onCheckBoxGroupChange handler will actually do (if you leave it the way you have it above), is the following:
Every time a user clicks a checkbox it will first reload the store from the server, and then add the selected filter to the store's filters and then filter the store by the filters it has saved.
E.g.:
User clicks "Albert" checkbox
Store reloads
Store adds `["Albert"]` filter function
Store performs filtering with `["Albert"]` filter function
User clicks "Francis" checkbox
Store reloads
Store adds `["Albert", "Francis"]` filter function
Store performs filtering with `["Albert"]` filter function
Store performs filtering with `["Albert", "Francis"]` filter function
User unclicks "Albert" checkbox
Store reloads
Store adds `["Francis"]` filter function
Store performs filtering with `["Albert"]` filter function
Store performs filtering with `["Albert", "Francis"]` filter function
Store performs filtering with `["Francis"]` filter function
You would just progressively get more and more filters. Plus unnecessarily reloading the store many times. I don't think that is what you are going for.
You should review the docs on datastore filtering for more data on how to go about this.
Also, in your question you said that you had this problem when you selected two checkboxes because it returned an array. According to the text of your question you are also getting an array when you select one checkbox (["Albert"]). It only has one item in it but it is an array.
That is why my solution (which requires your chkv variable to be an array) would work.
I have two related ComboBoxes ( continents, and countries ). When the continents ComboBox changes I request a XML from a certain URL. When I receive that XML i change the DataProvider for the countries ComboBox, like this:
public function displayCountryArray( items:XMLList ):void
{
this.resellersCountryLoader.alpha = 0;
this.resellersCountry.dataProvider = items;
this.resellersCountry.dispatchEvent( new ListEvent( ListEvent.CHANGE ) );
}
I dispatch the ListEvent.CHANGE because I use it to change another ComboBox so please ignore that (and the 1st line ).
So, my problem is this: I select "ASIA" from the first continents, then the combobox DATA get's updated ( I can see that because the first ITEM is an item with the label '23 countries' ). I click the combo then I can see the countries.
NOW, I select "Africa", the first item is displayed, with the ComboBox being closed, then when I click it, the countries are still the ones from Asia. Anyway, if I click an Item in the list, then the list updates correctly, and also, it has the correct info ( as I said it affects other ComboBoxes ). SO the only problem is that the display list does not get updated.
In this function I tried these approaches
Converting XMLList to XMLCollection and even ArrayCollection
Adding this.resellersCountry.invalidateDisplayList();
Triggering events like DATA_CHANGE and UPDATE_COMPLETE
I know they don't make much sense, but I got a little desperate.
Please note that when I used 3.0.0 SDK this did not happen.
Sorry if I'm stupid, but the flex events are killing me.
Setting the dataprovider of the comboBox' dropdown seems to fix this problem.
this.resellersCountry.dataProvider = items;
this.resellersCountry.dropdown.dataProvider = items;
this.resellersCountry.dropdown.dataProvider = items;
works (Flex SDK 3.5)
Hope this bug fixed in 4.0
In addition to Christophe´s answer:
When you are using data binding in your ComboBox you need to use the BindingUtils to set the dropdown´s dataprovider:
MXML:
<mx:ComboBox id="cb_fontFamily"
width="100%"
dataProvider="{ model.fontFamilies }" />
Script:
private function init():void
{
BindingUtils.bindSetter(updateFontFamilies, model, "fontFamilies");
}
private function updateFontFamilies(fontFamilies:ArrayCollection):void
{
if (cb_fontFamily != null) cb_fontFamily.dropdown.dataProvider = fontFamilies;
}
Thanks to Christophe for pointing in the right direction.
Another workaround, outlined in an Adobe Community forum post, is to avoid re-assigning a different ArrayCollection object to the ComboBox, and instead re-using (and re-populating) the original one instead:
items.removeAll();
for each (var item:* in newItems)
{
items.addItem(item);
}
I have a Zend_Form that has 4 or more subforms.
/**
Code Snippet
**/
$bigForm = new Zend_Form();
$littleForm1 = new Form_LittleForm1();
$littleForm1->setMethod('post');
$littleForm2 = new Form_LittleForm2();
$littleForm2->setMethod('post');
$bigForm->addSubForm($littleForm1,'littleForm1',0);
$bigForm->addSubForm($littleForm2,'littleForm2',0);
On clicking the 'submit' button, I'm trying to print out the values entered into the forms, like so:
/**
Code snippet, currently not validating, just printing
**/
if($this->_request->getPost()){
$formData = array();
foreach($bigForm->getSubForms() as $subForm){
$formData = array_merge($formData, $subForm->getValues());
}
/* Testing */
echo "<pre>";
print_r($formData);
echo "</pre>";
}
The end result is that - all the elements in the form do get printed, but the values entered before posting the form don't get printed.
Any thoughts are appreciated...I have run around circles working on this!
Thanks in advance!
This is what I did -
$bigForm->addElements($littleForm1->getElements());
Then, iterated over the form elements like so:
$displayGroup1 = array();
foreach($bigForm->getElements() as $name=>$value){
array_push($displayGroup1, $name);
}
Then, add a displayGroup to $bigForm:
$bigForm->addDisplayGroup($displayGroup1, 'test',array('legend'=>'Test'));
And repeat for multiple display groups.
I'm sure there is a better way to do it, but I'm currently unable to find one out.
This is currently one way I can think of to retrieve all the form values via $_POST, if a form is made up of one or more subforms.
If any one knows of a better solution, please post it!
A Zend_Form does not automatically retrieve values from the $_POST variable. Use:
$bigform->populate($_POST)
Or alternatively:
$bigform->populate($this->_request->getPost())
Another thing to keep in mind is that if the sub forms contain elements with the same name they will clash. To check this use the option View => Page Source in your browser and look at the HTML that is generated. When you see two <input> elements with the same name attribute, then this is the problem.
The Zend solution for this is to give the sub form elements different names using setElementsBelongTo:
$littleForm1->setElementsBelongTo('littleForm1');
$littleForm2->setElementsBelongTo('littleForm2');
Furthermore you should leave out these calls as they serve no purpose (but you should set them for the $bigForm):
$littleForm->setMethod('post');