Using @click from template


#1

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.


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

#3

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.


#4

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


#5

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


#6

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.


#7

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.


#8

Так делать нельзя, чтобы @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!


#9

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.


#10

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',
      });
    },
   }
  },
}

#11

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.


#12

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/


#13

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.