Jump to content

How to intercept InputfieldButton click event via JS?


bernhard
 Share

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!

Link to comment
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

Link to comment
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.

Link to comment
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...

Link to comment
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
Link to comment
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?

Link to comment
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

Link to comment
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.

Link to comment
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();
});

 

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