Attribute Edit Form element with javascript

Permalink
I have some custom attributes that use javascript in their edit form elements. I initially developed them for use as user attributes and they are working nicely on Profile, Registration and user dashboard pages. I am happy with the code so far. The relevant javascript is loaded by a series of 'addHeaderItem()' in the attribute controller form() method.

Just for fun, but you never know when it could be useful, I tried adding them to a page using the edit>properties>custom attributes dialog.

In this context, the associated javascript for my attributes is simply not loaded. I suspect because the whole dialog is served by an ajax call to load tools/required/edit_collection_popup.php.

Playing some more, I tried date-time and address attributes. Their javascript is loaded by javascript calls to ccm_addHeaderItem() inserted in a script block of the code for the dialog.

So, my question is, what is the nice way to get my attribute controller to extend the list of ccm_addHeaderItem() javascript calls inserted by edit_collection_popup.php? (and presumably a generic solution to similar problems in the future)

JohntheFish
 
jordanlev replied on at Permalink Reply
jordanlev
I think calling ccm_addHeaderItem() from javascript is the "recommended" way. The larger issue here is that you're asking the system to predict the future and know whether or not your particular attribute form will be used when the user edits the properties. There's no way to know this, so the only two possible solutions are:
1) Include it when it's needed -- via ccm_addHeaderItem() in the javascript of the attribute form.
2) Include it on every page all the time (while a user who has edit privileges is logged in), via your theme's header element or via a package controller on_start() event handler.

(This is my own understanding -- I could be missing something of course and hopefully others will pipe in).
JohntheFish replied on at Permalink Reply
JohntheFish
Building in my own javascript snippet on the form that calls ccm_addHeaderItem to load the attribute scripts may well be the way I have to go. But I suspect there is more to it with the edit_collection_popup because all the calls for ccm_addHeaderItem are placed together at the top of the attribute tab code, so can't be part of an individual attribute's form method. (looking at the response in the chrome developer network diagnostic)
jordanlev replied on at Permalink Reply
jordanlev
I don't know diddly-squat about actual facts here because I've never delved into this portion of the code... but my idle speculation may be that the javascripts it's already including are for things that it knows are going to be on that page -- like attributes that have already been set or that are set to show by default for the page type (or just the date/time stuff which is always there). Whereas you're talking about a situation where the attribute may or may not be added to the properties form.
Another thought is that whatever it's loading is just for the UI of the overall properties form, nothing specific to any one attribute. Which means there's no way to hook into it via the attributes themselves (it's just a built-in part of the system UI).
mesuva replied on at Permalink Reply
mesuva
Hey John and Jordan,

was there ever a resolution to this question? Any new API calls or what-not?

I've developed a new attribute type, which works great in the Composer, but I'm not sure how to inject the scripts it depends on when editing the the attribute via the Edit->Properties->Custom Attributes dialog.

I've got a feeling this is a bit of a tricky one!
JohntheFish replied on at Permalink Reply
JohntheFish
I had forgotten all about this thread.

I never needed to finish it for attributes because my immediate use for a few user attributes was solved. Just the general use that was not.

In other situations (not with attributes) I have used <script> tags in the add/edit form and call ccm_AddHeaderItem to lazy load specific assets.

The main area I get glitches is that the jQuery ready event fires in some situations following a lazy load, but not in others. It may be nested lazy loads that fail to trigger ready, so perhaps an issue inside ccm_AddHeaderItem. I have got round this by adding an intermediary event and triggering that on ready or a timer expiring (and then cancelling the time).
mesuva replied on at Permalink Reply
mesuva
Thanks John, I'll see if I can use ccm_AddHeaderItem for my purposes, but I've got a feeling the javascript I'm using is going to be pretty fussy about the way it's loaded up.

If I discover a good way to handle this I'll post it back to this thread.
mesuva replied on at Permalink Reply
mesuva
As a follow up to this I found it wasn't so bad after all and was able to get it working without the use of ccm_AddHeaderItem.

I'm not sure if it's a 5.6 thing (in fact I'm not really sure why it works), but simply calling $this->addHeaderItem in the form() function of an attribute type seems to pull in the scripts when the attribute is loaded via the page properties dialog.

The only thing I had to do was actually output my initialising script (i.e. the stuff that sets up the behaviour in $(document).ready(function()... ) to the actual page alongside my field and not include it as a header item.

I'm actually even having trouble seeing when and where concrete5 pulls in these scripts in this context and it seems to work regardless of whether I've already added the attribute to the page or not. It even works via editing properties in the sitemap.
It's either doing something very clever/elegant to handle this now, or it's not as complex a problem as I thought.

I do know the scripts are pulled in on page load and not when the properties are displayed, so perhaps concrete is calling all the form functions for the attribute types ahead of needing them. If I comment out either the javascript or CSS $this->addHeaderItem line in my code, the attribute type stops working correctly, so these lines are definitely coming into play.

So ultimately my advice here if anyone reads this is to just link in your scripts for your attribute type as normal using $this->addHeaderItem, and output your initialising code to the actual page so it gets triggered when the attribute is actually first displayed.
JohntheFish replied on at Permalink Reply
JohntheFish
I think my original post was still on 5.4.x. So perhaps something has changed. Or more likely your application is more conventional than what I was playing about with at the time.