Jump to content

Repeater, pages selector and "connected data"


moonwhaler
 Share

Recommended Posts

Hi there!

The title may be a bit misleading, or at least it's how I tried to achieve something which may not be possible in that combination. But let's start from the beginning: I'm trying to create a football team & game manager with processwire.

As someone who used Excel in all ways possible to manage every aspect of a football team (members, positions, games, etc.) and having used processwire for solely building websites in the past, I thought this has to work, too. And for the most part it does!

Yet, I have a few things which may work even better and that's where I'm stuck.

I currently manage:

  1. Team members (pages)
  2. Game positions (pages)
  3. Games (pages)

In "games" I have something like "location", "opponent", etc. and I have created a repeater field which includes "team member" (selector from page "team members") and "game position" (selector from "game positions"). I am able to map a "position" to a "team member" for each game. That's fine & well, BUT: it would nice, to have those selector being somehow connected to each other in a way, that if I am selecting a team member and assign him to a position, that this position & member will be deleted from other repeater "selectors".

This way I want to prevent a team member or game position to be used n-times in one game. It's just a usability thing, but a big one for me, since I may be not the person working with this in the future. :-[

Is this somehow possible?

Thank you!

  • Like 1
Link to comment
Share on other sites

I think you need to build a selector for your selection list with a pseudocode like: select all from teammembers that are not in games.position.teammembers

So, it depends on your fieldnames that you use in games.

Link to comment
Share on other sites

Do you need this to work on the frontend or in the admin part of processwire. On the frontend you can just use javascript to disable already selected players / positions and check on the backend, if nothing has gone wrong, before saving it. If you want to use the backend of processwire I think you've to build a custom InputfieldPage module, which does the job of disabling parts of the selectboxes to make positions / players unique to one game.

Link to comment
Share on other sites

Yep. It has to be some sort of "self-aware" selector. It should only display the names of the players / positions that not have been used yet.


Do you need this to work on the frontend or in the admin part of processwire. On the frontend you can just use javascript to disable already selected players / positions and check on the backend, if nothing has gone wrong, before saving it. If you want to use the backend of processwire I think you've to build a custom InputfieldPage module, which does the job of disabling parts of the selectboxes to make positions / players unique to one game.

Only in the admin part. :)

Link to comment
Share on other sites

Then you most likely need to write a own inputfield and/or whole fieldtype, as the only dependency current fieldtypes provide against other fields are dynamic required state and dynamic visibility. 

Edit: 

Another, less sophisticated, answer could also be to hook into page-save, check there if the requirements are met and just error if there are duplicate entries.

Link to comment
Share on other sites

After playing around a bit with PageTable I don't think this is a really good alternative to Repeater fields. I understand that it may be better performance wise, but Repeater are superior in terms of user interaction. A PageTable (as far as I understand it) is "just" another way of adding sub-pages to a page and then displaying them in a table on the parent page.

Repeaters, on the other side, are fast (looking at user input / UI wise) and responsive. Another thing is: I have to "name" a new page - in my case I have to name them "position1", "position2", etc. Repeaters don't need that (there's a automatic naming scheme #1, #2, ...)

Coming to the crux of my initial question: connected data. Since I really am a n00b, I didn't find the "setting" to create a custom code block for handling my "selector" drop downs. As far as I understand my situation, I have to create a new "field type" to reflect that. Am I right? :-[

Thank you!

Link to comment
Share on other sites

With you declaring yourself as pw noob I would strongly suggest, to give pagetables another try as this would be the far easier solution. 
 
From your post I assume that you're using the FieldtypeSelect module right now. This is a easy to begin fieldtype, but not very flexible. In your case you've to use the Page fieldtype. This is a type where you save a reference to the choosen page. This fieldtype can also be displayed as a select box, but also provides other input solutions.
 
The setup I would suggest would be:
 
Page Setup:
 
- Positions
    - …
- Players
    - …
- Games
    - Game 1 (game)

        - Line-Up Player 1 (lineup)

        - Line-Up Player 2

Template:

lineup

This template holds at least the first two fields below. With a custom naming convention you can define, you prevent the need of defining a custom name each time you add a page of this template.

 
Fields:
player
PageField

Here you can use the "custom php code for selectable pages" which is a option for that fieldtype:

$players = $pages->find("template=PLAYERTEMPLATE"); // All Players
$other_lineups = $page->parent->children; // All other Subpages, where Players are already choosen
// $page is one of the subpages, therefore the parent selector part

foreach($other_lineups as $lineup){
  $players->remove($lineup->player); // Remove unavailable Players
}

return $players; // Return the adjusted selection

position

PageField

Also use the custom php code, and just adapt my previous example for positions. 

lineup

PageTable

This pagetable is viewed in the game-template and let's you generate the lineup template, which should be used for the subpages of a game. 

The PageTable can show player.title and position.title in it's shown table, so you do have an overview in the game template, without the need to look into every subpage. 

With this setup everytime you add a new lineup subpage to a game, it removes already used positions and players from the fields.

  • Like 4
Link to comment
Share on other sites

Repeaters, on the other side, are fast (looking at user input / UI wise) and responsive. Another thing is: I have to "name" a new page - in my case I have to name them "position1", "position2", etc. Repeaters don't need that (there's a automatic naming scheme #1, #2, ...)

I agree that the PageTable field is not perfect in this sense, but there is a way around this:

Set up the Automatic Page Name Format option for the PageTable field and then go to the title field and adjust the settings in context of the template being used for the PageTable field content and uncheck required and set it to hidden. So it's still there, but at least it's not in the user's way. This way the page can be published without the title field.

Hope that helps a bit.

  • Like 3
Link to comment
Share on other sites

Hi guys,

here's a short list of my fields:

post-1971-0-08810500-1409259359_thumb.pn

and my current page structure:

post-1971-0-50693600-1409259359_thumb.pn

Sorry, it's german for the most part, but maybe you get the idea. Basically, there is a page "game list", "player list", "jersey list", "position list".

I already read that using simple "select" types is not recommended DB-wise, so I skipped that from the beginning. I mostly modelled the structure very similar to yours @LostKobrakai from the start.

Apart from that, I really like the "custom PHP code" approach. I didn't really saw that when using "Page" as field type. I will try that ASAP. So thank you for the kickstart! Also thanks to adrian for the heads up on the "Auto Page Name Format". I will definitely use that! ^-^

Link to comment
Share on other sites

Thank you LostKobrakai! This works like a charm.

One thing left though: when using "PageTable" and trying to add a new entry (Page) to the list, am I able to deny adding new "lineups" when there are no players / positions left to assign? Currently, I am able to add "blank" pages, since I have no more players in my Page selector.

Thanks again!

Link to comment
Share on other sites

This should be doable, but you need to hook into the pagecreation and if it's the "lineup" template, check if there are players/positions left for the current parent page.

I don't know how much you know about hooks, but this should provide a good introduction: http://processwire.com/api/hooks/. This should be the needed function to hook: https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/core/Pages.php#L428

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.

  • Similar Content

    • By joeck
      Hi,
      I'm facing the issue where i have a repeater field with a multi language textarea (german & english, german beeing default). In german more blocks should be displayed as in english.
      The textarea field is configured as inherit default language if blank (I don't want to change this since it is the wanted behaviour for all other pages...).
      Now I want to access the unformatted value of the textarea field in the repeater and only show it if it is not empty. Something like this:
      $body = ""; $page->of(false); foreach($page->blocks as $block){ //blocks is repeater field, each block has title and textarea if ($block->textarea->getLanguageValue($user->language)){ $body .= <<<EOD <div> <div class='uk-card uk-card-default uk-card-body'> <h3 class='uk-card-title'>$block->title</h3> $block->textarea </div> </div> EOD; } } $page->of(true); print $body; However this doesn't work: Call to a member function getLanguageValue() on string.
      I also tried the other syntax for getLanguageValue:
      $page->getLanguageValue($language, $field) But I didn't manage to get a unique name of the textarea field in the repeater.
      I looked into the API of FieltypeRepeater but couldn't find anyhting that fixed my issue.
      Any ideas?
    • By opalepatrick
      I see old posts saying that repeaters are not the way to go in Custom Process Modules. If that is the case, when using forms (as I am trying to do) how would one tackle things like repeat contact fields where there can be multiple requirements for contact details with different parameters? (Like point of contact, director, etc) or even telephone numbers that have different uses?
      Just for background I am creating a process module that allows me to create types of financial applications in the admin area (no need to publish any of this, pure admin) that require a lot of personal or company information.
      Maybe I am thinking about this incorrectly?
    • By spercy16
      I was previously using individual fields to capture and output multiple cards onto my web page but after recently learning about repeaters would prefer to use this field type, as it will be a lot more user friendly for end users to create new cards. I tried to modify my code to grab the fields from the new Repeater field(s) but am getting this error message on the page:
      Here is the code I'm currently trying to use for the cards:
      <?php // https://processwire.com/api/arrays/ // check if the array of images has items foreach($page->tall_card as $card) { $count = 0; $count++; $options = array( 'quality' => 70 ); $image = $card->image; $img = $card->image->size(550, 400, $options); $cardHeading = $card->title; $cardBody = $card->plain_paragraph; $raised = $card->raised_amount; $goal = $card->goal_amount; $link = $card->link; if ($raised == 0 ) : $percent = 0; else: $percent = $raised_amount / $goal_amount * 100; endif; if ($percent <= 5) : $percent = 0; endif; ?> <span id="card<?php echo $count?>" class="card"> <img class="cardThumb" src="<?php echo $img->url; ?>" alt="<?php echo $image->description; ?> Thumbnail" /> <div class="cardBody"> <div class="cardText"> <h2><?php echo $cardHeading; ?></h2> <?php echo $cardBody; ?> </div> <div class="progressBarSection"> <progress class="progressBar" id="progressbar<?php echo $count; ?>" value="<?php echo $percent; ?>" max="100"></progress> <span class="raisedAmount"> $<?php echo $raised; ?> usd </span> <span class="goalAmount"> $<?php echo $goal; ?> usd </span> </div> <div class="primaryBtn"> <a href="https://www.paypal.com/donate?hosted_button_id= <?php echo $link; ?> &source=url"> <button> <i class="fas fa-donate"></i> Donate </button> </a> </div> </div> </span> <?php } ?> Thanks in advance for any help!
    • By spercy16
      Coming from Perch (CMS) to Processwire, the one major downside I've found is that every place I want to insert content into my pages requires a single field (be that an image, integer, string, etc.). This can be a real pain to setup and manage if you have a lot of pages, many of them with dozens of unique fields. For example, on the Projects page of a site I'm working on right now I have to have fields for donate_amount (1-15, meaning fifteen unique fields that I have to duplicate manually), goal_amount(1-15), card_body(1-15), etc. After using Perch for a while, the way their system works is simply easier. You instead create your fields in a single PHP template (for every unique section, like a card) and their CMS imports those fields into the CMS when you choose to use that card, then you just fill in the values. You can also choose to reuse that card multiple times and each one you add gives you the several fields you need to fill in. So you can easily add your 15 cards, each with a picture, title, paragraph, and link, etc. and each one is basically given a unique ID that you can reference in your CSS files. If there's any way to make fields and templates work more like that, it would be a truly outstanding and efficient CMS. The great advantage of the way Perch is setup is that I can make a card with 10 fields, if need be, and easily duplicate that card out 40 times if I need 40 cards on the page and wouldn't need 10 fields for 40 cards (meaning in PW I would need 400 fields). If there's an easier way to do this in PW I would love to know, but as of right now, from what little I do know about the CMS 400 fields would be the only way to set that up, and that would be much more time consuming than if I could create one card (in PHP) with 10 fields that automatically added a number to the end of each field for each card (if that makes sense).
    • By Robin S
      Lister Selector
      A Process module that uses Lister/ListerPro, but with a selector string input instead of the normal InputfieldSelector filters.
      Features
      For power users, typing a selector string is often faster and more intuitive than fiddling with InputfieldSelector. It also lets you copy/paste selector strings that you might be using somewhere else in your code.
      Allows the Lister rows to be sorted by multiple fields (not possible in Lister/ListerPro)
      Allows the use of OR-groups (not possible in Lister/ListerPro)
      If ListerPro is installed you can run ListerPro actions on the listed pages - the available actions are defined in the module config.
      Bookmarks can be configured in the module config and accessed via the flyout menu for the module page. For your convenience you can copy/paste a bookmark string from the note at the bottom of the Lister Selector results.
      Usage
      Type your selector string on the Selector tab. The selector is applied when the "Selector string" field is blurred, so hit Tab when you have finished typing your selector.
      Unlike Lister/ListerPro, you can't sort results by clicking the column headings. Control the sort within the selector string instead.
      Superusers can jump to the module config (e.g. to create a bookmark) by clicking the cog icon at the top right of the module interface.
      The module is mostly intended for use by superusers, because in most cases site editors won't understand the ProcessWire selector string syntax. If you want another role to be able to access Lister Selector then give the role the "lister-selector" permission. Only superusers can define bookmarks because in ProcessWire module config screens are only accessible to superusers.
      Screenshots
      Process page

      Module config (when ListerPro is installed)

      Advanced
      If for any reason you want to create dynamic bookmark links to Lister Selector for a given selector you can do that like this:
      /** @var $pls ProcessListerSelector */ $pls = $modules->get('ProcessListerSelector'); // Define selector $selector = "template=foo, title%=bar"; // Define columns (optional) $columns = 'title,modified'; $pls_link = $pls->getProcessPage()->url . '?bm=' . $pls->urlSafeBase64Encode($selector . ':' . $columns); echo "<a href='$pls_link'>My link</a>";  
      https://github.com/Toutouwai/ProcessListerSelector
      https://modules.processwire.com/modules/process-lister-selector/
×
×
  • Create New...