Jump to content

Hook: replace method?


kongondo
 Share

Recommended Posts

I'm not double posting :-). I have been having a conversation with @netcarver about this but thought to expand the discussion. 

In relation to the module I am working on MenuBuilder and this comment, I need to modify the output of AsmSelect. Its ___render() method is hookable but the method does not have arguments so wondering whether in such a case, the best way is to use a Hook that replaces the whole method? Specifically, what I need to replace in the method is only one line - the one that loads the jquery.asmselect.js

$this->config->scripts->add($this->config->urls->$class . "asmselect/jquery.asmselect.js?v=$ver");

AsmSelect shows selected pages in a <span>Item Label</span>. So, instead of this:

post-894-0-14096100-1424853566_thumb.png

I want to have something like this (still rough around the edges!):

post-894-0-01497300-1424853567_thumb.png

In order to do that, I have needed to modify the jquery.asmselect.js plus modify the CSS a bit. 

Alternatively, I tried to remove the file using config->scripts->remove() and adding my modified one but that didn't work. The original jsquery.asmselect.js script was still loaded. I tried this in my Process modules execute() method and executeEdit() and just in case init().

I appreciate any thoughts on this, including alternatives, e.g. just manipulating the dynamically created DOM (the <span>Item Label</span> is dynamically created by jquery.asmselect.js) using jQuery. Also, I think extending the module in this case is an overkill - just to replace one line!

Thanks!

Edit:

Clarification based on comment below. I am not after an inputfield per se. The data in the extra inputs I want will be stored elsewhere

Edited by kongondo
  • Like 1
Link to comment
Share on other sites

I would suggest you take a look at ProcessTemplate::buildEditFormFields. It does use the standart asmSelect, but with additional information rendered. Then you could pack the "config" stuff in a modal window. If you want to stay with the inputfield inside the asmSelect I would suggest creating a seperate inputfield for it, so you can style it to fit your needs. Currently one just sees, that it's kinda hacked together from asmSelect, but it doesn't have to be such a small bar to be dragable.

Link to comment
Share on other sites

Thanks for the info.

The above is just a prototype - no styling has been applied yet :-). To clarify, I don't need an inputfield - just some temporary inputs in a table to send additional data for each selected page in the AsmSelect. The data will be saved elsewhere..In addition, I will not need the items to be draggable nor sortable - so I will remove those capabilities. 

Edited by kongondo
Link to comment
Share on other sites

Saving (already existing) pages is as easy as updating a hidden multiselect field with "selected" properties. If you're not really using the features of asmSelect, why use it then? Have a look at this http://jsfiddle.net/b7ty2Lud/1/. It's using simply InputfieldSelectMultiple. Then you can do everything else like you'd like it to work/look. You could also have a look in InputfieldPageListSelect about generating the markup for your rows. It's not like just updating a single line, but on the other hand your free in your markup.

Link to comment
Share on other sites

OK, let me try again....

The AsmSelect or any other select field is for choosing the page that the user wants to add to a menu. That menu will be generated in the frontend (a navigational menu). With such HTML menus, usually, one adds CSS properties to the links - CSS ID, CSS Class as well as some other link attributes. So, I need the inputs to send data about these CSS and link attributes (nothing more than that). That info, will be stored elsewhere - hence, the inputs are really shells to temporarily hold data for POST. The pagefield I need for selecting the pages + their ID (from which I can do other stuff - e.g. know their URL, etc...). In essence, if you have had a look at the MenuBuilder thread, I want to mimick what I can already do with the custom menu items (see the table with inputs) - just to improve user experience. For the custom menu items, the user enters each link's title, link and (optionally) CSS details. The difference is that for PW pages, I don't need to enter a link (PW will generate that automatically for me on render) and the title I already have. 

Given the above. I have several choices. I can use my own js to mimick what AsmSelect does or slightly modify what AsmSelect does to suit my needs. I prefer using AsmSelect (or Autocomplete) just because they are convenient in many cases (as opposed to other page field selects). Currently, rather than reinvent the wheel, I am leaning toward using AsmSelect, just hooking into it and modifying it a bit. This is mainly because I am lazy :-) and js is not my strong point...

Thanks for your thoughts!

Link to comment
Share on other sites

Sorted! (seems hackish but I don't really mind unless shown a better way ^_^). 

Documenting this in case there is a better way....

Add a Hook after AsmSelect's output:

wire('page')->addHookAfter("InputfieldAsmSelect::render", $this, "customAsm");

Slightly modify AsmSelect output in customAsm()

$value = $event->return; 
$value = str_replace("\"multiple\"", "\"multipleMB\"", $value);//see why this below..
$event->return = $value;

The reason for the str_replace is that in InputfieldAsmSelect.js you have this code:

$(document).ready(function() {
	$(".InputfieldAsmSelect select[multiple=multiple]").each(function() {//note this
		var $t = $(this); 

		if(typeof config === 'undefined') {
			var options = { sortable: true };
		} else {
			var options = config[$t.attr('id')]; 
		}
		$t.asmSelect(options);//note this
	}); 
}); 

We need to change the [multiple=multiple] to point to our custom selector multiple=multipleMB. We don't hack this but in our own .js file we have:

$(".InputfieldAsmSelect select[multiple=multipleMB]").each(function() {

/* blah blah */

$t.asmSelectMB(options);//this will be the name of our customised asmSelect function

Final thing is just to include our customised jquery.asmselect.js, i.e. jquery.asmselect-mb.js. (config->scripts->add()) with the modified function

$.fn.asmSelectMB = function(customOptions) {
/* blah blah */

This way, I can still set my properties values (e.g. $menuAddPageItems->setAsmSelectOption('sortable', false); ) and Bob's your uncle.

Downsides? AsmSelects native JS still gets loaded although I have no use for it.

OK, back to coding...

post-894-0-55041700-1424940238_thumb.png

  • 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
 Share

  • Recently Browsing   0 members

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