Jump to content

Repeatable Fields


ryan

Recommended Posts

@jbroussia: Thanks, I have looked into this and it is a bug. I think it may be possible to make repeater fields cloneable, but they are kind of a unique situation and the factors involved in cloning them are more broad and complex than with others fields. So my solution for this now is going to be to have it detect when it's being cloned and throw an exception to prevent it from happening. Longer term, I should be able to figure out when I've gone 1-2 days to wrap my head around it. :)

@Pete: He's talking about cloning fields rather than cloning pages. We did fix the issue with cloning pages that have repeaters. But cloning actual fields (Setup > Fields > some_repeater > Advanced > Copy/Clone) is a different thing.

Hope to find a way to make these cloneable. But since this is the first time it's come up, I don't think there's a lot of demand for cloning repeater fields. Unlike cloning pages with repeaters, which is probably a more common occurrence.

Link to comment
Share on other sites

Updated to 2.2.2, the problem remains.

I tried to delete all those repeaters and to recreate them; on my page I have a first repeater sliders and a second features which was created by cloning sliders. If I add a couple sliders items and save, the page will now have the same number of features items :'-(

EDIT: oh Ryan, you replied while I was typing this. That's fine, I will manually clone my repeater. Thanks :)

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

The repeater is still twitchy for me. I have a site where they sell buttons, and I need to be able to associate a name, description and image to each button. The repeatable field is perfect for that since there's only about 5 different buttons but I can't get the images to display.

foreach($page->get("product") as $item) {
if (count ($item->product_shot) > 1) {
echo "<div class='productcontainer'><div class='prodpic'><a class='nowandthen'><img src='{$item->product_shot->url}' alt='{$item->product_shot->description}'>
<img src='{$item->product_shot->url}' alt='{$item->product_shot->description}'></a></div>\n<div class='prodtext'><h2>{$item->product_name}</h2>\n{$item->product_description}</div></div>";
} else {
echo "<div class='productcontainer'><div class='prodpic'><img src='{$item->product_shot->url}' alt='{$item->product_shot->description}'></div>
\n<div class='prodtext'><h2>{$item->product_name}</h2>\n{$item->product_description}</div></div>\n";
}
}

I get

<img src='/pw/site/assets/files/1010/' alt=''>

in the markup while the name and description displays correctly.

I have almost the same set up in my own photography site for the galley where I have a name field and description associated with each image and it works (although I don't remember how I got it to work because it didn't at first either). is my selector wrong? "Product" is the repeater.

Link to comment
Share on other sites

Depends on how you define the "maximum files allowed" in the "input" tab of the image field. If you allow more than 1 image, PW returns an array of images, regardless of the effective quantity. So in your code you should have:

foreach($page->get("product") as $item) {
if (count ($item->product_shot) > 1) {
echo "<div class='productcontainer'><div class='prodpic'><a class='nowandthen'><img src='{$item->product_shot->first()->url}' alt='{$item->product_shot->first()->description}'>
<img src='{$item->product_shot->first()->url}' alt='{$item->product_shot->first()->description}'></a></div>\n<div class='prodtext'><h2>{$item->product_name}</h2>\n{$item->product_description}</div></div>";
} else {
echo "<div class='productcontainer'><div class='prodpic'><img src='{$item->product_shot->first()->url}' alt='{$item->product_shot->first()->description}'></div>
\n<div class='prodtext'><h2>{$item->product_name}</h2>\n{$item->product_description}</div></div>\n";
}
}

If you only want to have one image per (repeater-) field it is better to determine "1" as maximum in the field input settings. Because as a nice side effect, the existing image will be overwritten when you drag a new one into that field, no need to trash it manually by clicking the trash icon. And then there is no array returned and your code should work without changes.

  • Like 1
Link to comment
Share on other sites

No image displays regardless of how many images are posted. There's 2 allowed in the maximum files allowed so in this part:

if (count ($item->product_shot) > 1) {
echo "<div class='productcontainer'><div class='prodpic'><a class='nowandthen'><img src='{$item->product_shot->url}' alt='{$item->product_shot->description}'>
<img src='{$item->product_shot->url}' alt='{$item->product_shot->description}'></a></div>\n<div class='prodtext'><h2>{$item->product_name}</h2>\n{$item->product_description}</div></div>";
}

It displays 2 images as part of a CSS3 hover effect that replaces one image with another during mouseover but even if I remove that part of the code and just keep:

echo "<div class='productcontainer'><div class='prodpic'><img src='{$item->product_shot->url}' alt='{$item->product_shot->description}'></div>
\n<div class='prodtext'><h2>{$item->product_name}</h2>\n{$item->product_description}</div></div>\n";

It still doesn't display any image even when only one image is posted. I need to get at least one image to appear before I solve the problem of multiple images. I will use the $item->product_shot->first()->url when I get to that point though. Thanks.

When I use ($item->product_shot} strangely it returns the names of the images (both images) without the URL but when I use {$item->product_shot->url} it returns the URL but without the image names.

Link to comment
Share on other sites

When I use ($item->product_shot} strangely it returns the names of the images (both images) without the URL but when I use {$item->product_shot->url} it returns the URL but without the image names.

($item->product_shot} return array, maybe stringyfied..

{$item->product_shot->url} because it's an array and the image not accessed using first() or any index but the field itself, it returns the path to the page asset folder.

Link to comment
Share on other sites

($item->product_shot} return array, maybe stringyfied..

{$item->product_shot->url} because it's an array and the image not accessed using first() or any index but the field itself, it returns the path to the page asset folder.

OK. I'm not following you though. It still doesn't display the image. I was just pointing out that the selector seems to be ok since one displays the image name but not the url and the other displays the url but not the image. I have used that exact code on another site and it works but not here. If I only have 1 image in the repeater I shouldn't need to use first() and I don't on the other site, and it works, but not here.

it doesn't seem like what I've got is wrong unless I've missed something, it's just not working.

Link to comment
Share on other sites

I think you just don't get it! :P

If you're image field has a max of 2! images, the field returns an ARRAY, EVEN IF only 1 images is uploaded.

So you have to threat it as an array. Hence the example of using $item->product_shot->first()->url. Will return the url of the first image in stack, EVEN IF there's only 1 image uploaded.

You can also use $item->product_shot->eq(1)->url; to retrieve the second one. And so on.

Hope that helps :D

Link to comment
Share on other sites

I think you just don't get it! :P

If you're image field has a max of 2! images, the field returns an ARRAY, EVEN IF only 1 images is uploaded.

So you have to threat it as an array. Hence the example of using $item->product_shot->first()->url. Will return the url of the first image in stack, EVEN IF there's only 1 image uploaded.

You can also use $item->product_shot->eq(1)->url; to retrieve the second one. And so on.

Hope that helps :D

Well, you're right, I don't get it. I'm learning though. Thanks for pointing that out. ;)

You have to admit, your post above

was a bit on the cryptic side for someone who's not fluent like me. I get it now though.

Thanks for everyone's efforts. It was another learning experience at least.

  • Like 1
Link to comment
Share on other sites

That is very common mistake, I remember making it many times. I actually think it might be more clear to image field work always the same on the api. So it would return imagearray even when only 1 image is allowed. I don't like that changing "max no of images" setting might break your site.

Edited by apeisa
now I might make some sense, thanks MMD.
Link to comment
Share on other sites

That is very common mistake, I remember making it many times. I actually think it might be more clear to image field work always the same on the api. So it would return imagearray even when only 1 image is allowed. I don't like that changing "max no of images" setting might break your site.

What changed should be made I'm not sure, I just fear, having it always return array even if it's only one image, will cause the same problem at the end. I can't find the post from Ryan, but I can find 10000 times a post where this was the issue. I think there's no way around having work both ways with single image anyway to maintain backward compatibility.

Remember the issue here with digitexs example is simply about not understanding it is an array, even if it's a singe image uploaded. Imagine it will work with the original code and then upload a second image, it will be hard to understand why it suddenly doesn't work if understanding it's an array arrays is not so obvious.

What about also throwing an explaining error notice if used the wrong way?

Link to comment
Share on other sites

One solution might be to have two fieldtypes: image and images. Other is always single image and other is always an array. Not sure though that this is something that should be changed now - I love the fact that PW API is not changing all the time. This kind of change is something that I would like to see in version 3.0, not during 2.x branch. Also not sure which would be best solution here, but I think the current way is not ideal.

Link to comment
Share on other sites

Why not always returning an array? Don't know how it actually looks like but I think like this:

imageField[0]['url'] = 'path/to/image1.jpg'

imageField[0]['description'] = 'description1'

imageField[1]['url'] = 'path/to/image2.jpg'

imageField[1]['description'] = 'description2'

and in case of a single image:

imageField['url'] = 'path/to/image1.jpg'

imageField['description'] = 'description1'

right so far?

Why not turn this field into an array like:

imageField['url'] = 'path/to/image1.jpg'

imageField['description'] = 'description1'

imageField[0]['url'] = 'path/to/image1.jpg'

imageField[0]['description'] = 'description1'

imageField[1]['url'] = 'path/to/image2.jpg'

imageField[1]['description'] = 'description2'

or if only one image:

imageField['url'] = 'path/to/image1.jpg'

imageField['description'] = 'description1'

imageField[0]['url'] = 'path/to/image1.jpg'

imageField[0]['description'] = 'description1'

so both, imageField->url and imageField->eq(0)->url will work and backwards compatibility will remain? Am I overseeing something in my lack of PHP? :-

  • Like 1
Link to comment
Share on other sites

That's what I meant basicly. Just not the ugly ['foo'] thing. :)

Well what I see is it doesn't solve the problems many unexperienced have they use the single image but they have a multiple image field. And one can even think if I only upload only 1 image it can't be an array.

Edit: Well behind the scenes it's already always an array no matter what max setting is, just the value is treated differently on pages outputFormatting (page context) I think.

Link to comment
Share on other sites

I think it might just be a matter of how it's described in the field setup. It originally started out as just a toggle: "single image" or "multiple images". But it was such a small stretch to make it also behave as a max files quantity, that it went there instead. And I think that may have been the mistake, because the max files quantity is serving two purposes rather than one. But the solution is pretty simple. It would be relatively easy for me to just add another Inputfield to the configuration that says: "Do you want this field to behave as a • single image or • multiple images?" And it would just be a symbolic front to the max-images setting, that hides the multi-purpose nature of it.

While there might be some benefits to having it split out into two separate fieldtypes, there are also great benefits to having it as one. It always behaves as a multi-file field when output formatting is off, so any modules written for files/images automatically support both single and multi-file versions (with no effort). If these were split up as different fieldtypes, it would be more to maintain and people would have to potentially get a lot more code involved when writing anything to do with files/images.

  • Like 1
Link to comment
Share on other sites

I think it might just be a matter of how it's described in the field setup. It originally started out as just a toggle: "single image" or "multiple images". But it was such a small stretch to make it also behave as a max files quantity, that it went there instead. And I think that may have been the mistake, because the max files quantity is serving two purposes rather than one. But the solution is pretty simple. It would be relatively easy for me to just add another Inputfield to the configuration that says: "Do you want this field to behave as a • single image or • multiple images?" And it would just be a symbolic front to the max-images setting, that hides the multi-purpose nature of it.

While there might be some benefits to having it split out into two separate fieldtypes, there are also great benefits to having it as one. It always behaves as a multi-file field when output formatting is off, so any modules written for files/images automatically support both single and multi-file versions (with no effort). If these were split up as different fieldtypes, it would be more to maintain and people would have to potentially get a lot more code involved when writing anything to do with files/images.

I wouldn't call it a mistake. Although I never considered the purpose of the max file setting to be to determine whether to return a single image or an array, I took it merely as a control feature for a site admin to restrict image upload. If left to their own, many users would upload an unlimited number of images and there is a real advantage (load time, bandwidth, server space) to restricting them so that they are forced to edit themselves. It's a nice feature.

Having said that, I have never had an issue with the image field, max file setting or displaying images EXCEPT when an image field is included in a repeater. I'm not saying it's never going to happen again but there isn't necessarily anything to fix either. I think simply including documentation to explain the need to handle it differently with repeaters would do the trick. There's a learning curve to processwire, at least for me :-[ and it only slowed me down for a couple of hours (thanks to MMD and SOMA's help). I didn't see anything specific to images in repeaters in the documentation so if a warnings and pitfalls section was added to explain specific code requirements with repeaters you would just be able to direct people to read it whenever there's a problem.

I don't know, I just think simple is better. If you feel the need to add more inputfields maybe just have processwire throw a warning whenever anyone tries to include an image field in a repeater. When they save, bring up a new dialog to determine if there will be multiple images.

Link to comment
Share on other sites

Having said that, I have never had an issue with the image field, max file setting or displaying images EXCEPT when an image field is included in a repeater. I'm not saying it's never going to happen again but there isn't necessarily anything to fix either. I think simply including documentation to explain the need to handle it differently with repeaters would do the trick.

The image field is well documented http://processwire.com/api/fieldtypes/images/, and it's not different in a repeater.

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...