Federico Posted February 8, 2018 Share Posted February 8, 2018 Hi all, I have to create a form in admin by populating inputfield from multiple pages. It's all fine now, except how multilanguage inputfields are displayed, because no text field is rendered. This is the tree structure - parent page -- children_01 --- Grandchildren_01_1 (this page has inputfields to be displayed in the fieldset form) --- Grandchildren_01_2 (same as above for all following grandchildren pages) --- Grandchildren_01_3 -- children_02 --- Grandchildren_02_1 --- Grandchildren_02_2 --- Grandchildren_02_3 --- Grandchildren_02_4 --- Grandchildren_02_5 This is a sketch to illustrate how the final result looks like: My code so far look like this: public function ___execute() { $page_01_reports = $this->pages->get(1038); $wrapper = new InputfieldWrapper(); foreach($page_01_reports->children() as $childs) { // loop of three pages $fieldset = wire('modules')->get('InputfieldFieldset'); $fieldset->label = __("$childs->name"); $wrapper->append($fieldset); foreach($childs->children() as $child) { // loop of final/targeted grandchildren pages $fieldset2 = wire('modules')->get('InputfieldFieldset'); $fieldset2->label = __("$child->name"); $fields = $child->getInputfields(); foreach($fields as $field) { $fieldset2->append($field); } $btn = $this->modules->get("InputfieldButton"); $btn->href = "{$this->wire('config')->urls->admin}/reports/custom"; $btn->icon = 'plus-circle'; $btn->value = "Export for $child->name"; $btn->aclass = "classeAnchor"; $btn->addClass = "pw-modal"; $btn->id = "ID"; $fieldset2->append($btn); $fieldset->append($fieldset2); } } return $wrapper->render(); } and this is the weird multilanguage inputfield as rendered in the form: Do you have any hint to give? Maybe with this? $this->page->of(false); thank you a lot Link to comment Share on other sites More sharing options...
Federico Posted February 8, 2018 Author Share Posted February 8, 2018 Deleted post Link to comment Share on other sites More sharing options...
Robin S Posted February 10, 2018 Share Posted February 10, 2018 The bare bones are: $form = $this->modules->InputfieldForm; $parent = $this->pages(1234); // Get the parent page foreach($parent->children as $child) { if(!$child->hasChildren) continue; $fs_level_1 = $this->modules->InputfieldFieldset; $fs_level_1->label = $child->title; $fs_level_1->collapsed = Inputfield::collapsedYes; foreach($child->children as $grandchild) { $inputfields = $grandchild->getInputfields(); $fs_level_2 = $this->modules->InputfieldFieldset; $fs_level_2->label = $grandchild->title; $fs_level_2->collapsed = Inputfield::collapsedYes; $fs_level_2->add($inputfields); $fs_level_1->add($fs_level_2); } $form->add($fs_level_1); } // Add submit button or anything else here // ... return $form->render(); 1 Link to comment Share on other sites More sharing options...
Federico Posted February 10, 2018 Author Share Posted February 10, 2018 Thanks Robin, works properly - my code was too dirty with redundant parts while yours look pretty neat. I had to change it a little in order to ignore some specific fields, such as title: $form = $this->modules->InputfieldForm; $page_01_reports = $this->pages->get(1038); $ignorefields = array("title"); foreach($page_01_reports->children as $child) { if(!$child->hasChildren) continue; $fs_level_1 = $this->modules->InputfieldFieldset; $fs_level_1->label = $child->title; $fs_level_1->collapsed = Inputfield::collapsedNever; foreach($child->children as $grandchild) { $inputfields = $grandchild->getInputfields(); // new fieldswrapper needed to get rid of selected fields in $ingorefields $fieldswrapper = new InputfieldWrapper(); foreach($inputfields as $field) { if(in_array($field->name, $ignorefields)) continue; $fieldswrapper->add($field); // rebuilding the final fieldswrapper(s) to feed the InputfieldFieldset } $fs_level_2 = $this->modules->InputfieldFieldset; $fs_level_2->label = $grandchild->title; $fs_level_2->collapsed = Inputfield::collapsedYes; $fs_level_2->add($fieldswrapper); // add a submit button to the form $submit = wire('modules')->get('InputfieldSubmit'); $submit->attr("value","$grandchild->title"); $submit->attr("id+name","submit_$grandchild->id"); //1061 $fs_level_2->add($submit); $fs_level_1->add($fs_level_2); } $form->add($fs_level_1); } // Add submit button or anything else here //.... // render final form output return $form->render(); Link to comment Share on other sites More sharing options...
Federico Posted February 10, 2018 Author Share Posted February 10, 2018 @Robin S maybe (for sure) you know why I can't get input vars from the above form, this code is located in module init() if($this->input->post->submit) { echo "There are " . count($this->input->post->submit) . " post variables <br /> <hr>"; foreach($this->input->post->submit as $key => $value) echo htmlentities("$key = $value") . "<br />"; } I see the submit button actually submitting the form, but no vars are rendered from the above code, it just says there are 1 post variables regardless the real number of values submitted for several inputfields + Tracydebbuger says that the $value is an invalid argument Invalid argument supplied for foreach() Thank you very much Link to comment Share on other sites More sharing options...
Robin S Posted February 10, 2018 Share Posted February 10, 2018 25 minutes ago, Federico said: I see the submit button actually submitting the form, but no vars are rendered from the above code $this->input->post->submit is a single post variable with the name "submit". To get all your post variables you want to use $this->input->post. But I think you will find a problem in that if two or more of your grandchildren pages share the same the same template then the inputfields on those pages will share the same names. Meaning that the post variables will be overwriting each other when the form is submitted. So you will need to find a way to rename the inputfields in your form so each inputfield has a unique name. Something like this might work, which prepends the page ID to the inputfield name: // ... foreach($inputfields as $field) { if(in_array($field->name, $ignorefields)) continue; $field->name = $grandchild->id . '_' . $field->name; // make name unique by prepending the page ID $fieldswrapper->add($field); } // ... Link to comment Share on other sites More sharing options...
Federico Posted February 10, 2018 Author Share Posted February 10, 2018 I've also implemented pretty much the same conf to make each inputfields name unique, many thanks for this hint. Fortunately, In may case I have submit buttons for each grandchildren inputfields wrappers, so once a user submit the form by clicking one grandchildren form button, only the related form vars will be taken into account with this standard conditional if($this->input->post->submit_1061) // only inputfields for the grandchildren form with ID 1061 therefore there shouldn't be any issue related to overwriting fields I guess. However, the major issue I am facing is that I cannot retrieve vars from the post submission Link to comment Share on other sites More sharing options...
Robin S Posted February 10, 2018 Share Posted February 10, 2018 9 hours ago, Federico said: Fortunately, In may case I have submit buttons for each grandchildren inputfields wrappers, so once a user submit the form by clicking one grandchildren form button, only the related form vars will be taken into account No, a form doesn't work that way. The way you have it set up now you have a single form with multiple submit buttons. It doesn't matter which submit button you click, the submitted form data will be the same. The thing is that the name of each post variable is determined by the name of the input element it corresponds to. Where you have multiple inputs with the same name (which you will have unless you rename them using something like what I suggested before) only the last input of each name will actually make it into post. Although you could change to having multiple forms (one for each grandchild page) I don't think the idea of multiple submit buttons is a good one. Where users see multiple fields from multiple pages in the same module interface the expectation will be that they can edit all of these fields at once. But in fact all changes they make besides those inside the form they click the submit button for will be lost. Users might not notice that which could cause problems, or they might notice it and report it to you as a bug. You don't really want either of those. A single form with a single submit button would be better, then you loop through the submitted form data and use the added page ID prefix to connect it to the relevant page. But remember you need to sanitize all the submitted data. It looks like you're sort of recreating ProcessPageEdit with your module here - have a look at ProcessPageEdit::processInput to get an idea of the kinds of things to look out for. 9 hours ago, Federico said: However, the major issue I am facing is that I cannot retrieve vars from the post submission If the action of your form points to your Process module page (which it will do by default unless you changed it) then all the post data will be accessible in the init() method of your module, as you are already trying. But as I said above, the array of data is in $this->input->post. You mentioned you have Tracy installed - so do... bd($this->input->post); ...in your init() method and you will see the post data you have available. 3 Link to comment Share on other sites More sharing options...
adrian Posted February 10, 2018 Share Posted February 10, 2018 39 minutes ago, Robin S said: You mentioned you have Tracy installed - so do... bd($this->input->post); ...in your init() method and you will see the post data you have available. You don't even need to do that If you have the Request Info panel running, you will see the POST variables automatically populated - depending on your scenario it might be in the main bar, or the "redirect" bar., 4 Link to comment Share on other sites More sharing options...
Federico Posted February 11, 2018 Author Share Posted February 11, 2018 13 hours ago, Robin S said: No, a form doesn't work that way. The way you have it set up now you have a single form with multiple submit buttons. It doesn't matter which submit button you click, the submitted form data will be the same. The thing is that the name of each post variable is determined by the name of the input element it corresponds to. I do not know why I didn't think about that, in fact regardless the number of submit buttons (equal to the number of grandchildren in my case), the form is only one and therefore the submitted data will be always the same (involving all inputfields from all grandchildren pages). [thanks Robin] Dealing with this, my scenario is to see whether the form (submit_form_report) is submitted from the init() if($this->input->post->submit_form_reports) { $this->executeFormInputsProcessing(); } If yes, then I have to check every single inputfield to sanitize and whitelist them, like this protected function executeFormInputsProcessing() { foreach($this->input->post->submit_form_reports as $key => $value){ if(empty($value)) continue; // discard empty values // processing inputfields as a single item - is it the most appropriate way doing this one by one...? if ($key == '1061_reports_manager') { // page array $p = $this->pages->get($value); $pname = $p->name; // grab the page and its name $var_array = array(); foreach ($value as $a) { $var = $this->sanitizer->pageName($a); // sanitize all values (page reference array) $var_array[] = $var; } $this->input->whitelist('something', $var_array); //$input->whitelist('expertise', implode(',', $var_array)); } } } not sure though if I have to duplicate every conditional if($key == 'somethingAgainstToCheck') for each inputfield, as I have like 50 inputfields overall and it will not really handy when scaling Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now