Jump to content

Repeatable Fields


ryan

Recommended Posts

I just committed FieldtypeRepeater to the core, so it's now there, though as a 'beta' module. Right now it's in a fairly simple form, as I still have some more options being worked on with it. But I wanted to get it posted for those that wanted to try it and help test it. Since I'm the only one that's used it so far (and on basic/small things) I don't suggest using it in production just yet, as there are bound to be issues uncovered as others test it. I appreciate any help testing this.

To install, just make sure your core is up-to-date, go to Admin > Modules and click 'Check for new modules'. It should find FieldtypeRepeater. Click install. Then create a new field and select 'Repeater' when it asks for the type.

Once you've added a repeater field to a page, you use the field from the API exactly as you would any other multi-page reference field (see the first post for an example).

I also want to note that if you have 'debug' mode enabled in your PW, the Repeaters Fieldtype is quite chatty (which you may or may not like). If debug mode is off, the fieldtype will do its job quietly.

Link to comment
Share on other sites

Has anybody had the chance to try out these repeatable fields yet?

I have one more update that I put in the latest commit, though this applies to all fields, not just repeatable fields. This update enables you to create columns rather than just rows. You can now specify a width percent in any field's input settings (or use the columnWidth property on an inputfield from the API). Here's a screenshot of the new setting:

post-2-0-39425100-1329842532_thumb.jpg

And here's the result (combined with a repeatable field). In the screenshot below, I've set building_name to have a width of 50%, floors to have a width of 25% and height to have a width of 25%:

post-2-0-63011500-1329842516_thumb.jpg

Note that because this involves some stylesheet tweaks, this may not work on 3rd party admin themes right away. But I'll be happy to assist admin theme developers to add the necessary stylesheet tweaks to make this work.

  • Like 4
Link to comment
Share on other sites

Thats awesome feature! Cant wait to present it to the clients.

I was wandering what are the Repeater disadvantages compared to the children model "used before" related to Search and selectors?

Which template cache settings should to be used when updating Repeater field?

- Clear cache for current page only

- Clear cache for entire site *

- Clear cache ...

- ...

BTW. The Repeater (tested without the columnWidth) is working flawless.

Link to comment
Share on other sites

Seddass, thanks for your feedback.

I was wandering what are the Repeater disadvantages compared to the children model "used before" related to Search and selectors?

While I've now had a lot of experience developing them, I've not yet had much experience using them. So I don't feel all that qualified to outline the cases where one should or shouldn't use them. However, my feeling is that repeaters are ideal for reasonably small collections of data that don't need their own page URL.

For instance, an office locations list or employee directory or something of that sort. Instances where you are going to be outputting the data in some table or list together, much like you edit them together. But I think the potential uses are much more broad than what I can think of right now, so this might be a better question for someone that's used matrix fields in EE or ACF in Wordpress, or a question for me to answer a couple months from now. :)

Search and selectors?

By default, the repeater pages are created somewhere outside of your site tree (actually in /processwire/repeaters/). Because they are hidden off below the admin, they aren't searchable as pages themselves, except by those with admin access. That's intentional. We don't want selectors matching these pages since they aren't being used in the context of pages (at least not by default). I will be adding an option to make them "detached" so you can place them wherever you want and actually use them as pages in your site should you want to. But that will be an option, not the default behavior.

Because they aren't searchable on their own by default, they have to be searched within the context of the page where they are used. So if you wanted to match all pages that had a 'buildings' having 40+ floors and a height field 800 or fewer feet, you'd do this:

$pages->find('buildings.floors>=40, buildings.height<=800'); 

If you just wanted to match pages that had one or more buildings:

$pages->find('buildings.count>0'); 
$pages->find('buildings>0'); // this also works 

Which template cache settings should to be used when updating Repeater field?

This doesn't matter unless you actually implement a template file for your repeater field. So you should be fine to clear the current page only, unless you prefer to clear the site for another reason.

If you want to implement a template file for your repeater, you create a file in your /site/templates/ named "repeater_[field name].php", i.e. in the case of the buildings field, it would be "repeater_buildings.php". That template file will receive a $page variable that is represents one 'buildings' record. So you could do something like this:

/site/templates/repeater_buildings.php

<?php
echo "<h2>{$page->building_name}</h2>"; 
echo "<p>{$page->floors} floors, {$page->height} feet</p>";

The template used by your page with a 'buildings' field could then do this:

/site/template/basic-page.php

foreach($page->buildings as $building) {
   echo $building->render(); 
}

However, for a relatively simple case like this, I would probably not bother with creating a repeater_buildings.php template file, and instead just put it all in the basic-page.php template. But if you do use the approach of rendering repeater elements with their own template, then you would want to consider the cache. Rather, you'd probably want to avoid using the cache for your repeater_buildings template and instead just rely on the cache used by your basic-page template.

Link to comment
Share on other sites

Awesome with the rows! Great work I'm going to test now.

BTW why didn't you use my slider field? :P I know it isn't in the core... just kidding.

I'm testing it since yesterday and have had some issues, and some very strange issues.

- Thumbnails doesn't work. The edit links isn't found. Not sure whos responsible for this :D

- can't see the images in the RT from an image field in the repeater itself.

- When I add element, add image then delete it after save, after adding a new element the image is still in the there.

- I think the slider collumn field isn't saving, because I have to reinstall first? haven't tried yet.

Strange:

- When first time testing I did a repeater in a repeater and it doesn't seem to work. I removed the repeater and added new normal one text,slider,image,richtext. After that I experienced being showed the error by my own "soft edit page lock" module, after saving the page with repeater field, that the page is currently being edited by myself... Somehow does the session change or something? Now I only expereinced this 2-3 times and now since I created a new repeater without slider it haven't seen it yet again. Though I'll try test again see if I can reproduce.

Link to comment
Share on other sites

Columns are fantastic. One thought on the slider: I think there's much more precision than is needed in this context, i.e. the vast majority of people are going to set it to 25, 50, or 75%, so being able to set 51% is actually kind of annoying as you have to nudge it into the number you want. Maybe it could even just be 1, 2, 3, or 4 (it assumes a 4-column admin layout)?

Link to comment
Share on other sites

Thanks for testing it out Soma and Statestreet.

Thumbnails doesn't work. The edit links isn't found. Not sure whos responsible for this

Are you talking about the Thumbnails module by Antti? I haven't tried it out with the repeater yet. In order to work in a repeatable, a module would have to be okay with having multiple instances of itself on the page (whether in a repeatable or just used by more than one field). All the core field types are good in this area, as far as I know. One way to test it is to just create two separate fields that use the Thumbnails module, assign them both to the same template, and then attempt to edit a page with that template. If you get the same issue, then very likely there is some hard-coded ID attribute in one of the elements or something.

TinyMCE didn't take kindly to being in a jQuery sortable, so I had to make some adjustments for it. If you drag a repeater with a TinyMCE in it, you'll see I had to turn off TinyMCE for the field during the duration of the drag. But other than that, I've not run into problems with any other fieldtypes. If the Thumbnails module doesn't work now, I'm sure we'll be able to find a way to make it work.

can't see the images in the RT from an image field in the repeater itself.

I don't understand. What's an RT? (retweet?) :)

When I add element, add image then delete it after save, after adding a new element the image is still in the there.

Just confirmed -- this is a bug. If you only populate an image field (and not any other fields on the item) the page and image gets saved with ajax. The repeater doesn't get the opportunity to see a change was made. But I think this'll be an easy fix.

I think the slider collumn field isn't saving, because I have to reinstall first? haven't tried yet.

Can you clarify? Are you talking about the column width percent? You shouldn't have to reinstall anything. But make sure you are using the default admin theme, and hit reload once or twice to make sure you don't have JS or CSS files from an old version.

Somehow does the session change or something?

The repeater is basically rendering the Inputfields for multiple pages, so chances are that the soft lock is hooked into something that is getting called several times rather than just once. We can take a closer look at interactions with other modules, though I'm thinking I should work out any bugs with the Repeater module first.

Now I only expereinced this 2-3 times and now since I created a new repeater without slider it haven't seen it yet again.

Browser cache is always a possibility too.

I think there's much more precision than is needed in this context, i.e. the vast majority of people are going to set it to 25, 50, or 75%, so being able to set 51% is actually kind of annoying as you have to nudge it into the number you want. Maybe it could even just be 1, 2, 3, or 4 (it assumes a 4-column admin layout).

I think that's a good idea, but I also don't want to make too many assumptions here. If someone wants 10 columns of integer fields, they should be able to do it. But I don't want to limit the increment to 10s, because than would mess up someone doing a 4 column of 25%. Likewise, don't want to limit the increment to 5s because that would screw up the person trying to do 3 equal columns. Ultimately it doesn't seem like I can impose pre-defined increments here without excluding a lot of useful possibilities.

Link to comment
Share on other sites

The repeater is basically rendering the Inputfields for multiple pages, so chances are that the soft lock is hooked into something that is getting called several times rather than just once. We can take a closer look at interactions with other modules, though I'm thinking I should work out any bugs with the Repeater module first.

The soft lock checks for the user and only outputs error message when the user saved in the table isn't the same one. So what does that tell? :D

Browser cache is always a possibility too.

Could be but I got cache disabled and it occured multiple times... It seems gone one I removed range slider from repeater. Doesn't make sense, but maybe.

I don't understand. What's an RT? (retweet?) :)

I have a image field in the repeater and a RT (richttext) TinyMCE. If I upload an image it doesn't show up in the TinyMCE image dialog, but other images outside the repeater does.

Thumbnails work, but can't edit them anymore if it's in the repeater, the "edit" link opens in new window, there the url can't be found. It work with images outside repeater, even multiple.

Link to comment
Share on other sites

I think that's a good idea, but I also don't want to make too many assumptions here. If someone wants 10 columns of integer fields, they should be able to do it. But I don't want to limit the increment to 10s, because than would mess up someone doing a 4 column of 25%. Likewise, don't want to limit the increment to 5s because that would screw up the person trying to do 3 equal columns. Ultimately it doesn't seem like I can impose pre-defined increments here without excluding a lot of useful possibilities.

That makes sense. That got me thinking, though (at the risk of overthinking :) ), how about a drop-down next to the slider that selects how many columns you want to divide into?

2/4 |========[]========| Columns: [ 4 ▼ ]

So if you're doing 10 columns of integer fields, you can easily jump to 1/10th, and if you're doing something like sixths, you don't have to stop to mentally calculate what percentage one of those is.

Link to comment
Share on other sites

Ryan, you went much further with this than i ever imagined :)

I really think this will make the editors experience much more pleasant and easier. But it will at the same time ask for a more responsible and detailed work from the developer.

The columns are just great! I had to go look for the post where I asked this some time ago http://processwire.com/talk/topic/715-adding-complexity-to-template-forms/page__hl__complexity__fromsearch__1. Your implementation is way better ;)

Link to comment
Share on other sites

I'm still getting sometimes this error message that another "me" user currently is editing this page! :D from the when I save page.

Don't really see what it could be.

BTW it would be somehow be cool to update the #index when dragging an item. I think it could make sense since it isn't saved anyway. Though It may would be even cooler to have a title somehow "name" shown in the bar, that is recognized when collapsed not just #1,#2,#3.

Link to comment
Share on other sites

So if you're doing 10 columns of integer fields, you can easily jump to 1/10th, and if you're doing something like sixths, you don't have to stop to mentally calculate what percentage one of those is.

assume that all colums are equal do you? screen shot show columns, lengths different

Link to comment
Share on other sites

That makes sense. That got me thinking, though (at the risk of overthinking :) ), how about a drop-down next to the slider that selects how many columns you want to divide into?

2/4 |========[]========| Columns: [ 4 ▼ ]

So if you're doing 10 columns of integer fields, you can easily jump to 1/10th, and if you're doing something like sixths, you don't have to stop to mentally calculate what percentage one of those is.

I think it's not as a good idea as it might sounds, you can't do smaller than 10% anyway..

so

  • 10 elements easy
  • 9 easy let it on 10%
  • 8 set it to 10 or 12%
  • 7 set it to 12%
  • 6 set it to 15%
  • 5 set it to 20%
  • 4 => 25%
  • 3 => 33%
  • 2 => 50%
  • 1 => let it how it is.

Simple enough I think and there isn't much to it either. And having to first select the dropdown every time won't help much, or even save it will come in the way at some point anyway where you have to change it again. So I think it's ok as it is for now. :)

----

Label not translated. Bug?

Ryan. The label of the repeater field the one you can drag, doesn't show me the german label..

Link to comment
Share on other sites

Ryan, well, it's actually everytime I add a new element enter something and save it first time, I get the soft page lock. After that saving is normal, until I add new element. I have latest PW and nothing special installed , and also deinstalled couple and still same. Also tried different fields each time. Seems an issue in combinations with user data that is handled by my "PageEditSoftLock" module.

Could you if you have time take a look into what could cause this? And if you can reproduce.

Something else:

post-100-0-69169600-1354551837_thumb.jpg

:D

Link to comment
Share on other sites

Soma thanks for all your testing. I hope to test, reproduce and resolve the issues you've mentioned tomorrow morning, and then post a new update.

Thanks also to Statestreet, Diogo, Seddass and Biotech for the testing and feedback.

2/4 |========[]========| Columns: [ 4 ▼ ]

Compliments on this diagram, quite cool. :) While I need to retain the ability to have columns of different lengths, I do think this would be perfect if we were sticking to columns of the same width.

I'm still getting sometimes this error message that another "me" user currently is editing this page!

I should be able to figure it out when I test tomorrow.

BTW it would be somehow be cool to update the #index when dragging an item. I think it could make sense since it isn't saved anyway. Though It may would be even cooler to have a title somehow "name" shown in the bar, that is recognized when collapsed not just #1,#2,#3.

Showing the title in the bar is something I'd like to do, it will be coming. But will just require that the repeater has a title field (title fields aren't required for repeaters).

Label not translated. Bug?

Ryan. The label of the repeater field the one you can drag, doesn't show me the german label..

It's just not yet language aware in that regard. I'll add that in on the next update though.

Something else:

Beautiful! :)

Link to comment
Share on other sites

assume that all colums are equal do you? screen shot show columns, lengths different

Quite the opposite, actually! That's one of the benefits of this approach—you set the divisions to, say, 8, then you can have one field that shows up five times in a row and is set to 1/8, then one field that shows up once and has the slider set to 3/8.

Anyway, not to get hung up on this; I just like adaptively granular controls. :)

Link to comment
Share on other sites

Ryan. Something that just hit me hard. While thinking all the time about these columns, setting them up makes just clear that the implementation is on the wrong level. It should be something to define on templates level to keep re-use ablity alive as much as possible and separate structur from the data as long as possible. Having "editing mask" layout setting on field level seems just wrong to me. I hope you proof me wrong.

I really think it would make it a lot better if these information would be held on template level or in this case the repeater field group. While I think a good implementation would go very far regarding "interface" with some kind of editor with drag and drop, defining columns, but surely something possible. But maybe just having some sort of a text inputfield along each field in the drag bar to enter a % number could do the job in its simplest form.

I'm really loving what you've doing here, just wanted to give my honest feedback. While I've had my wow moments (dancing in the kitchen) while playing around with all these stuff, I'm looking a little closer and try to look at all the different aspects.

Link to comment
Share on other sites

Soma I think there's multiple ways to look at it, but I'm not too enthusiastic about getting the templates involved in individual field settings. That seems like blurring the line about where things are defined, leaving one to guess where they would define one thing or another. This is when software gets complicated. Would you really want to define the width of the field in the template and then the type, size and maxlength with the field? These things are all related and shouldn't be separated in my mind. Templates aren't supposed to know anything about fields other than which ones they have. I do think about this stuff a lot before coding it. I also appreciate exploring this from all angles, and that's why I'm very glad to have you involved in this project. Your viewpoint is always valuable and well thought out.

Consider how we work with markup. When you define floats, the container doesn't decide the proportional width of the floats--the floats do. When we define the type, size and maxlength of a field, we define it with the field, not the container. If a field is suitable for use in a narrow column, that's got to do with the type of field that it is and how you've configured it. This is the field's data.

Reusability is far from black and white here. If you've setup a field for reduced-width use, shouldn't that remain consistent regardless of whether you are using it for columns or not? There's more than one reason to set the width of a field. Another consideration is that if we start defining field widths with the template right alongside the fields, people will think this is something rather important. I don't want people to think they have to use this. It's a nice optimization, and far from a requirement. If this were particularly important we would have had it a long time ago.

Where I like your idea is as an add-on or override at the template level for the power-user. The field still defines its width, but you have the opportunity to override it in the template. That way the field still owns the data it should, but the template can see that and choose to override it. If you only wanted to define it at the template level, then you could. I want to hide the details of that by default so as to avoid confusing what is template data and what is field data, but give the option to the power-user. So I'm thinking an optional module or setting one can turn on if they want to define it at that level (and sliders would be particularly fun here).

Link to comment
Share on other sites

Thanks for your reply! My thinking is a little different than yours it seems. :D

I actually think it would simplify a lot. To define the layout mask of the template on the template itself and not on the field. Width is actually something related to the template mask the field will be put, I don't see this same as the other field settings.

Also regarding re-usability of the fields. This would have effect on how fields can be used across different templates, I don't want to have multiple "title" fields just because one I want one 50% and the other 100%...

This way (defining on template level) it wouldn't make it more complicated, but as it is now, it's actually getting complicated: to maintain, to setup and to trace...

Whereas when defining such things on template, would require one look and one place to edit these widths. As it is now, I can't see what field has what width and makes it hard to keep track of it.

As you say there's different views on this particular subject, but I'm sure I'm not alone on this.

I think having the possibility to overwrite the width setting of a field on template as a option, will make it blurry and "complicated" and it opens traps and confusion. I just have hard time accept in my mind that this would be a good way to get around the problem.

---

Problem report:

When I add a file field with small width, the upload button gets overlayed by the "drop files here"... note in the field, and I can't click it to upload a file.

Link to comment
Share on other sites

What Soma is saying makes some sense if we look at it, not only from the perspective of these new fields, but also in general with other fields. I felt the need to define, for instance, the name of one field, differently on different templates several times. I mean... If i want to use the same field, with all the same characteristics, but with only a different name, why should I create another one, and another, and another, depending on the template? What maybe would make sense (could be a module like Ryan suggests), would be being able to override the settings of each field while creating the template. But as I say, this would apply to all field settings, and not only the columns.

EDIT: at same time Soma. Overwriting can make more trouble if you do it on all of them, but if you do it only on some, it makes less trouble. I think it's good to have a default value.

Link to comment
Share on other sites

When you edit a field, there is a tab called 'input' and that's where you define the settings related to the input field presented to you in the admin. When you edit a template, you are there to edit the settings related to the template, not the individual fields. Maybe you don't agree with this architecture, but that's the way the system was designed from the beginning and I don't want to cross those concept boundaries until they fit the bigger picture of the system. That bigger picture is called template field context, and that's a feature that's already planned for and something we've been talking about for a long time. But also something that's going to take some real time resources to do well, and it can't be done now. But when we go there in a future version, you'll be able to modify some field settings within the context of the template. Things like title, description and now likely width. But I'm not interested in blurring this line until we have full support for field contexts within templates.

As you know, ProcessWire does not currently support those different contexts for a field on a per-template basis. If you are creating multiple fields just to get different widths, stop doing that. You should not be using field widths in that case--leave it as a normal PW 100% width field like you've always used. These width settings are for when you have a specific need, like a pricing table or something like that. They are not something you should use on every field and not something you should use on fields where you need all kinds of different contexts.

Because PW has always had 100% width fields before yesterday, not every field is going to be a good candidate for reduced width -- Soma the file field probably shouldn't be used at anything less than 50% at present. I would expect there will be other fields that won't be happy at reduced width, though I've not found any yet.

Link to comment
Share on other sites

Seems an issue in combinations with user data that is handled by my "PageEditSoftLock" module.

I tested it out with PageEditSoftLock and found the problem. The reason it tells you that another instance of you is editing the page is because of this statement in the checkpagestatus function:

$user = $this->users->get($user_id);
if($user === $this->user){

When a new repeater page is added, it goes through a $pages->save(). After $pages->save() finishes, it clears the in-memory page cache to ensure any future $pages->get/find operations in the same request aren't returning old versions (it has always done this). Users are pages. As a result, your $this->users->get($user_id) is returning a new instance of the current user than what is in $this->user, so a '===' comparison won't work, since it checks to see that two objects are the same instance. But the fix is easy, just change the above code segment to this:

if($user_id == $this->user->id) {

This is also more efficient, as there's no need to retrieve the user from $this->users->get() when all you need is the user ID, and you already have it.

---

Edit: fixed issue with the repeater labels note honoring the language setting. They should work properly now.

  • Like 1
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...