Jump to content

Recommended Posts

Posted

Don't Show API Form Labels 

(If I may add this here for the sake of completeness.)

I have been looking for a way to leave the label out of the markup that does not involve recreating a module (a silly thing to do). The solution we have been using up until this point was a blank label. (Resulting in unnecessary markup and a negative margin.) However curiosity took me to the Inputfield module. Hey great job on these fields BTW. Reading the file I came across these options.

const skipLabelNo = false; // don't skip the label at all (default)
const skipLabelFor = true; // don't use a 'for' attribute with the <label>
const skipLabelHeader = 2; // don't use a ui-widget-header label at all
const skipLabelBlank = 4; // skip the label only when blank

// wire/core/Inputfield.php

Found in: in Inputfield.php 

The best solution I found to use this in a form builder. (I would like to credit this to somma's comment on checkbox-other-text-in-header-than-label-text)

//controller.php
$submit = $modules->get("InputfieldSubmit");
$submit->skipLabel = Inputfield::skipLabelBlank; //HERE IS THE SOLUTION!
$submit->attr("value","SUBMIT");
$submit->attr("id+name","submit");
$submit->attr("class","button");
$form->append($form_submit);

Thank you Somma!

Thank you Ryan!

  • Like 10
Posted

Nice first post - very useful to know as I've scratched my head over this before, thanks! :)

  • 4 weeks later...
Posted

HowTo: InputfieldWrapper classes (Question)

Adding classes to the wrapper via a hook.

So here I am again. Wrestling with the API form. Love it and know I don't know enough to say anything bad about it. I am certain that there is a way to do most things you want when using the Processwire API. 

Short Description

What I am trying to achieve is have all the Inputfields in my form render with unique classes. Why I am trying to do this is I am using a CSS-Framework that has an insanely intuitive grid system and would like to use these classes in the form. So when at render I will output the classes specific to that field. Hooking is one way I have thought of that might be plausible but, as mentioned I don't know how best to do it due to my limited knowledge of ProcessWire. I am open to other suggestions too.

Method

Create a form as in the feed done like Soma has suggested. Add to the form a markup and class array. Now add the fields you desire. In short...

<?php /* contact_contoller.php */
// And a whole lot more code
function hookAppendClassName($event) {
  $otherEvent = $event->arguments(0); // grab event provided to PageRender::renderPage
  $className = " [classes for the grid]";
  $classes_array = $otherEvent->object->getParent()->getClasses();
  $classes_array = array_merge($classes_array, array('item' => $classes_array['item']." ".$className));
  $otherEvent->object->getParent()->setClasses($classes_array);
  $otherEvent->return = $event;
  $event->replace = true;
}
function createForm() {
  $form = $modules->get("InputfieldForm");
  $form->setMarkup(array(
    'list' => "<div {attrs}>{out}</div>",
    'item' => "<div {attrs}>{out}</div>",
    'item_label' => "<label for='{for}'>{out}</label>",
    'item_content' => "{out}",
    'item_error' => "<p>{out}</p>",
    'item_description' => "<p>{out}</p>",
    'item_head' => "<h2>{out}</h2>",
    'item_notes' => "<p class='notes'>{out}</p>",
  ));

  $form->setClasses(array(
    'list' => '[list-class]',
    'list_clearfix' => '',
    'item' => '{class}',
    'item_required' => '',
    'item_error' => '',
    'item_collapsed' => '',
    'item_column_width' => '',
    'item_column_width_first' => ''
  ));

  $form_name = $modules->get("InputfieldText");
  $form_name->addHookBefore('renderValue', $this, 'hookAppendClassName');
  $form_name->label = "Name";
  $form_name->setParent($form);
  $form_name->required = 1;
  $form_name->attr('id+name','name');
  $form_name->attr('placeholder','Name');
  $form_name->attr('class','');
  $form->append($form_name);
}

This code does not work. Was hoping someone could be of assistance. Here is my current output.

<html>
<form id="contact-form" class="InputfieldForm" name="contact-form" method="post" action="./" data-colspacing="1">
  <div class="[list-class]">
    <div class="InputfieldText" id="wrap_name">
      <label for="name">Name</label>
      <input id="name" class="InputfieldMaxWidth" name="name" type="text" maxlength="2048" placeholder="Name">
    </div>
  </div>
</form>
</html>

This is what i desire. Note the [list-class__item].

<form id="contact-form" class="InputfieldForm" name="contact-form" method="post" action="./" data-colspacing="1">
  <div class="[list-class]">
    <div class="InputfieldText [list-class__item]" id="wrap_name">
      <label for="name">Name</label>
      <input id="name" class="InputfieldMaxWidth" name="name" type="text" maxlength="2048" placeholder="Name">
    </div>
  </div>
</form>

Thanks in advance!

Posted

Your hook and method has a lot wrong.

If this all would work, then you would hook into Inputfield::render() and not Inputfield::renderValue();

And a hook to do what you wanted would look more like this:

function hookAppendClassName($event) {
  $className = " mygrid";
  $classes_array = $event->object->getParent()->getClasses();
  $classes_array = array_merge($classes_array, array('item' => $classes_array['item']." ".$className));
  $event->object->getParent()->setClasses($classes_array);
}

But this is not possible. When a inputfield is rendered in the inputfieldwrapper, the classes and markup is already set and you can not overwrite it at that moment in time.

I also was looking into this and by chance I found a line of code in latest dev, that seems to be added recently. InputfieldWrapper rendering method looks for a $inputfield->wrapClass, I didn't know was there.

So you can now simply do this:

$field = $modules->InputfieldText;
$field->label = "Name";
$field->wrapClass = "mysuperlol-col1--wonder__toootooo";
...
  • Like 6
Posted

Thanks Soma

Thanks Soma. That should work. Busy downloading Processwire from Github now. I see my mistakes now. I had it correctly but changed it to the wrong code and did not fully correct it when I uploaded the code. Sorry about that renderValue.

The only issue I have with this method is that it comes from the dev branch. Production should be kept separate from dev in my opinion.

Posted

I'm trying to get a image upload working with the form api. 

	$field = $modules->get("InputfieldImage");
	$field->attr('id+name','images');
	$field->required = 0;
	$field->destinationPath = $config->uploadTmpDir;
	$field->extensions = "jpg jpeg gif png";
	$field->maxFilesize = 2*1024*1024;
	$field->maxFiles = 1;
	$field->skipLabel = Inputfield::skipLabelBlank;
	$form->append($field);

But if I call 

$form->processInput($input->post);

I get this error: 

Error: Exception: Nicht zulässiges Bild (in /Users/Benni/Projekte/A-06-2014_HONourables/www2/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module line 282)

or with InputfieldFile

Error: Exception: New page '/mitglieder/postfach/conversation-2014-09-06-10-59/' must be saved before files can be accessed from it (in /Users/Benni/Projekte/A-06-2014_HONourables/www2/wire/core/PagefilesManager.php line 240)

I don't understand why this is trying to create a page in this location, which is the location of the page, which shows the form. The file is supposed to be for a page further down the hierarchy. Also the only template allowed as child of "postfach" doesn't even have a image field which could serve as temporary storage. 

I could use own upload processing, but I would much rather stay consistent with the form api.

  • Like 1
Posted

@Soma
Thanks for your example, but the errors I posted above are happening while "$form->processInput()". I've read the thread and your previous examples, but I can't see what I'm doing different. 

Posted

I have no idea to be honest. Works fine here. But I'm not using InputfieldImage but InputfieldFile.

  • Like 1
Posted

I try to generate a form from a (multidimensional) array and searching for the best data format... any suggestions?

It have to map 

1) form / field values

$form->method = 'post';
$form->set('method', 'post'); // should work to?

2) form / field attributes

$form->attr('id+name', 'myForm');

3) defined Inputfield type like

InputfieldText
InputfieldSubmit
...

First array format is something like this...

$formField = array('module' => 'InputfieldText', 
                   'attr' => array('key' => 'value'),
                   'set' => array('key' => 'value'));

So I can cutting attributes, ...

But it looks... confusing *g*

*UPDATE*

But could be parsed with a function like that (untested)...

    protected function createFormFields() {
        foreach ($this->option['formFields'] as $formField) {
            $field = $this->modules->get($formField['module']);            
            
            foreach ($formField['set'] as $key => $values) {
                $field->set($key, $value);
            }
            foreach ($formField['attr'] as $key => $values) {
                $field->attr($key, $value);
            }
            $inputfields[$field->name] = $field;
        }
        return $inputfields;
    }

$this->option['formFields'] is a multidimensional array with the form data / config...

Posted

The problem ist to find a "simple" data structur as configuration to my form helper.
But also should be parsed without much overhead...

Posted

The problem ist to find a "simple" data structur as configuration to my form helper.

But also should be parsed without much overhead...

any associative array as:

  • json
  • serialized array
  • or still as php array

??

Posted

tried to remove all classes from Inputfield and set one single new class. Expected class="loggy" get class="loggy InputfieldMaxWidth". Why? Which method will remove all classes persistent?
 

	$form = $modules->get('ProcessLogin');
	$form->addHookAfter('buildLoginForm',null, function ($event) {
		$new = $event->return;
		$new->get('login_pass')->removeAttr('class'); // removes: class="whatever"
		$new->get('login_pass')->setAttribute('class','loggy');// adds: class="loggy InputfieldMaxWidth" and not class="loggy"
		$event->return = $new;
	});
	echo $form->execute();

Posted

You can't I guess. PW needs those helper classes. After all it's never intended to be used for front-end. So expect some compromises.

  • 2 months later...
  • 1 month later...
Posted

How could I change individual field markup and class ?

The default html markup is not or to much for bootstrap.

For example, each input element is wrapped by a div, this html markup is too much and I want to get rid of it.

Posted
$submit = $modules->get("InputfieldSubmit");
$submit->attr("value","Submit");
$submit->attr("name","submit");

how to get rid of the label of a submit button ?

Even though I don't provide the label attribute, it will use the name attribute as the label name

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...