Jump to content

Repeatable Fields


ryan

Recommended Posts

Stephen, I haven't fully developed the API for this field just yet. But here's how you'd do it at present (and it will get a lot simpler than this). I've written this in the browser so there might be mistakes here, and I can try to test this out later.

// create the new repeater field
$repeater = new Field();
$repeater->type = wire('modules')->get('FieldtypeRepeater');
$repeater->attr('name', 'my_repeater');
$repeater->label = 'Your Field Label';
$repeater->save();

// forces a self-setup + configuration (this is an odd step, I know, will improve)
$repeater->type->getConfigInputfields($field);
$repeater->save();

// add some other fields to the repeater
$repeaterTemplate = wire('templates')->get($repeater->template_id); // get the template used by the repeater
$repeaterTemplate->fields->add(wire('fields')->get('title')); // add title field
$repeaterTemplate->fields->add(wire('fields')->get('summary')); // add summary field
$repeaterTemplate->fields->save();

// add the new 'my_repeater' field to your the 'basic-page' template, as an example
$template = wire('templates')->get('basic-page');
$template->fields->add($field);
$template->fields->save();

Now to jump to another example. Lets say you already have a repeaters field called $page->my_repeater and you want to add a new repeater item to it:

$repeater = wire('fields')->get('my_repeater');
$item = $repeater->type->getBlankRepeaterPage($page, $repeater);

$item->title = 'Test item';
$item->summary = 'This is just a test item';

$page->my_repeater->add($item);
$page->save();

This is all a little complex from the API side in my opinion, so I'll be making this a lot simpler... but just wanted to at least reply with a useful example.

Link to comment
Share on other sites

Soma, Diogo: you'll be glad to know I've taken a close look at field template context and how we might support it in the core. It'll be simpler than I thought, so there's a good chance I can get this in version 2.2, relatively soon. Now that I understand how we'll do it, I think we'll be able to provide template context of almost any field setting (custom and internal). So it will likely go beyond just title, description, collapsed, width, etc. To change the context of a field within a template, you will edit a template, then click on a field name or edit icon (in the asmSelect). It'll open a modal window with all the field's configurable settings, all within the context of the template. I think this will be pretty cool.

Link to comment
Share on other sites

Soma, Diogo: you'll be glad to know I've taken a close look at field template context and how we might support it in the core. It'll be simpler than I thought, so there's a good chance I can get this in version 2.2, relatively soon. Now that I understand how we'll do it, I think we'll be able to provide template context of almost any field setting (custom and internal). So it will likely go beyond just title, description, collapsed, width, etc. To change the context of a field within a template, you will edit a template, then click on a field name or edit icon (in the asmSelect). It'll open a modal window with all the field's configurable settings, all within the context of the template. I think this will be pretty cool.

Awesome Ryan! This will simplify a lot. You know, I was actually thinking quite a lot of times, that it would be nice and possible, to completely being able to setup fields within the edit template screen directly, and kinda use dialogs and such to edit fields, drag them into the template etc. After first week starting with PW back then, I was even starting to play around in my mind with creating a visual node template editor with raphaël js (brilliant svg) library. :D I found it would require a lot of experimenting and some better knowledge of PW. Also there's no really good implementation of a visual node (with drag drop connecting and stuff) for raphaël yet, only one more decent and unfinished. So writing one my own first would go a little far and held me up.

Can't wait to get my hands dirty with this new feature and see how it feels! Thanks for your continuous effort to make this the best CMS around.

Link to comment
Share on other sites

Soma, Diogo: you'll be glad to know I've taken a close look at field template context and how we might support it in the core. It'll be simpler than I thought, so there's a good chance I can get this in version 2.2, relatively soon. Now that I understand how we'll do it, I think we'll be able to provide template context of almost any field setting (custom and internal). So it will likely go beyond just title, description, collapsed, width, etc. To change the context of a field within a template, you will edit a template, then click on a field name or edit icon (in the asmSelect). It'll open a modal window with all the field's configurable settings, all within the context of the template. I think this will be pretty cool.

This all sounds amazing Ryan. Field contexts on a template level will allow so much flexibility in the admin. We can then create ever more usable, custom admin screens for clients - simplifying the editing process for them. I can imagine that it will also keep the number of different fields necessary down to a minimum too?

This is a really exciting development.

Link to comment
Share on other sites

Thanks. I agree this does have potential to reduce the number of fields you might need, or at least, allow you to be more specific and contextual with the information you present with the fields. Ultimately it should lead to a better experience either way.

Link to comment
Share on other sites

Just tested reusable fields and I'm really happy with this handy feature as there are so many use cases. Thanks so much for this!!

Two thingsI stumbled upon:

1) I couldn't change the »input field settings« from »always open« to somethings else. It jumps back to the basics tab but doesn't save the change.

2) Is there a special setting to make the output of a repeatable field viewable to users who are not logged in? Currently I only see the output when I'm logged in.

Link to comment
Share on other sites

For my work this is a HUGE step forward. I'm using this on a site that we're developing right now and the structure look so much better.

The only bug so far is the one christoph has already mentioned: the visibility settings don't work. Will we have separate options for the repeater and the items inside the repeater?

Link to comment
Share on other sites

I've been tinkering with this with a view to some sort of invoicing system (if you think about it, the only thing missing to produce something like that in PW was repeatable fields and adjustable-width columns, both of which are now here ;)).

The only thing I feel is missin is the ability to display repeatable fields as a table, or more of a grid view. What I mean is the field titles are repeated with every repeater row, whereas for invoicing or similar needs it would be great to have them as a grid.

One of the problems here is that as far as I can tell grid views aren't part of jQueryUI (yet), however when I looked at the example 3rd party plugins I immediately got excited by SlickGrid's examples - check out the Making it editable example, as well as looking at the different ways to display data (although data display should be more about the end-user experience and doesn't belong in the admin, but you get where I'm going with the editable part of it at least).

My thinking is that to achieve something like this requires:

  1. Settling on a jQuery plugin to use - requires some thought as you wouldn't want to have to change it at a later date ideally
  2. Adding a checkbox to repeatable field configuration to choose to display it as a grid instead of the normal repeater - this needs the usual "only tick this if your repeater will display tabular data" disclaimer as it will obviously break if you add image fields or RTE text fields etc to your repeater.
  3. Some code to display it as a grid
  4. Some code to add a button to the end of the table to add another row, as well as a button at the end of each row to remove only that row

I think that's it - sounds easy huh? ;) I'm not sure whether ryan already has plans for something like this, or whether it should be included as part of the current module or as an additional module if it were ever to be built, but I think the possibilities for this could be very exciting indeed.

Link to comment
Share on other sites

I think I would be better to build a "table grid" module, rather than "violating" the repeater for a "table" like display which isn't meant to be in first place, it's an "element repeater". I could imagine having table like field type for this sort of table data, that is configurable to have certain number of columns. Then use such a plugin as datatables or slickgrid's to handle the UI.

Link to comment
Share on other sites

That's pretty much what I was saying - take a look at the example I linked to ;)

My thinking was that when they're in the database they're essentially the same thing, so rather than reinvent the wheel...

You still want the fields values to be stored separately in the database - for example if you then built a template to display rows from an invoice it would need to calculate the totals for each row (quantity x unit price) and the overall subtotal, tax and total. Similarly you could then build a module to automatically email something like that to a client when the page is published.

The way I'm thinking about it, a "row" is a repeatable element, which is where I thought it would be a natural extension of the current module (whether as part of this module or another additional module that requires the current module).

Link to comment
Share on other sites

I know them Pete, I already used them in projects (even PW), I just can't see that it's something easy to implement for the repeater field the way it's done.. .

But maybe I'm wrong. As I see it is that you have a table with text and number, not images, page refs , RT's etc. So I could see an easy implementation that's using datatables and the data stored as serialized array. Just trying to look at it different. :D

Link to comment
Share on other sites

I did think serialized arrays at first and they would be cool too, but then you can't easily show multiple invoices for clients with total value outstanding etc - I'm thinking more complex, searchable, sortable needs which is why I thought of repeaters, as then you just iterate through each row and build your totals up to display at the bottom (on the front-end or a client-restricted admin page) :)

Link to comment
Share on other sites

Darn, I just wrote up a long reply and accidentally closed the window trying to do a screencap. I've run out of time to redo it, but going to try and summarize: :)

  • You can sort of use repeatable fields for this now, but they won't look like a spreadsheet
  • Repeatable fields aren't ideal for this because they can support ANY fieldtype. In a grid/spreadsheet view, you only need to support limited data types.
  • I think it would work best as it's own FieldtypeMulti, where it manages it's own data with columns in a table… more traditional database style. PW API supports searches in anything that has it's own column in the DB schema, so long as an index is defined for it (in MySQL). This would be more efficient in this case because the limited set of data types you'd need to support line up nicely with how you'd define a DB table. Pages are of course a lot more flexible, but you don't need that flexibility here.
  • I've built fieldtypes like this for managing property availability and rates. It's not hard to do by making your own FieldtypeMulti. This is exactly what the FieldtypeMulti class is designed to do. (FieldtypeComments and others are based on it). The main challenge in this Grid Fieldtype would be in making the schema configurable per field, but I still think it's well within reach.
The only bug so far is the one christoph has already mentioned: the visibility settings don't work. Will we have separate options for the repeater and the items inside the repeater?

Sorry, I missed that before. I fixed and committed it over the weekend.

2) Is there a special setting to make the output of a repeatable field viewable to users who are not logged in? Currently I only see the output when I'm logged in.

Repeater fields are meant to be iterated like any other group of pages, and they are technically no different. That means you have to foreach() them and output them in the manner you want. I will probably include some default render() method in there in a future version, but it would mainly only be useful for testing/debugging. There is also an example of how to output repeater fields on the first page of this thread.

Field contexts on a template level will allow so much flexibility in the admin. We can then create ever more usable, custom admin screens for clients - simplifying the editing process for them.

I'm glad to report that Template>Field contexts are now completed and working. I'm going to be testing here more before committing to the core source, but wanted to let you guys know you'll be able to use them in the next week. I'll be posting a video in the next day or two. Also, I have limited the field properties that can be configured per-template to include just these:

  • Label (including all languages)
  • Description (including all languages)
  • columnWidth
  • Visibility (collapsed settings)

I think these are the most likely ones to be configured in this manner. Though technically, the core can support configuration of any field property (including all custom ones defined with an inputfield or fieldtype). But I've specifically disabled those for now as it makes me think I'd need to do a lot more testing before putting this out there. I'll probably enable it as an advanced mode option for anyone that wants it, after confirming that everything works well with these basic settings in lots of different contexts.

Link to comment
Share on other sites

Thanks ryan - for some reason I completely forgot about FieldtypeMulti which will, as you say, eliminate most of the headache as well as be able to provide me with a more sensible single table in the database with many fields, which is perfect for the various scenarios I was thinking of (I actually mocked up an idea for the invoicing repeater before my previous post and noticed I was quickly racking up a lot of separate fields just for that, so this is a much better way to go).

Sorry Soma if you had suggested that or that was what you meant - it wasn't until ryan said FieldType multi that it sank in ;)

Link to comment
Share on other sites

Repeater fields are meant to be iterated like any other group of pages, and they are technically no different. That means you have to foreach() them and output them in the manner you want. I will probably include some default render() method in there in a future version, but it would mainly only be useful for testing/debugging. There is also an example of how to output repeater fields on the first page of this thread.

Thanks for your reply, Ryan.

The problem I have is a little different. I have no problem creating output with a foreach(), the problem is that I only see that rendered HTML output if I'm currently logged into the system. So if I log out or view the page with a different browser I see nothing rendered.

Oh, and while I wanted to check the page just now in the back end I got an error:

Duplicate entry 'for-page-5799-5807' for key 2

Link to comment
Share on other sites

Christoph - are you sure that the page in question's template has view access for guest users? I can't see why it wouldn't, as the default is for guests to view all new templates, but I'm wondering if this might somehow be the case.

Link to comment
Share on other sites

Christoph, it's hard for me to tell for sure how to locate the error without actually seeing it. If you have an admin login you can PM to me, that might help me to see what's going on. Another thing to look at is: Pages > Admin > Repeaters > [your field name] > for-page-5799 (this is where it stores the repeater pages), and see if there's anything there that doesn't look like the others. As for displaying the repeater pages, could I see the block of code you are using to display them?

Link to comment
Share on other sites

Christoph is right, it's not possible to render the repeater field when not logged in as superuser. It must be simply that the repeater pages are located under /admin/ pages. I got similar problems when creating the shop with saved orders as pages under /admin/. I had to do include=all to get it working for other users.

I can't imagine you're not able to reproduce this. I got simple repeater and the following code won't show anything when I'm logged out.

foreach($page->items as $p) {
   echo "<p>$p->item_title</p>";
}
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...