Using @click from template

Hello.

I am trying to add a @click="" within an template generated with template7.

The function is defined in the component methods as it comes by default:

<script>
	return {
		// Component Methods
		methods: {
			openExtras: function(c) {
				//do something
			}
		}
         }
</script>

If I put a button in the page with @click=“openExtras(‘a’)”, that works perfect.

But if the button is included in a template string then it does not work.

Which is the correct way to do this?

Best regards.

<button data-id="123">
openExtras: function(e) {
				$(e.target).data('id); // id
			}

Thanks for your reply.

That looks more professional that what I usually do.

But I am not sure I understand how to trigger the method.

I thought it needed something like this:

<button data-id="123" @click="openExtras()">Trigger Me</button>

the @click is the part that I can’t figure out.

As mentioned before, this works fine if it is a button within the page, but when it is generated from a template then it stops working.

Best regards.

Each vue file has its own methods, they are different, maybe this is the problem?

@click=“openExtras()” => @click=“openExtras”

Thanks again.

This is the full example of what I am doing.

The first button, the one ‘ready’ in the html works just fine. But the second one which is generated via the templating system does not work properly.

If I look into the browser inspector I notice that the first button has an ‘event’ associated with it, but not the second button.

<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-inner sliding">
        <div class="left">
          <a href="#" class="link back">
            <i class="icon icon-back"></i>
            <span class="if-not-md">Back</span>
          </a>
        </div>
        <div class="title">Component Page</div>
      </div>
    </div>
    <div class="page-content">
	    <button data-id="123" @click="openExtras" class="button button-fill">Trigger Me First</button>
    	<div id="test"></div>
 	</div>
  </div>
</template>
<script>
  return {
    // Component Methods
    methods: {
      openExtras: function(e) {
	id = $$(e.target).data('id'); // id
	alert(id);
	}
    },
    // Page Events
    on: {
      pageAfterIn: function(e, page) {
        console.log('pageAfterIn', page);
        t = '<button data-id="{{code}}" @click="openExtras" class="button button-fill">Trigger Me</button>';
        tC = Template7.compile(t);
	context = {code: '123'};
	html = tC(context);
	$$('#test').html(html);
      },
     }
  }
</script>

Best regards.

Thanks for the input.

I am not using vue.js if that is what you mean.

This method is defined in the same page, when called from a button already in the page it all works fine, the problem arises when the button is created from a tpl.

Так делать нельзя, чтобы @click сработал, нужно или изначально так писать в template или обновлять его с помощью $setState.

https://framework7.io/docs/router-component.html#dom-events-handling
If you add such element to DOM manually it won’t work!

1 Like

Well, that makes sense.

So, is there a way to do it?

I am reading in the routes documentation but I can’t seem to find any information about it.

I tried with onClick=“openExtras()” and other variations with no success.

I can just move the function to my plugin, but I would prefer to have it on the same page where it will be used.

Thanks again.

Yes, if you add such elements manually they won’t work. As @shastox mentioned, use $setState for this to update layout:

<div class="page-content">
  <button data-id="123" @click="openExtras" class="button button-fill">Trigger Me First</button>
  <div id="test">
    {{#if testButtonCode}}
      <button data-id="{{testButtonCode}}" @click="openExtras" class="button button-fill">Trigger Me</button>
    {{/if}}
  </div>
</div>
return {
  data: function () {
    return {
      testButtonCode: null,
    };
  },
  methods: {
    // ...
  },
  on: {
    pageAfterIn: function(e, page) {
      const self = this;
      self.$setState({
        testButtonCode: '123',
      });
    },
   }
  },
}
1 Like

Thank you very much.

Then, the button has to be in the existing html code in order for it to work?

Because I am creating the buttons ‘on the fly’ on pageInit, they come from a template.

It is a list of messages and each one has a hidden set of controls that may be opened on demand.

I tried with this code but the button does not appear when generated from the template.

I can just add the code to the plugin and it will work fine, but it would be nicer to have it on the same page.

Best regards.

In order to handle events correctly, button must be in original template. Templates is template. It doesn’t mean it is in the DOM all the time.

It is a list of messages and each one has a hidden set of controls that may be opened on demand.
Not a problem, then you should do a “loop” in your template

Here is a working example https://jsfiddle.net/0dkfmqLb/

Thank you very much for the example, it clarifies a lot of things.

My case is a bit different since I am creating the button after the page is created and I load the template from a js file, I have not been able to use the templates using the format:

<script id="template" type="text/template7">
    <p>Hello, my name is {{firstName}} {{lastName}}</p>
</script>

But this example really helps me understand a lot my options.

I will keep on playing with this example and I hope I can get it to work the way I want it. For now I am just calling the functions that are in the plugin and it works fine.

Javascript continues to be something out of my reach, maybe some day.

Best regards.