Is there a TV for selecting items from a MIGXDB CMP?

I have a MIGXDB custom manager page where the client enters all their details about images.
Part of the DB are fields for selecting resources the images link to. For example a resource named “Jane Doe” is ID 10, and so in the MIGXDB there is a field for “authors” and it contains 10.

I didn’t originally build this site, but the way they linked the images to various resources is explicitly defined in the MIGXDB data, not the resource. In other words, the resource doesn’t choose what images belong to itself, the MIGXDB data chooses what resource it belongs to.
It feels kind of backwards to me but whatever.

Now I need to do the not-backwards way. I need to create resources which should have a TV where the client can choose any image in the entire MIGXDB dataset.

Imagine we had a “image of the week” page and the client just wants to edit the page and select a new image using a TV.

I can’t find such a TV.

I’ve found lots of examples of TVs that can choose from lists of tags and categories and resources, but none that choose from MIGXDB CMP data itself.

What I’d like is for the client to open the resource and go to the TVs area, and be presented with a small table with thumbnails, titles, few other bits of data, and search/filter so they can find the image(s) they need to select (there is almost 7000 images).
Then in the template I just need to pull these images out of the MIGXDB data and use all the fields connected to that image that I need.

I know I must be missing something. Does MIGX not come with a TV that helps select items from the MIGXDB data we create? How are resources and MIGXDB data meant to be related if not explicitly defined in the MIGX data itself?
I know I can use getImageList for getting the data, but I need my resource to first define which rows I want to return via a TV selection in the first place!

Any help would be lovely!

it is possible to have a migxdb - TV, which shows only the images connected to a resource, if it has a column, which holds the resource-id

could also be a many to many table which could connect many images with many resources.
This could also be managed with a migxdb - TV

I’d like to explore the options you presented but not sure how this comes together.

If I create a TV as a migx TV, it lets me define my data/fields/columns, but how is that actually related to the other migxdb data? I actually need a TV that lets me search through and select the migxdb data. A normal migx TV doesn’t do that.

The closest I’ve seen is using a mutli-select TV and then populating the select via a snippet that returns the IDs for the migxdb data.
Not sure how performant that is considering it will output 7k IDs.

Seems like the only way to relate resources to the migxdb data is to have a column in migxdb itself to set the resource ID. Then the resource is able to pull this via the template, no TV even needed. But this is backwards to me. I want my resources to be able to find and select the migxdb data so that users can pick things from inside the resource itself.

I don’t know exactly how to assemble this feature.

could you post the xpdo schema and the exported migx configs?

I think this is the schema:

<?xml version="1.0" encoding="UTF-8"?>
<model package="artwork" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
    <object class="artWorks" table="artwork" extends="xPDOSimpleObject" >
     <field key="artist_resource_id" dbtype="text" phptype="string" null="false" default="" />
     <field key="exhibition_resource_id" dbtype="text" phptype="string" null="false" default="" />
     <field key="artFair_resource_id" dbtype="text" phptype="string" null="false" default="" />
     <field key="image" dbtype="varchar" precision="255" phptype="string" null="false" default="" />
    <field key="title" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
<field key="videoLink" dbtype="text" phptype="json" null="false" default="" />
<field key="artistName" precision="255" dbtype="varchar" phptype="string" null="false" default="" />
<field key="artistLastName" precision="255" dbtype="varchar" phptype="string" null="false" default="" />
<field key="extendedOne" dbtype="text" phptype="string" null="false" default="" />
<field key="extendedTwo" dbtype="text" phptype="string" null="false" default="" />
<field key="extendedThree" dbtype="text" phptype="string" null="false" default="" />
<field key="media" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
 <field key="sizes" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
 <field key="edition" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
 <field key="tagOne" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
 <field key="tagTwo" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
 <field key="tagthree" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
 <field key="tagFour" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
 <field key="secondaryMarket" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
 <field key="availability" dbtype="varchar" precision="255" phptype="string" null="false" default="" index="index" />
<field key="videoLinkTwo" dbtype="text" phptype="json" null="false" default="" />
<field key="extendedVideo" dbtype="text" phptype="string" null="false" default="" />
<field key="artText" dbtype="text" phptype="string" null="false" default="" />
<field key="altText" dbtype="text" phptype="string" null="false" default="" />
</object>
</model>

So you’ll notice three fields xx_resource_id. This is where they have a pipe-delimited list of resources this art relates to. So it might contain “41|17|123|9”.
This is parsed out by the templates that are expecting to find art with IDs in these fields.

Now like I said I want to relate some new resources to the art but I don’t want to add more of these csv fields. I just want to open the resource and have some kind of selector TV to browse and choose from the available art.

Here is the MIGX config: https://pastebin.com/ep6x5fVk

In the spirit of just getting this done, I’ve created a simple text TV so they can enter IDs manually. For example “12,20,59”.

Now all I need to do is grab the migxdb rows with those IDs and loop them.

I’m guessing the snippet migxLoopCollection is the one I want, but I can’t find good docs on how to use it and assemble the query and so forth. Is that the right snippet?

I’m trying something like this:

[[!migxLoopCollection?
&debug=`1`
&packageName=`artwork`
&classname=`artWorks`
&where=`{"1":[
    {"resource_id":"[[*the_ids]]"},
    {"OR:resource_id:IN":"([[*the_ids]])"}
    ]}`
]]

I don’t think this actually returns anything. I’m mostly curious about trying to use the “IN” search. Because of the $debug, I get to see the query, which has this in it:

FROM `modx_the_art_table` AS `artWorks` WHERE ( `artWorks`.`resource_id` = '53,54,55' OR `artWorks`.`resource_id` IN '(53,54,55)' )

What might be wrong is putting the parenthesis after IN, in quotes. If the quotes shouldn’t be there, I don’t know how to remove them.

Or maybe someone knows where I can get more in-depth docs on how to use this snippet.

I think, they should enter the ids, not the resource_ids. Then it would look like that:

&where=`{"id:IN":[ [[*the_ids]] ]}`

Alternatively you maybe could use the extra SuperBoxSelect.
It has pagination which is advantageous with 7000 database entries.
‘Out of the box’ it only supports the built-in classes modResource and modUser, but it is possible to add support for custom classes, if you create your own custom getlist processor.

  • Set the system setting superboxselect.advanced to Yes.
  • Create the processor file under core/components/artwork/processors/types/artwork/getlist.class.php. Copy the code from the modUser processor. Change the $classKey to 'artWorks', replace username with title, delete the stuff with the user groups and override the initialize-function to add your package ($this->modx->addPackage(...))
  • In the ‘Input Options’ of your TV set the field “Package:” to artwork and “Type:” to artwork.artwork.

You are correct, it can just be “id”. The “resource_ids” was used in some other templates I had just copied it over.
However, this query looks like it returned ALL results. I don’t think it actually put the “IN” into the query at all. Maybe wrong syntax or something. I’ll keep playing with it.

OK I had to dig in more to the syntax and it looks like MIGX uses a MODX function “fromJSON()” to parse the &where content.
I still had double-quotes around my array, like "id:IN":"[ [[*the_ids]] ]"
All I had to do was not use the quotes, and stick with square brackets, cause fromJSON() converts it to proper use of parenthesis.
I was trying to do stuff like "id:IN":"( [[*]] )" but this would return a literally 0 and nothing would happen.

It’s working now that I have a handle on the syntax.
I wish this stuff was better documented!

Update: also found the importance of keeping a space between the square brackets. [ [[*]] ] versus [[[*]]]. Without the extra spacing it doesn’t work.

you are not alone :smile: