Jump to content

Module: FieldtypeSelectRelation


justb3a
 Share

Recommended Posts

I'm not quite sure if this is worth to be a module. But I needed it...

This Fieldtype creates a select list (drop down) in relation to another field (you can restrict the list by setting up certain templates and / or pages).

Installation:

1. Clone the module and place FieldtypeSelectRelation in your site/modules/ directory. 

git clone https://github.com/justonestep/processwire-fieldtypeselectrelation.git your/path/site/modules/FieldtypeSelectRelation

(or get it from the module page)

2. Login to ProcessWire admin and click Modules. 

3. Click "Check for new modules".

4. Click "install" next to the new FieldtypeSelectRelation module. 

Usage:

After installation, you'll have a new "Select" fieldtype that will allow you to define the items you'd like in the drop down depending on another field.

  • Create a new field and assign type SelectRelation
  • Click on the Details tab, there you find different fields to create your select list
  • Field: required, choose another field you created before from which the select list should be populated
  • Repeater: optional, if the field you chose is included in a repeater, select the repeater here
  • Template(s): optional, restrict your result by setting certain template(s)
  • Page(s): optional, restrict your result by setting certain page(s)
  • Unique Values: optional, check this field if you want to avoid duplicate values 
    (If you enable this, the string value will be saved instead of the ID. You will not be able to reference via ID.)
  • Including not only visible pages: optional, include all hidden and unpublished pages and pages that user doesn't have access to view
  • Multiple Output: optional, multiple selection (using ASMSelect)

Unique Values Disabled

If this field is not enabled the key is the pages_id and the value is the value from the other field.

<select id="Inputfield_chosen_fruit" name="chosen_fruit">
  <option value=""></option>
  <option selected="selected" value="1026">Strawberry</option>
  <option value="1030">Apple</option>
  <option value="1031">Banana</option>
  <option value="1032">Lemon</option>
</select>

Note:

If you change the value of a field the value changes too. If you deleted a value the value now is empty and multilingualism works like a charm.

Accessing the value:

// single select
echo $pages->get((int)$page->chosen_color)->color;

// multiple select
foreach ($page->chosen_color as $p) {
  echo $pages->get((int)$p)->color;
}

`chosen_fruit` and `chosen_color` are of the type SelectRelation.  

`title` is the page title and `color` a simple input field (TextLanguage for example).

In `chosen_fruit` the selected field is `title`.

And in `chosen_color` the selected field is `color`.

Unique Values Enabled

If this field is checked the key as well as the value are the value from the other field.

<select id="Inputfield_chosen_color" name="chosen_color">
  <option value=""></option>
  <option value="red">red</option>
  <option value="green">green</option>
  <option selected="selected" value="yellow">yellow</option>
</select>

If you don't check this box you might have duplicate colors (because there is more than one fruit which has a yellow color for example).  

BUT if you change the value of an field, your already chosen value stays the same, because there isn't a relation via ID.

Access such a field like you are used to:

// single select
echo reset($page->chosen_color);

// multiple select
foreach ($page->chosen_color as $p) {
  echo $p;
}

TL;DR:

I tried to save a comma separated list for duplicate values .It works until you change anything. For example, if you have two times the color yellow a key of the kind '1034,1036' may get saved. Now assume you change a basic color (the banana turns brown :D), the selected value is now empty because a key like '1034,1036' doesn't exist anymore. And in the frontend you may get a wrong output. 

  • Like 14
Link to comment
Share on other sites

I added two config options:

  • Including not only visible pages: optional, include all hidden and unpublished pages and pages that user doesn't have access to view
  • Multiple Output: optional, multiple selection (using ASMSelect)

Field settings:

field-settings.png

Select Lists:

(settings above -> first one)

fields.png

  • Like 5
Link to comment
Share on other sites

Thanks for this - I think it will come in very handy. Just a quick note though - looks like you did a find/replace just before submitting, because there are several instances of "FieldField" instead of just "Field", eg. $chooseFieldField and instanceof FieldFieldtypeRepeater - this is preventing your attempts for excluding a bunch of field types from the list of available fields.

PS I'd love to see support for Profields Table subfields :)

Link to comment
Share on other sites

Not sure I understand this module? Is this for creating relation between two page fields? When I select Europe, then in next field I can choose countries from Europe?

That is already supported in core. But there seems to be much more in this module than just that. Maybe I should just try this :)

  • Like 2
Link to comment
Share on other sites

I was a little confused at first too and thought it might work to generate dynamic/conditional dropdowns like you are describing with the Europe countries example - actually that is a field type that I think would be nice - I have been thinking about it the last couple of days actually :)

What this relation fieldtype does is create a dropdown field that lists the entries for the selected field from all the matched templates/pages. The option value is the ID of the page that has the entry. Clear as mud right :) Maybe you just need to try it :)

  • Like 2
Link to comment
Share on other sites

Adrian, no need for custom field for that. Just set parent=page.otherpagefield as selector value for your page field.

And thanks for the explanation, I got it!

Nope, I mean this: parent=page.manufacturer kind values for page fields "define selector to find pages". They create ajaxified UI for field relations.

  • Like 3
Link to comment
Share on other sites

Adrian, no need for custom field for that. Just set parent=page.otherpagefield as selector value for your page field. 

Wow - how did I miss (or maybe forget about) this - thanks :) That works perfectly!

PS Sorry for hijacking your thread here @justb3a

Link to comment
Share on other sites

Adrian no problem  :)  Indeed I appreciate this, it's always good to learn more and to get some feedback. I just started my second ProcessWire project and there is so much more to discover...

I tried to use the Page Fieldtype (parent=page.otherpagefield) but I got a complete different output. The point is that I don't want to get a whole page object, I need a plain value in order to receive this value using the ServicePages API. Unfortunately my use case is quite complex and you need a lot of background knowledge so I had to find another example.

Use case: Categorize Posts/Pages

"The common way": Create a single page for each category. Add a Page Inputfield, set up the parent page / template and you get a select list of categories (pages). Fine.

"My way": Create just one page to hold all categories in a repeater. Add a SelectRelation Inputfield, set up field=category, repeater=r_categories. Then you get "the same" list. If you need more than just the title (or any other field) you should use the Page Inputfield for sure.  

The difference is that you don't select a page, you select a field value depending on a page. I guess this should also work for Profield Table subfields but I didn't test it.

  • Like 3
Link to comment
Share on other sites

  • 4 weeks later...

@JoZ3: I'm not quite sure whether I understood your request right. You want to select an image to be the cover?

If so I would suggest using tags. Activate the `use tags?` checkbox in image settings and enter the tag "cover" (or something else) for the specific image.

post-2759-0-52140500-1424683153_thumb.jp

In your template you can pick this image using the following code (adapted to your needs / field names, ..):

page.images.getTag('cover');
  • Like 2
Link to comment
Share on other sites

@justb3a I think what @JoZ3 might mean is can this field be used to select an image from a multiple image field and use it on another page? For example (I think) he wants to use an image from a field on a product page on the home page but the image he wants is (fro example) the fifth one down in a field.

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

I did, but there are multiple parent pages with multiple child pages. The select is in the child and I'd like to dynamically populate the select with data from a repeater from the parent.

so:

_ parent1 (with repeater)

_ _ child1 (get from parent 1)

_ _ child2 (get from parent 1)

_ parent2 (with repeater)

_ _ child1 (get from parent 2)

_ _ child2 (get from parent 2)

_ _ child3 (get from parent 2)

I tried editing the module by adding an option to the choosepagesfield with $page->parent but I just ended up breaking it :P

Link to comment
Share on other sites

not tested, add in function getInputfield after line 153

// later: check before if this is enabled in field settings
if (!empty($page->parent_id)) {
  $selector[] = 'has_parent=' . $page->parent_id;
}

Please let me know if this works. I'll then add a checkbox in field settings and the depending check as well.

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

×
×
  • Create New...