Jump to content
bernhard

How to intercept InputfieldButton click event via JS?

Recommended Posts

Hello everybody,

got stuck on a supposed simple thing: I want to intercept a click on a button that is rendered in the backend from InputfieldButton::render(); The button code is wrapped around an anchor tag because I set the HREF attribute:

<a class="InputfieldButtonLink" href="...">
  <button class="... rt-panel" name="button" value="..." type="button" data-href="...">
    <span class="ui-button-text"><i class="fa fa-plus"></i> Add something</span>
  </button>
</a>

I can't seem to find a way how I can prevent PW from opening this link 😞 The reason why I want to do this is that I need to modify the behaviour of the internal panel.

$(document).on('click', 'a.InputfieldButtonLink', function(event) {
  var $el = $(event.target);
  alert('clicked');
  return false;
});

It shows the alert but it also reloads the page, which is not what I want!

Outside of PW this works fine: https://jsfiddle.net/baumrock/npvzk6t7/1/

Any ideas? Thx!

Share this post


Link to post
Share on other sites

Have you tried event.preventDefault() instead of return false?

Share this post


Link to post
Share on other sites

It might be easier to add a button via this hook to try it yourself:

/site/ready.php

$this->addHookAfter("InputfieldText::render", function($event) {
  $field = $event->object;
  if($field->name != 'title') return;

  /** @var InputfieldButton $b */
  $b = $this->wire->modules('InputfieldButton');
  $b->href = 'https://www.processwire.com';
  $b->attr('data-href', $b->href);
  $b->value = 'pw.com';

  $script = '<script>'.$this->files->render(__DIR__ . '/button.js', [], [
    'allowedPaths' => [$this->config->paths->site],
  ]).'</script>';

  $event->return .= $b->render().$script;
});

/site/button.js

alert('loaded');
$(document).on('click', 'a', function() {
  alert('click');
  return false;
});

LoptlM1.png

Share this post


Link to post
Share on other sites

Haven't looked at this too closely, but you should be preventing the button click, not the <a> click, no?

Edited by kongondo

Share this post


Link to post
Share on other sites

OK. Still won't work. Maybe set the button href yourself using JavaScript after you've done your manipulations? Alternatively, use InputfieldSubmit. It works with that 

Just my 2p 🙂

Edited by kongondo
typo

Share this post


Link to post
Share on other sites

I still don't get what you want to achieve in the end, but try this

$(document).ready(function() {
	$(".InputfieldButtonLink").removeAttr("href");
	$(".InputfieldButtonLink").on("click", function (e) {
		e.preventDefault();
		console.log("so now what?");
		return false;
	});
});

For some reason, this will do a console.log() twice, because there's also a click handler defined in wire/modules/LanguageSupport/LanguageTabs.js

i.e. if you want to make sure that your custom action only fires once, you'd have to somehow de-activate that click handler too.

Share this post


Link to post
Share on other sites
1 hour ago, kongondo said:

Haven't looked at this too closely, but you should be preventing the button click, not the <a> click, no?

1 hour ago, kongondo said:

OK. Still won't work. Maybe set the button href yourself using JavaScript after you've done your manipulations? Alternatively, use InputfieldSubmit. It works with that 

54 minutes ago, dragan said:

$(document).ready(function() { $(".InputfieldButtonLink").removeAttr("href");

The href attribute is there for a reason:

54 minutes ago, dragan said:

I still don't get what you want to achieve in the end, but try this

I'm developing RockTabulator and a comman scenario is having a button to add new pages on top of the grid. I want this button to open the page edit screen of the newly created page in a pw-panel. And I want it to support middle-clicks to open the link in a new tab (that's why I need the href attribute and the data-href alone is not enough). So far, so good (and easy). But pw-panel does not offer a way to check which element triggered the opening of the panel. So I wanted to create a workaround that does the following:

When a link/button having class "rt-panel" is clicked, open a pw-panel and (and that's what differs from pw-panel) when this panel is closed, reload the corresponding grid.

pw-panels have the "pw-panel-closed" event, but I know nothing about the triggering element. So if I had 3 grids with one "add new ..." button each, I'd have to reload all 3 grids even if a page was only added to one grid (and only this grid should get reloaded). That's why I wanted to intercept the click on the link, add the triggering element to the panel element (as data-toggle or whatsoever) and whenever a pw-panel is closed check for the triggering element, get the grid and fire the grid.reload()

Hope that makes things clearer.

Maybe a request to change the implementation of pw-panels would make more sense. Just wanted to know if I'm missing something totally obvious 🙂 

PS: I could use a regular links as well, but I'm creating buttons in the backend (via PHP) and the syntax for InputfieldButton fits best:

$button->addClass('foo bar');
$button->icon('plus');
...

Am I missing a good way of creating simple links that look like buttons that way? Not sure about using InputfieldSubmit - I have to think about that...

Share this post


Link to post
Share on other sites

I doubt it is a desired solution but unbinding click event which is binded in setupButtonStates function like posted before would do the trick.

$(document).ready(function() {

    $(document).off('click', 'a > button')
        .on('click', 'a.InputfieldButtonLink', function(e) {
            e.preventDefault();
            var $el = $(event.target);

            console.log($el);

        });
});

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
1 hour ago, bernhard said:

But pw-panel does not offer a way to check which element triggered the opening of the panel.

Are you sure about this? I use pw-modal-closed in several of my modules and code similar to below works ok.

 

$(document).find('a.some_class, a.another_class').on('pw-modal-closed', function (evt, ui) {
    var $parent = $(this).parents('div.some_wrapper');
    $parent.addClass('class_to_hide');
    console.log('parent hidden');
    console.log($parent,'PARENT')
});

The correct div.some_wrapper has the class to hide it ('class_to_hide') applied to it. Are you using ProcessWire's JqueryMagnific?

Share this post


Link to post
Share on other sites
18 minutes ago, kongondo said:

Are you sure about this? I use pw-modal-closed in several of my modules and code similar to below works ok.

Yes, if I'm not missing anything: https://github.com/processwire/processwire/blob/master/wire/modules/Jquery/JqueryUI/panel.js#L387

Actually that's my own fault 😮 😅 https://github.com/processwire/processwire/pull/107

Share this post


Link to post
Share on other sites
5 hours ago, bernhard said:

But pw-panel does not offer a way to check which element triggered the opening of the panel.

Actually you can do this with a simple native JavaScript command inside the panel: 

window.parent.document.activeElement

This returns the element that triggered the opening of the panel.

Share this post


Link to post
Share on other sites

And how would i log that to the console when the panel is closed?

I'll file an issue on github for a little change that the events are triggered on the toggling element instead of $(document) - I think that would be the best solution. Thx for your help!

Please give the issue a thumb up: https://github.com/processwire/processwire-issues/issues/975

Then triggering the grid reload is as simple as this:

$(document).on('pw-panel-closed', '.rt-reload', function() {
  RockTabulator.getGrid(this).reload();
});

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...