Home › Toolset Professional Support › [Resolved] One page to edit selectable custom fields (for all posts)
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | - |
- | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | - |
Supporter timezone: Asia/Karachi (GMT+05:00)
This topic contains 12 replies, has 2 voices.
Last updated by joostH-2 3 years, 4 months ago.
Assisted by: Waqar.
I'm building a game site with guests (= WP users). Guests are assigned personal challenges in several rounds (typically 10 rounds). I've created a proxy CPT "guests" for each user/guest. I've added 10 custom fields to that CPT, named 'personal-challenge-i' with i=1,10. I want to create a frontend page to edit the personal challenges for each guests per round. I envision a radio-button form to select round 1-10 and then get a form to edit the challenges for all guests in a single page.
I have succesfully created a frontend page to edit a single challenge, following the solution to a previous question: https://toolset.com/forums/topic/edit-custom-fields-in-a-single-from-for-all-posts-simultaneously/. I created a suitable form, added that to a view, which is added to a page. That intermediate result is here: hidden link
That works fine for a single round. Now I want to create this mechanism to add field or radio button to select other rounds of challenges as well. Creating the radio button form is not the problem, but how can I use the result as identifier for the correct custom field of the round? One thing I'm not sure of, is if creating 10 custom fields is the best approach, or that a repeatable custom field or a field that can have multiple instances would be better.
I hope the question is clear enough. Please ask clarification if not.
Thanks in advance!
Joost
Hi Joost,
Thank you for contacting us and I'd be happy to assist.
From your message, I'm not clear if, for each round, you need to store a single custom field value or a group of custom field values, for each user.
If you just need to store a single custom field for each round, for example, "Round Score", you can add 10 custom fields for each round with the "Guests" post type:
1). Round 1 Score
2). Round 2 Score
3). Round 3 Score
.....
10). Round 10 Score
However, if you need to store multiple custom fields for each round, then you'll need to a slightly different approach.
For each round's custom fields, you can add a new custom field group, but they all will still be attached to the same post type "Guests".
1). Round 1 Fields
2). Round 2 Fields
3). Round 3 Fields
.....
10). Round 10 Fields
Storing fields for each round into its own field group will offer a better usability experience and avoid any clutter.
Note: I'm not recommending using repeatable field group in this case because:
a). Fields added inside the repeatable group will not be stored with the actual post type "Guests" in the database. This means that you'll not be able to use the same front-end form for the "Guests" posts to manage the fields in the repeatable field group.
and
b). The repeatable field group is useful for the cases where the instances of the repeating items are not known or are variable. But in this case, we know that the number of items (rounds) is fixed to 10.
I hope this helps and please let me know if you need any further assistance around this.
regards,
Waqar
Hello Waqar,
Thanks for your reply. As further clarification: I store a single custom field per guest per round. And I already have this implemented with 10 custom fields in the Guest post type as you suggest. The link that I added in my original post shows the first of those 10 custom fields for each guest. So this works already and thanks for the confirmation that this is the best approach.
What I now could do is to build 10 similar views + corresponding pages for each round. That would work, but it feels akward and is not convenient for the game operators.
My question is that I'd rather build a single view and a single page where the operator can select (e.g. via a radio button) which round to edit. How could I do that?
Thank you for sharing further details.
I'll need to perform some testing to see if this can be achieved using a single view. But first, I'll need to see exactly how these elements are set up on your website.
Can you please share temporary admin login details, in reply to this message?
Note: Your next reply will be private and though no changes will be made on your website, please make a complete backup copy, before sharing the access details.
Thank you for sharing these details.
To re-use the same edit form and the view for multiple round fields, you can use include all 10 fields in the form "Admin - Persoonlijke opdracht 1", but show them, conditionally based on the URL parameter passed to the page.
For example, you'll note that I've wrapped the 3 available fields in that form, inside 3 conditional checks, which look for the value from the URL parameter "stage":
https://toolset.com/documentation/legacy-features/views-plugin/using-shortcodes-in-conditions/
[wpv-conditional if="( '[wpv-search-term param='stage']' eq '1' )"] Field 1 code [/wpv-conditional] [wpv-conditional if="( '[wpv-search-term param='stage']' eq '2' )"] Field 2 code [/wpv-conditional] [wpv-conditional if="( '[wpv-search-term param='stage']' eq '3' )"] Field 3 code [/wpv-conditional]
The first conditional check will only show the field 1, if the URL parameter value for "stage" is equal to "1":
yourwebsite.com/admin/persoonlijke-opdracht-1-velden/?stage=1
The second conditional check will only show the field 2, if the URL parameter value for "stage" is equal to "2":
yourwebsite.com/admin/persoonlijke-opdracht-1-velden/?stage=2
The third conditional check will only show the field 3, if the URL parameter value for "stage" is equal to "3":
yourwebsite.com/admin/persoonlijke-opdracht-1-velden/?stage=3
Using the same approach, you can add the remaining 7 fields.
Hello Waqar,
Thanks for your help. You've taken an approach that I never could have thought of myself. Very creative. What is not clear to what the function of the radio button selector is. It appears for every participant but seems to have no function. If I comment them out, it still works.
What's still missing is a mechanism to jump to the page yourwebsite.com/admin/persoonlijke-opdracht-1-velden/?stage=1 ( and 2, 3, 4,.... 10 ) I could create 10 buttons linking to the respective URLs, and that would be OK. But perhaps this can be done more elegantly with one single radio button selector for the whole page (which was my original thougth). I'm not sure if and how that can be done in the same form. Can't I use the outcome of the radio button parameter in the conditional and url in the rest of the form?
Or, perhaps even better, could I use a global parameter 'round' or 'stage' to fill in the URL? I understand that Toolset does not really support global parameters, but I mean via a CPT 'Options' that would have a field 'round' or ' stage', like suggested in this post? I would have other uses for such an approach, so setting that up is not a problem. I just can't see yet how I could use such a field/parameter in this case.
Thanks for the update and glad that it worked.
If your page only had a single instance of the form, you could add a generic checkboxes type field and then use the conditional display of form input fields to show or hide the form fields:
https://toolset.com/course-lesson/conditional-display-for-form-inputs/
But, you have multiple instances of the form on the page, which means that the generic checkboxes type field would repeat for each instance of the form and the user would have to select the stage in each form, independently. I'm sure this is not what you'd prefer.
Another workaround can be to add a custom form, on top of your view with the forms:
<form method="get"> <input type="radio" name="stage" value="1" id="stage-1"> <label class="wpt-form-label wpt-form-radio-label" for="stage-1">Stage 1</label> <input type="radio" name="stage" value="2" id="stage-2"> <label class="wpt-form-label wpt-form-radio-label" for="stage-2">Stage 2</label> <input type="radio" name="stage" value="3" id="stage-3"> <label class="wpt-form-label wpt-form-radio-label" for="stage-3">Stage 3</label> <input type="submit" value="Submit"> </form>
When a stage's radio option will be selected and the form is submitted, the page will refresh and only that stage's fields will be shown.
For more personalized assistance around a different custom code solution, you can also consider hiring a professional from our list of recommended contractors:
https://toolset.com/contractors/
Hello Waqar,
Indeed this works. Perhaps not the most elegant UI (with the extra Submit), but it is more than sufficient as it is for admin use.
However, I encounter another issue now. I'm not sure if it has arised with the implemenation of the above, or that I had not tested the earlier version sufficiently thorough.
If you visit MyWebsite/admin/persoonlijke-opdrachten/ ((logged in as admin, you have the details) and select one of the stages ('rondes'), than you get a perfect form for that stage/ronde. However, entering data in the fields and submitting them, appear to go well. But in reality, the data is not stored in the particapant profile ( = 'deelnemer' proxy post). As I still not fully grasp the mechanism exploited here, I can't figure out what is (not) happening. Could you have another look?
Thanks in advance!!
Thanks for writing back.
I've performed some tests and can confirm that if the form is set to submit using AJAX, then the fields wrapped inside the conditional display block are not saved properly.
I was able to make this work using a slightly different approach. Instead of wrapping the fields inside the conditional blocks, I wrapped them inside special div containers:
<div class="form-field-container form-field-container-stage-1"> <div class="form-group"> <label for="%%FORM_ID%%_persoonlijke-opdracht-1">[cred_i18n name='persoonlijke-opdracht-1-label']Persoonlijke opdracht 1[/cred_i18n]</label> [cred_field field='persoonlijke-opdracht-1' force_type='field' class='form-control' output='bootstrap'] </div> </div> <div class="form-field-container form-field-container-stage-2"> <div class="form-group"> <label for="%%FORM_ID%%_persoonlijke-opdracht-2">[cred_i18n name='persoonlijke-opdracht-2-label']Persoonlijke opdracht 2[/cred_i18n]</label> [cred_field field="persoonlijke-opdracht-2" force_type="field" class="form-control" output="bootstrap"] </div> </div> <div class="form-field-container form-field-container-stage-3"> <div class="form-group"> <label for="%%FORM_ID%%_persoonlijke-opdracht-3">[cred_i18n name='persoonlijke-opdracht-3-label']Persoonlijke opdracht 3[/cred_i18n]</label> [cred_field field="persoonlijke-opdracht-3" force_type="field" class="form-control" output="bootstrap"] </div> </div>
Please note how each container div is wrapped with a common class name "form-field-container" and a unique class name "form-field-container-stage-X", where X is the stage's number.
Next, below this field's code, I added some custom CSS code, that hides all the fields inside the fields container, and only shows the fields, where the stage number matches the parameter value and the unique class name:
<style> .form-field-container { display: none; } .form-field-container.form-field-container-stage-[wpv-search-term param='stage'] { display: block; } </style>
As a result, when the page loads and there is no stage selected, no fields are shown. When a stage is selected and its number is available in the URL parameter, only that stage's fields will show.
Hello Waqar,
Thanks for your further assistance! Now indeed it works as I imagined.
For my education, so that I can build similar constructs myself in the future, two questions for clarification.
1) As I understand it, the construct relies on the parameter 'stage' that is defined in the radio button form in the view and transmitted to the form. Correct? What is the scope of this paramater transmission? Just within the view (as the form is nested in the view), or can one transmit parameters in this way within a page, between different views and or forms if required? I would not expect that transmission between pages is possible.
2) What remains unclear to me is the function of the part <label for="%%FORM_ID%%_persoonlijke-opdracht-1">. Could you explain?
Thanks!
Joost
1) As I understand it, the construct relies on the parameter 'stage' that is defined in the radio button form in the view and transmitted to the form. Correct? What is the scope of this paramater transmission? Just within the view (as the form is nested in the view), or can one transmit parameters in this way within a page, between different views and or forms if required? I would not expect that transmission between pages is possible.
- Any value passed through the URL parameter e.g. /?stage=1234, is available globally when the page loads. This means that you can access it using the shortcode [wpv-search-term param='stage'] ( ref: https://toolset.com/documentation/programmer-reference/views/views-shortcodes/#wpv-search-term ) inside the page's content, inside the view, or inside the form, as needed.
That shortcode makes use of the superglobal variable "$_GET" and here are some useful guides on the topic:
hidden link
hidden link
The technique of passing URL parameters is useful when we need to pass some information/value from one page to another or make the content of the page dynamic, based on the passed value.
2) What remains unclear to me is the function of the part <label for="%%FORM_ID%%_persoonlijke-opdracht-1">. Could you explain?
- The label tag is added with the input fields to associate some identifying text labels. Through them, visitors and screen readers can easily figure out what information a particular field expects.
( screenshot: hidden link )
Hello Waqar, thanks for the further explanation and resolving my question. Greatly appreciated!