Embed Express Form block inside Express Entry List Block, plus modify form field and insert data

Okay so if I’m reading this right, the method at the core here is leveraging a for (foreach?) loop to iterate and check if the $targetHandle matches the attribute, sounds good.

However:

  1. I’m not seeing which file I should be doing that in (as I don’t see that example code in the files on the repo… I think?)
  2. I am not seeing exactly how to insert the data into the form field (by code example)

It depends how are you opening magnific popup.
But if you are using #target-div in href attribute, then you probably have access to this object or something like that inside magnific function ( which is an element that you have clicked).

I’m more asking the previous questions against the example code in your example repo that you pointed me to. I want to understand that method before I start stuffing it into my own things. So while I do generally use the href method for Magnific Pop-up, for the sake of understanding the method you’re presenting, let’s just put Magnific Pop-Up aside for now, to simplify it a bit :slight_smile:

So… same questions considering that?

You don’t need to do any for/foreach loop in overrides.
Only for/foreach loop you need is in express block template (which is already there, since block is listing items).
In package you are overriding field TYPE in specific Express object (to display handle in data-* attribute).
This override applies to every association field in form from chosen Express object (if you add one or more associations). But you have only one, so it doesn’t matter - there is no need for

 <?php if ($targetHandle  === 'your_attribute_field_handle_from_express'): ?>style="display: none"<?php endif; ?>

but you should keep it in case you ever add more associations to form.

Okay so I THINK I’m starting to wrap my head around all this. And oh boy is this complicated (and it sure looks to be complicated due to how Concrete CMS does this).

If I’m understanding correctly…

  1. I can define a CSS class to apply “display: none” to it (instead of in-line styling, as you suggest) when I use " <?php if ($targetHandle === 'your_attribute_field_handle_from_express'): ?>class=“whatever-class-name-for-styling”<?php endif; ?>". And I can add this to line:46 for : parasek/concretecms-express-form/blob/master/elements/express/form/tournament_registration_form/association/select.php
  2. I somehow use javascript to insert the data (yes, I am going to use javascript for Magnific Popup for this) with the below quote (I think that’s what you’re getting at there)

===

HOWEVER I suck at javascript, and I don’t know how to leverage what you propose in javascript to insert the data. And I’m not seeing any .js files in the example repo. I suspect you want me to set data-id=“$tournamentEntry” (this is short-hand, not the actual value). Which I’m pretty sure I can figure out how to make work in the Express Entry List template.

BUUUUTTT I’m still not seeing how setting the data-id to a value, results in that data being “forcefully selected” in the form. Also… I’m not entirely seeing how I “insert the form” into the “Magnific Popup”.

You earlier mentioned put an Express Entry List block on the page + an Express Form on the same page. That sounds like placing two blocks, when my intent here is to just place the one block (Express Entry List) and have the Template I select for that block to then “add specific form to the Magnific Popup” as part of the Template itself. How can I achieve that? (preferably in PHP/HTML, and not JS).

I’m pretty sure I’m getting closer to comprehending here, please clarify any areas I may still be off.

Thanks again for your help! Seriously!

You can do everything in “Express List” block, but you would have to code form, validation, saving data etc. by yourself.
Which is not a big deal but nontheless you would need to code something.
And you would need to pass data with js anyway.

Js can be placed anywhere, just after jquery was loaded, in php template file, view.js or your main js file.

<script>
	$(function () {
		$('a[data-id]').on('click', function (e) {
			e.preventDefault();
			// Get tournament id from clicked link
			const tournamentId = $(this).attr('data-id');
			// Set value of tournament select in form block on the same page
			$('[data-express-field-handle="tournament"]').val(tournamentId);
		});
	});
</script>

Try do do that first before moving to magnific popup.
For that you need to wrap your “form” block with div that is set to display:none.
Check official examples how to do inline popup:

@Parasek ,

Given the choice between coding the form, validation, saving date, etc… and… doing some javascript… I would rather do some javascript.

For me, there is value in leveraging the “already written” Express Form code, not only as it reduces code I would need to write, but it also means I can likely benefit from future code improvements in it… such as security improvements… which I realistically have zero budget for.

When you say to try the js code, and wrap the “form” block with a div, are we talking about me “normally” placing an Express Form block (via dashboard interface) on a page, applying a template to wrap a div around the $render part, and enforcing “display:none”? Or are you… talking about another method and I’m misunderstanding?

If I understand your “trick” here well… the jscode, and the earlier php modifications you’ve proposed, will invoke this second block (“invisible” to the user) within the first Express List Block? Am I following this functional flow correctly?

Again, I really do appreciate your time with this, thanks!

1 Like

Yeah, first block is “Express list”.

Second block is “Express form” which you want to make invisible. Make a template where you surround it with div and hide it somehow. In magnific examples mfp-hide is being added if I recall.

You have to surround hide class/style with something like:
if (!$c->isEditMode()) { }
in php, so block template will not be invisible for you when editing.

Yes, you will trigger change in second block from clicking link in first one (but of course they have to be on the same page).

Try to do it first without magnific though, it somehow adds another layer. Express Form block is not ajax based, so it will refresh page when sending.

1 Like
  1. Will I need one “Express Form Block” for each different forms on the same page that I want to use this method for? It’s looking like “yes”
  2. The page being reloaded when hitting “submit”/equivalent is an acceptable UX IMO, and I was already anticipating that (plus I think there’s an ajax paid plugin I can use if I REALLLYY want that, but right now ajax for this isn’t a priority)
  3. Thanks for that isEditMode aspect, as I was already trying to think how to manage it from an admin perspective hehe.
  4. I’m probably going to take a stab at this today if I can, maybe in the next few hours
  5. Seriously thanks again!

Hey so I’m trying to get this going, and I’m getting this PHP error thrown:

Class ‘TournamentRegistrationForm\Express\Controller\TournamentRegistrationFormController’ not found

And I’m not entirely seeing what I’m doing wrong. As I have…

"
use TournamentRegistrationForm\Express\Controller\TournamentRegistrationFormController;
"

and

"
protected $pkgAutoloaderRegistries = [
‘src’ => ‘TournamentRegistrationForm’,
];
"

in the /controller.php

and the file /src/Attribute/Context/Express/Controller/TournamentRegistrationFormController.php copied directly from your repo.

I haven’t worked with these aspects, so it’s not jumping out at me as to what I’m doing wrong here. Can you point me in the right direction please?

There is not such file in repo. There is one actually, but in different folder. Have you copied it to proper folder?

Aha you’re right! I put two files in the wrong folder, whoops!

So I moved them to the correct folders, things seem to be loading right now. However, after adding the JS script blocks into my express_entry_list template, the click link doesn’t work (pop-up) and the developer console outputs this (not sure how to correct this).

event-test-page:401 Uncaught TypeError: $.concreteExpressEntryList is not a function
    at HTMLDocument.<anonymous> (event-test-page:401:11)
    at i (jquery.js?ccm_nocache=1a72ca0f3692b16db9673a9a89faff0649086c52:2:27449)
    at Object.fireWith [as resolveWith] (jquery.js?ccm_nocache=1a72ca0f3692b16db9673a9a89faff0649086c52:2:28213)
    at Function.ready (jquery.js?ccm_nocache=1a72ca0f3692b16db9673a9a89faff0649086c52:2:30006)
    at HTMLDocument.K (jquery.js?ccm_nocache=1a72ca0f3692b16db9673a9a89faff0649086c52:2:30368)

Okay so I removed the part relevant to the search functionality (as in this case I’m not going to use it).

However, the pop-up happens, but I don’t see the “form” (submit button) in the pop-up. And I’m… not entirely seeing how to connect the form on the page to the pop-up.

I am doing this for the pop-up hyperlink:

<a class="popup-with-move-anim" href="#tournament-register-<?=$item->getEntry()->getID()?>" data-id="<?= h($item->getEntry()->getId()); ?>">

What step am I missing here? I’ve re-read through this conversation a whole bunch, and I’m not sure what to do next…

As always, thanks for your help! And I really seriously super appreciate this!

There should be two blocks, 1 express list and 1 express form block.
Express form should be wrapper with div that hides it.
I would open magnific popup manually

<script>
	$(function () {
		$('a[data-id]').on('click', function (e) {
			e.preventDefault();
			// Get tournament id from clicked link
			const tournamentId = $(this).attr('data-id');
			// Set value of tournament select in form block on the same page
			$('[data-express-field-handle="tournament"]').val(tournamentId);

            // Open popup here, check example  at  
            // https://dimsemenov.com/plugins/magnific-popup/
            // when you hover at  "Popup with form" and click view source
		});
	});
</script>

In this case, content of href attribute is irrelevant.

I have the Express Form Block on the same page. And for the sake of testing it isn’t hiding yet.

I still am not seeing how to get the link to bring up the specific Express Form on that page, into the magnific pop-up rendering area. Although I was going to try using the < a> tag with the href maybe point to it with a template, but from what you say it sounds like maybe that’s not how what you’ve written works.

So yeah, the pop-up is happening, but I don’t see the form in the pop-up.

edit: Wait… does the Form magically get connected when it has an attribute with the handle matching the js script? in this case…

data-express-field-handle=“tournament”

??

In your case, if you are using # in href, every href attribute should be pointing to single form (or to be more specific, div that wraps that single form)"
href="#tournament-register"

1 Like

AHA!!! My nearly-asleep-pseudo-drunken-stupor last night was onto something! I was literally about to fall asleep when I thought about this last night, had to get up and write it down so I don’t forget, and have been meaning to try it out today. I just haven’t yet as other things in the way :smiley:

I’m pretty sure we’re on the same wavelength here and I’ll have to try this out real soon!

Sorry for all my confusion and questions about this. I truly do appreciate your patience with all this. :slight_smile:

Okay so I have the form popping-up, however the Association is not being pre-filled.

I do not have any “hidden” stuff set yet, as I want to see this all raw, by the way.

For the pop-up I’m using…

<a class="popup-with-move-anim" href="#tournament-register-form" data-id="<?= h($item->getEntry()->getId()); ?>">

And in the js I’ve updated it to…

$('[data-express-field-handle="event_tournaments"]').val(tournamentId);

Note that “event_tournaments” is the Express Object that has an Entry I want to select.

In the association between the “Event Tournaments Individual Reg List” (current name of Express Object with the registrations in this particular case, I will rename it better soon haha), I have it as ManyToOne.

The Target Property Name is “event_tournaments”. So as far as I can tell this likely is the handle I want to use… I think?

So…

In the pop-up, I see the form, and the tournament has not been pre-selected at all. When I click on “Select Entry” I can see the two test tournaments to be selected.

When I open up F12 debug, I don’t see any errors in the console.

What part did I miss for this? I am soooo close to this working it looks like!

Oh also, I’m not sure if it matters, since how all this “Context” aspect of Concrete CMS is still not really fully in my head, but… the template I’m using for the Form is called “event_page_tournaments_register”. I’m not sure if that naming for the template is breaking the connection to select.php or not.