doolak Posted December 16, 2012 Share Posted December 16, 2012 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 More sharing options...
Pete Posted December 17, 2012 Share Posted December 17, 2012 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 More sharing options...
apeisa Posted December 17, 2012 Share Posted December 17, 2012 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 More sharing options...
doolak Posted December 17, 2012 Author Share Posted December 17, 2012 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 More sharing options...
Soma Posted December 17, 2012 Share Posted December 17, 2012 (edited) 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 December 19, 2012 by Soma some code corrections 2 Link to comment Share on other sites More sharing options...
doolak Posted December 17, 2012 Author Share Posted December 17, 2012 Wow - that was fast! Thank you, Soma! Looks like exactly what i need - I will try and report how it works. Link to comment Share on other sites More sharing options...
Soma Posted December 17, 2012 Share Posted December 17, 2012 Np. Just noticed some major fault. in modules it's not $pages but wire("pages")->find() or simply $this->pages->find(). Will correct again Link to comment Share on other sites More sharing options...
doolak Posted December 17, 2012 Author Share Posted December 17, 2012 And has it to be $this->page->template instead of $page->template, too? Link to comment Share on other sites More sharing options...
Soma Posted December 17, 2012 Share Posted December 17, 2012 And has it to be $this->page->template instead of $page->template, too? No look closely where the $page comes from. Link to comment Share on other sites More sharing options...
doolak Posted December 17, 2012 Author Share Posted December 17, 2012 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 More sharing options...
doolak Posted December 18, 2012 Author Share Posted December 18, 2012 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 More sharing options...
doolak Posted December 19, 2012 Author Share Posted December 19, 2012 Ok, i found one thing which i think is not correct: In the second part - shouldn't it be $user->save(); there? But i tried it by saving the member page, too - so there it should have worked fine... Link to comment Share on other sites More sharing options...
Soma Posted December 19, 2012 Share Posted December 19, 2012 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 More sharing options...
doolak Posted December 19, 2012 Author Share Posted December 19, 2012 (edited) 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 December 19, 2012 by doolak Link to comment Share on other sites More sharing options...
Soma Posted December 19, 2012 Share Posted December 19, 2012 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 1 Link to comment Share on other sites More sharing options...
doolak Posted December 19, 2012 Author Share Posted December 19, 2012 Perfect! Works like a breeze! I thank you so much for spending your time for my problem! Cheers, Christian Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now