Jump to content

AsmSelect Label Field (multiple fields?)


Hani
 Share

Recommended Posts

I'd love some direction on how best to tackle this issue. Under a Page field's configuration, you're able to "select the page field that you want to be used in generating the labels for each selectable page." With that configuration, you're able to select only one field. I'd love to be able to use multiple page fields' values to generate the label.

For instance, my Page field allows me to select any of the users in PW. I'd love the labels to be a combination of their first name, last name, and email address - which are all separate fields.

What's the best way to approach this? Should I be looking at creating a new inputfield? If so, which module do I extend? InputfieldPage? Thanks for any guidance!

EDIT: Solution for ProcessWire 2.3.0 is out on GitHub: https://github.com/Hani79/Processwire_FieldtypePageWithLabels

Link to comment
Share on other sites

I don't think this is something that can be done in a straightforward manner unless you modify and replace InputfieldPage.module, where this label is assigned. However, it seems like a good idea and we can look at making this an option in the core module for the future.

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

I finally had a chance to take a stab at this - and I'm pleased with what I was able to do. I added the functionality directly in the core - in InputfieldPage.module as Ryan said I would have to do. I decided to leave the Label Field intact and simply add a couple more configurable fields. It makes sense to simply replace the Label Field (InputSelect) with the Multiple Label Field (AsmInputSelect) I added, but didn't want to remove the core functionality in case I missed some trickle-down implications. (Ryan, would there be any?)

What this does is add two configuration fields to the Page fieldtype. The first allows you to define multiple fields to use as the label for selectable pages. It simply gives you a combination of the selected values imploded with " - ". The second field I added (a text field) allows for ultimate flexibility; you can define the pattern to use for the label, so you can do things like:

{title}, {parent->title}

Anyway, here's what I did in the InputfieldPage.module:

After line 28 in the $defaultConfig array, add the following:

'labelFieldNames' => '',
'labelFieldNameCustom' => '',

Replace line 114 in the getInputfield() function with the following:

if ($this->labelFieldNameCustom) {
$label = preg_replace('/{(.*?)}/ie','$child->$1', $this->labelFieldNameCustom);
}  else if ($this->labelFieldNames) {
$labelItems = array();
foreach ($this->labelFieldNames as $f) {
	$labelItems[] = $child->get($f);
}
$label = implode(' - ', $labelItems);
} else {
$label = $this->labelFieldName ? $child->get($this->labelFieldName) : $child->name;
}

After line 367 in the ___getConfigInputfields() function, add the following:

// MULTIPLE FIELD LABELS
$field = $this->modules->get('InputfieldAsmSelect');
$field->setAttribute('name', 'labelFieldNames');
$field->setAttribute('value', $this->labelFieldNames);
$field->label = 'Label Field (Multiple Page Fields)';
$field->description = "Select the page fields that you want to be used in generating the labels for each selectable page. This setting supercedes the single field label option.";
$field->collapsed = Inputfield::collapsedBlank;
if ($this->fuel('fields')->get('title')) {
$field->addOption('title', 'title (default)');
$field->addOption('name', 'name');
$titleIsDefault = true;
} else {
$field->addOption('name', 'name (default)');
$titleIsDefault = false;
}
$field->addOption('path', 'path');
foreach ($this->fuel('fields') as $f) {
if (!$f->type instanceof FieldtypeText)
	continue;
if ($f->type instanceof FieldtypeTextarea)
	continue;
if ($titleIsDefault && $f->name == 'title')
	continue;
$field->addOption($f->name);
}
$inputfields->append($field);

// CUSTOM FIELD LABELS
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'labelFieldNameCustom');
$field->attr('value', $this->labelFieldNameCustom);
$field->label = "Label Field (Custom)";
$field->description = "Define the page fields (enclosed in braces) that you want to be used in generating the labels for each selectable page. This setting supercedes the multiple field label option.";
$field->notes = 'Example: {title}, {parent->title}';
$field->collapsed = Inputfield::collapsedBlank;
$inputfields->append($field);

It's working beautifully for me!

Ryan - does it look like I missed anything? I saw that labelFieldName was referenced in the ___renderAddable() function, but I wasn't sure what that does.

  • Like 1
Link to comment
Share on other sites

Hani, this looks like a good and well thought out solution. Thanks for posting. I can't think of any immediate issues here, so if it seems to be working well in your case, I think you should be good. The only thing I might suggest is copying it to a separate module in /site/modules/InputfieldPageCustom.module or something like that, so that you have a separate module that can be easily carried through version changes. If you do that, remember to update the class name too. It would also enable you to more easily share the module with others that had a similar need.

Link to comment
Share on other sites

Thanks for the feedback, Ryan. Great idea. Now, by copying it to a separate module, does it automatically override the core functionality? Meaning, should I keep InputfieldPage.module as it was before I tweaked it or should the core file keep the changes as well?

Edit: Nevermind! I should have tried before I even asked. Turns out it doesn't override the core functionality - which makes sense. I haven't come across forum posts or documentation that indicate how to override core modules. Is it safe to assume that you can't without replacing the core modules themselves, correct? (If so, I would guess this would be done so that the risk of other modules breaking due to dependencies is minimized.)

Link to comment
Share on other sites

In this case you would just be adding a new Page fieldtype (called something else) leaving the existing one as is. Then you'd edit your field (in setup > fields) and change the type to the new one you added.

Link to comment
Share on other sites

  • 3 weeks later...

I've tried making these suggested modifications without success. Could someone share the module version? This is exactly what I was looking for. Thanks guys!

EDIT: tried it again and it works now. Nevermind!

Link to comment
Share on other sites

Glad you got it to work, Evan! I've been bogged down with deadlines recently - but it's still on my radar to make this into a module. I'll definitely post it once it's done.

Link to comment
Share on other sites

  • 11 months later...
  • 2 months later...

I just tried to use FieldtypeConcat instead of implementing my modifications and it didn't seem to work.

While I was at it, I decided to make these into modules (compatible with PW 2.3.0).  Its out on GitHub: https://github.com/Hani79/Processwire_FieldtypePageWithLabels

Tested and seems to work just fine.  However, I have a question, Ryan.  I ended up simply duplicating the InputfieldPage and FieldtypePage modules and made my changes.  I did this rather than extending InputfieldPage and FieldtypePage.  Was that the right way to do it?

I tried to extend FieldtypePage itself, but was unsuccessful.  I was getting the following error:

 Class 'FieldtypePage' not found 

Which was referencing this line:

class FieldtypePageWithLabels extends FieldtypePage {
  • Like 1
Link to comment
Share on other sites

I ended up simply duplicating the InputfieldPage and FieldtypePage modules and made my changes.  I did this rather than extending InputfieldPage and FieldtypePage.  Was that the right way to do it?

In this case I think it's fine to do what you did, rather than extending. Though what you'll miss out on is when fixes or additions are made to the core modules, your module won't automatically inherit those. I usually try to extend or better yet, delegate, when it makes sense. But sometimes it can be a less direct path. So it does come down to how much time you want to put into it as well. 

 Class 'FieldtypePage' not found 

I'm not exactly sure why that would be occurring in your case–is your module file in /site/modules/? One way you can resolve it is to add this at the top, before the class declaration: include(wire('config')->paths->modules . 'Fieldtype/FieldtypePage.module'); or wire('modules')->get('FieldtypePage'); But I'm surprised you'd have to do that in this case, at least I've not had to when extending a core module. If running APC, you might want to apc_clear_cache(); just in case. 

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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