Jump to content

Change the value of one field by editing another one - possible?


doolak
 Share

Recommended Posts

Hi there,

is there any possibility to change the value of one field by editing the value of another field on another page?

I have the following scenario:

There is a member list of a sports club - when editing a member you have to choose the team(s) he belongs to.

There are different sport teams - it should be possible to have the team members listed on the edit page of the teams, too. And - i would like to make it possible to delete or add a member from the teamlist to a team there.

When a meber is added or deleted this should be visible on the member's edit page, too...

If i remember there were some possibilities in the API which allow a database change - but i could not find them. But maybe there is another solution?

Would be great if you could give me an idea if/how this could be handled.

Cheers, Christian

Link to comment
Share on other sites

I had thought of a similar scenario where this would be useful yesterday but can't remember it now.

In other topics we've said to not bother with this as you can get all the correct info to show on the front-end by just adding a person to a team in one place and using selectors, but I think my scenario where this falls down was if one person is in charge of adding teams and only has those permissions and someone else is im charge of adding/editing team members and you want both to be able to see each others content im the relevant pages.

The easiest way would be with a module that's coded so that an update in one field updates another field - relatively easy I think - but what I think would be even better is a module that extends the Page fieldtype so that you can specify other fields that the current field updates in the field config so it doesn't have to be hard-coded in a separate module.

What do others think, assuming I made sense?

Link to comment
Share on other sites

Interesting question - it is kind of reverse page field or something like that. Lot's of directions how this could be handled and I think we need to think about it carefully. This is pretty rare reference, but I see the huge value in this particular case.

Link to comment
Share on other sites

Yes, i agree that this is a pretty rare scenario - but if one would have that possibility i can imagine that it would open some very nice new possibilities.

In the frontend everything is nice - Team members are listed in the teams and on the members profiles one can see to which team the member belongs.

I just would like to offer the admins the possibility to change the members of a team on both ends by editing them in the team or just changing the team on the members site. As far as i could find it out it would be possible with a hook: when saving the edited team the field on the members page has to be changed - and the same reversely.

I found this thread and i will digg into it and try to find how i can do this:

If anybody has a "quick solution" of course i would appreciate this.

Link to comment
Share on other sites

Quick and dirty? There you go with a simple module, but maybe not the real and best way as if it could be implemented with a dedicated page custon fieldtype. I thought about having a module that hooks after Page::save and reads two page fields, each is setup to select the template the other lives in.

Template: user -> Page field: teams_select

Template: team -> Page field: users_select

teams_select can select user template page and vise versa.

So now you'll need to check on every save those two templates and fields and remap them. This requires to go through all pages and make changes. This is like many to many but with not mapping table. Maybe I don't see anything obvious. But I think if you not go crazy with amount of pages, it should work well.

Example code in the Page::save after hook:

Removed previous code.

Added gist snippet: https://gist.github.com/4335296

Not tested, but it should works. Maybe not the best but you know it.

Edited by Soma
some code corrections
  • Like 2
Link to comment
Share on other sites

No look closely where the $page comes from.

Ok, got it: $page = $event->object;

In the beginning of your code you wrote: // autoload module extends WireData

Do i have to change the beginning of the module somehow?

Here my complete code:

<?php

class Members extends WireData implements Module {
public static function getModuleInfo() {
 return array(
  'title' => 'Members vs Teams',
  'version' => 1,
  'summary' => 'Lorem Ipsum Dolor Sit',
  'singular' => true,
  'autoload' => true,
  );
}

public function init() {
 $this->pages->addHookAfter('save', $this, 'hookPagesave');
}
public function hookPagesave(HookEvent $event){
// get current page saved
$page = $event->object;

if($page->template == "mitglied"){
// iterate all team pages once
foreach($this->pages->find("template=team") as $team){
// iterate each selected team in the current user page to map
// and add or remove
foreach($page->mitglied_team as $s_team) {
// if team page is a selected one and not added, add it
if($s_team === $team) {
if(!$team->team_mitglieder->has($s_team)) $team->team_mitglieder->add($page);
} else {
// if it's not in the selected team but in array, remove it
if($team->team_mitglieder->has($s_team)) $team->team_mitglieder->remove($page);
}
// save the mapped team page
$team->save();
}
}
}
// same for team page save
if($page->template == "team"){
// iterate all team pages once
foreach($this->pages->find("template=mitglied") as $user){
foreach($page->team_mitglieder as $s_user) {
if($s_user === $user) {
if(!$user->mitglied_team->has($s_user)) $user->mitglied_team->add($page);
} else {
if($user->mitglied_team->has($s_user)) $user->mitglied_team->remove($page);
}
$team->save();
}
}
}
}

}

So far it does not work - but i can imagine it's just a small mistake somewhere...

Link to comment
Share on other sites

Damn - i cannot get this to work.

I tried a lot of variations, verified if the variables are correct and i read and read the code again - i think from the logical structure it should do what it is supposed to do. So as i said, i just can imagine that there is a small mistake somewhere. I tried "append" instead of "add" - but no difference.

I am trying and trying - but i have no idea yet what's wrong :(

Link to comment
Share on other sites

Yeah I tested code and found some issues. I create a code that works. Study how it's done and the changes.

$page needs to be retrieved different, and it had some logik faults, it needs to add or remove $page, not $s_team...

Biggest issue with save hooks is that when you save a page in the module it will get called endless recursive. To prevent this we save a skipme to the pages saved on runtime to it does skip them.

Also added some additional checks for if there's no pages selected at all, to remove all references.

Here a new working proof of concept module: https://gist.github.com/4335296

Link to comment
Share on other sites

Hey Soma, thanks for your effort and your help!

I am just not sure about one thing.

What is the purpose of that part:

$this->set("tpl_team","basic-page");
 $this->set("users_select","users_select");
 $this->set("tpl_user","user");
 $this->set("teams_select","teams_select");

Do i have to change just that part in a way that it matches with my own field names and leave the rest as it is?

e.g.:

$this->set("team","basic-page");
 $this->set("team_mitglieder","users_select");
 $this->set("mitglied","user");
 $this->set("mitglied_team","teams_select");

I use the templates "team" and "mitglied" and the page fields "team_mitglieder" and "mitglied_team"...

Or do i have to change the rest of the code, too?

Edited by doolak
Link to comment
Share on other sites

Yes those are just properties I've set to change the two fields and templates more quickly. It could be done differently. Also there could be some configuration with 2 dimenstional array to map many fields and templates and the mapping part could also be a little more abstract, but it's nothing too serious and just a quick straight forward proof of concept that for now works. I'm not sure how mapping could be done better scaleable and reusable, but sure this would take some good implementation rethinking. A dedicated field approach extending page field, that may even adds another table to do it. All just hot air for now.

Edit:

You use set(key,value)

So it would be

$this->set("tpl_team","team"); // template
$this->set("users_select","team_mitglied"); // its page field

$this->set("tpl_user","mitglied");//template
$this->set("teams_select","mitglied_team");// its page field

and this may also work if you peferer

$this->tpl_team = "team"; // template
$this->users_select = "team_mitglied"; // its page field

$this->tpl_user = "mitglied"; //template
$this->teams_select = "mitglied_team";// its page field
  • Like 1
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...