Jump to content

select field type who uses images for preview changes


Chris
 Share

Recommended Posts

short story:

think of a radio button mechanic in the background, but ui-wise you present images with captions as "buttons".

for instance i whant to be able to let admins change some visual themes of a single page, with different background and formating for each, i could place screenshots thumbs with a short caption. so the admins are able to se a preview image and know better what this setting does.

therefore it would be needed to define images for an input field, during the field creation. maybe someone likes the idea and is able to do it? 

Link to comment
Share on other sites

Or this:

class InputfieldSelectThumbnail extends InputfieldSelect {

	/**
	 * Return information about this module
	 *
	 */
	public static function getModuleInfo() {
		return array(
			'title' => __('InputfieldSelectThumbnail', __FILE__), // Module Title
			'summary' => __('Select a page from a list that displays a thumbnail of the first image found in the page', __FILE__), // Module Summary
			'version' => 101,
			'autoload' => true
			);
	}

	public function init()
	{
		$this->addHookBefore("InputfieldPage::getConfigInputfields", $this, "addOwnClassToSelect");
	}

	public function addOwnClassToSelect($event)
	{
		$obj = $event->object;
		$classes = $obj->get("inputfieldClasses");
		$classes[] = "InputfieldSelectThumbnail";
		$obj->set("inputfieldClasses", $classes);
		$this->log->message("addOwnClassToSelect: InputfieldSelectThumbnail");
	}

	protected function renderOptions($options, $allowBlank = true) {

		$out = '';
		reset($options); 
		$key = key($options); 
		$hasBlankOption = empty($key); 
		if($allowBlank && !$this->required && !$this->attr('multiple') && !$hasBlankOption) $out .= "<option value=''> </option>"; 

		foreach($options as $value => $label) {

			$selected = $this->isOptionSelected($value) ? " selected='selected'" : '';
			$attrs = $this->getOptionAttributesString($value) . " " . $this->getThumbnailAttributes($value);
			$out .= "\n\t<option$selected $attrs value='" . htmlspecialchars($value, ENT_QUOTES, "UTF-8") . "'>" . $this->entityEncode($label) . "</option>";
		}

		return $out; 
	}

	protected function getThumbnailAttributes($pgid)
	{
		$this->log->message("getThumbnailAttributes({$pgid})");
		$pg = $this->pages->get($pgid);
		if( $pg instanceof NullPage ) return "";

		$fields = $pg->template->fields;
		$imgfield = null;
		foreach($fields as $fld) {
			if( $fld->getInputfield($pg, $fld) instanceof InputfieldImage ) {
				$imgfield = $fld;
				break;
			}
		}
		if( $imgfield == null ) return "";
		
		$img = $pg->get($imgfield->name);
		if( $img == null ) return "";
		
		if( is_array($img) ) {
			if( count($img) == 0 ) return "";
			$img = $img[0];
		} else if( $img instanceof WireArray ) {
			if( $img->count() == 0 ) return "";
			$img = $img->first();
		}
		
		$thumb = $img->size($this->maxThumbWidth, $this->maxThumbHeight);
		$width = $this->maxThumbWidth + 4;
		$height = $this->maxThumbHeight + 4;
		$attrs = "style='padding-left: {$width}px; height: {$height}px; background-image: url({$thumb->url}); background-position: 2px 2px; background-repeat: no-repeat;'";
		return $attrs;
	}

	public function ___getConfigInputfields() {

		$inputfields = parent::___getConfigInputfields();

		$fieldset = $this->modules->get('InputfieldFieldset');
		$fieldset->label = $this->_('Thumbnail options'); 
		$fieldset->attr('name', 'thumboptions'); 
		$fieldset->icon = 'image';

		$field = $this->modules->get('InputfieldInteger');
		$field->label = $this->_('Max. width');
		$field->attr('name', 'maxThumbWidth');
		$field->attr('value', $this->maxThumbWidth ?: 80);
		$field->columnWidth = 50;
		$fieldset->add($field);

		$field = $this->modules->get('InputfieldInteger');
		$field->label = $this->_('Max. height');
		$field->attr('name', 'maxThumbHeight');
		$field->attr('value', $this->maxThumbHeight ?: 80);
		$field->columnWidth = 50;
		$fieldset->add($field);
		
		$inputfields->add($fieldset);
		return $inputfields;
	}
}

If picked as the input field type for a page field, it adds a thumbnail from the first image found in each selectable page to the dropdown (by resizing that image and setting it as the option's background image through css).

  • Like 3
Link to comment
Share on other sites

Here you go. Images need to go into /site/templates/ImageSelect/[path/] and must be named [optionValue].jpg. For usage with FieldtypePage you need to add the module in the settings of InputfieldPage. For the newer options fieldtype it's available right away.

Edit: My version might be more suited to the usecase of presenting layout options to the admins, rather than having a full blown thumbnail display.

Archiv.zip

  • Like 3
  • Thanks 2
Link to comment
Share on other sites

Here you go. Images need to go into /site/templates/ImageSelect/[path/] and must be named [optionValue].jpg. For usage with FieldtypePage you need to add the module in the settings of InputfieldPage. For the newer options fieldtype it's available right away.

Edit: My version might be more suited to the usecase of presenting layout options to the admins, rather than having a full blown thumbnail display.

LostKobrakai, this solutuin fitts my needs well, thank you verry much!

i have some little issues. Images are requested like this 

<img class="image_picker_image" src="/site/templates/ImageSelect/3.jpg">

which will not work for me for two reasons

1. my page is in a subfolder currently e.g. www.awesome.com/nice/site/.... which is not reflected by the url

2. when one liked to use several versions of the field, it could be a little akward, becouse all images are in one directory level, so i would end up keeping track of which id'S are already used by other fields. i suggest to put images in a subfolder with the name of the field, e.g. site/templates/ImageSelect/coolFieldName/1.jpg and so on.

Link to comment
Share on other sites

You can already define custom subfolders in the field settings (at least you should be) and here's the patch to have subfolders supported:

--- /InputfieldImageSelect/InputfieldImageSelect.module
+++ /InputfieldImageSelect/InputfieldImageSelect.module
@@ -13,7 +13,7 @@
 			if(empty($this->optionAttributes[$value])){
 				$this->optionAttributes[$value] = array();
 			}
-			$this->optionAttributes[$value]["data-img-src"] = "/site/templates/ImageSelect/$path$value.jpg";
+			$this->optionAttributes[$value]["data-img-src"] = $this->config->urls->templates . "ImageSelect/$path$value.jpg";
 		}
 
 		if($this->showLabels) $this->addClass("InputfieldImageSelectShowLabels");

Link to comment
Share on other sites

  • 3 years later...
On 1/9/2016 at 3:50 AM, LostKobrakai said:

Here you go. Images need to go into /site/templates/ImageSelect/[path/] and must be named [optionValue].jpg. For usage with FieldtypePage you need to add the module in the settings of InputfieldPage. For the newer options fieldtype it's available right away.

Edit: My version might be more suited to the usecase of presenting layout options to the admins, rather than having a full blown thumbnail display.

Thanks @LostKobrakai, this is great, exactly what I needed!

Just posting a note anyone else using in modern times, I had problems with this inside a matrix repeater with dynamic content. The version of image-picker from 2016 has this line. Straight jquery click doesn't handle event delegation, so for dynamic content you need to use on( "click", ...).  The latest version of image-picker fixes this and swapping out the files in the download linked by LostKobrakai above works fine.

https://github.com/rvera/image-picker/releases

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Similar Content

    • By spercy16
      These issues should be fairly easy for any intermediate to advanced ProcessWire developer to answer. I'm new to PHP and relatively new to ProcessWire and just need a bit of help. What I'm trying to do is bring in a couple of cards from my Projects page to display on my home page. I finally got the code right to bring in the cards but right now they're using my original images instead of my resized "variations". So firstly, I would like to know how to reference the variations of my images instead of using the original. Secondly, I need to grab only four of the cards from the Project page and not import in all ten. It should be just two small changes to my code to do these things (I would imagine). Here is the code I currently have for that section:
      <?php // https://processwire.com/api/arrays/ // check if the array of images has items if (count($pages->get("/projects/")->images)) : // get array of images from the field $images = $pages->get("/projects/")->images; $count = 0; // iterate over each one foreach ($images as $image) : $count++; $sectionText = $pages->get("/projects/")->get("paragraph_$count"); $img = $image; $buttonCode = $pages->get("/projects/")->get("url_$count"); ?> <span id="card<?php echo $count?>" class="card"> <img class="cardThumb" src="<?php echo $img->url; ?>" alt="<?php echo $image->description; ?> Thumbnail" /> <div class="cardBody"> <div class="cardText"> <h2><?php echo $img->description; ?></h2> <?php echo $sectionText; ?> </div> <div class="primaryBtn"> <a href="https://www.paypal.com/donate?hosted_button_id= <?php echo $buttonCode; ?> &source=url"> <button> <i class="fas fa-donate"></i> Donate </button> </a> </div> </div> </span> <?php endforeach; endif; ?> Thanks in advance for any help!
    • By Neue Rituale
      https://github.com/neuerituale/FieldtypeOembed
      or in the modules directory: https://processwire.com/modules/fieldtype-oembed/
    • By sambadave
      Hi there
      Short version of question
      Let's say I have a page in the admin that contains a field... Is it possible to output the content from that field on another page in the admin? Almost like a reference.
      Longer version of question (with example)
      A house builder with multiple (60+) developments. They want to be able to create notices/messages that can be added to one or many developments. Handy for things like regional covid lockdowns or temporary office closures due to bad weather.
      My approach for the admin editing options:
      Add each message to each development
      Pros: You edit the message on the development page in context
      Cons: Very time consuming and repetitive if the same message needs to be applied to 60+ developments
        Control all the messages from one admin page and say which development each message should be applied to
      Pros: Easier to add/remove messages to more than one development at a time. Control all messages from one place.
      Cons: Content is not added on development page, which is where typical admin users may expect to find it I went for option 2 due to flexibility, and created a page within the admin for global development notices. This contains a repeater with:
      Field for message to display Checkbox list of all developments. The user can select which ones to apply each message to It's working really well but the only thing is that if the user goes to a specific development in the admin, the relevant messages aren't displayed in context (as they aren't edited on that page and instead on the global development notices page)... which may cause confusion when a new staff member / content admin tries to edit the text but there is no field when they go to the development admin page where they expect to see it...
      Solution???
      I don't require the message(s) to also be editable on the development page, but I wondered if there was a nice way to show it/them somehow. I feel like I am missing something really simple as I'm sure ProcessWire will have a nice way of achieving this, or maybe there are field settings that allow this kind of thing to happen?
      Any ideas on approaches or similar experiences would be much appreciated, even if it is just a much simpler example with the content from one field being shown on another admin page to get the ball rolling.
      Thanks in advance for any advice :)
    • By picarica
      so hello there i have fiel field type i have lots of stuff there, and also an image i can easily get image from that field using
                                                        
      $options = array('quality' => 85, 'upscaling' => true, 'cropping' => 'north', 'sharpening' => 'medium'); $word = ".png"; // Test if string contains the word foreach($childgames->subor_hry as $file) { if(strpos($file, $word) !== false){ /* $imger = $file->size(473, 266, $options); */ echo $file; /* echo $file->url; */ } } so i get the fiel i tried invoking size on it like the commented out part and it doesnt work i get error Oh snizzle… Error:     Exception: Method Pagefile::size does not exist or is not callable in this context (in
      what am i doing wrong? can you guys help me by all logic this should work
    • By Max Esnée
      Hi,
      When I upload a large(ish) SVG (≈120ko in this case) into an image field, it tends to get stuck at 100% and block the whole website. If I force refresh the admin page, the svg has not been uploaded. The file is correctly copied into the assets folder though. Other svg tends to be uploaded fine albeit I've noticed that pages containing svg images in the admin are very slow to load generally. Other pages using the same template but with jpeg or png images are much faster to load.
      I get the following error in the JS console:

      I develop locally using MAMP on macOS and I'm using Firefox. I'm using the last ProcessWire version (3.0.165).
      I also tested in Chrome and got the same error.
×
×
  • Create New...