Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get the component contents within Javascript when the sub-components are dynamically created? #3409

Open
ceremcem opened this issue May 18, 2022 · 2 comments

Comments

@ceremcem
Copy link

Description:

I've my reasons to re-invent the radio buttons with <button> elements (like displaying "loading" icon and confirming database writes before displaying a "selected" tick). This is the stripped down version of my radio-buttons component (playground):

Ractive.components['radio-buttons'] = Ractive.extend({
  template: `{{>content}}`,
  oninit: function(){
    setSelection = (selection) => {
      // do something else, like setting button colors
      this.fire('select', selection)
    }
    this.on({
      '*.init': (ctx, instance) => {
        instance.on('click', (ctx2) => {
          setSelection(instance.partials.content[0])
        })
      }
    })
	}
})

Ractive.components['radio-button'] = Ractive.extend({
  template: `<button on-click="click">{{yield}}</button>`
})

new Ractive({
  target: 'body',
  template: `
  <radio-buttons on-select="radioSelected">
  	<radio-button>hello</radio-button>
  	<radio-button>there</radio-button>
  </radio-buttons>  
  `,
  on: {
    radioSelected: function(ctx, selection){
      alert("selection is: " + selection)
    }
  }
})

However, when I try to create the radio-buttons with an {{#each}} loop, buttons' on-click handler doesn't work as intended: playground:

  <radio-buttons on-select="radioSelected">
    {{#each myArray}}
      <radio-button>{{.}}</radio-button>
    {{/each}}
  </radio-buttons>  

Expected output when we click on [a] button: selection is: a
Observed output is: selection is: undefined

How can I make it work when I create the sub-components dynamically? What becomes different when we encapsulate the sub-components into the {{#each}} loop?

Versions affected:

1.4

Platforms affected:

Browser

@ceremcem
Copy link
Author

Note that if we don't use instance.partials.content[0] and use instance.get('text'), it works as expected (playground):

  <radio-buttons on-select="radioSelected">
    {{#each myArray}}
      <radio-button text="{{.}}">{{.}}</radio-button>
    {{/each}}
  </radio-buttons>  

So the problem is that we can't get the "content" of a component when it's created by a loop.

@ceremcem ceremcem changed the title How to register sub-components' init functions when they are dynamically created? How to get the component contents within Javascript when the sub-components are dynamically created? May 18, 2022
@evs-chris
Copy link
Contributor

Since content is a partial, it can be any template. In the case of loop, the content is an interpolator that references .. As template content, there isn't really a value associated with it until it's rendered, so there are two things you could do:

  1. which you've already done in your second comment, is add some sort of value to the radio-button and pull that it from the event. This would also open things up to be more than just text.
  2. pull in the innerText from the element firing the event and use that as the value. This is only a solution if you only want your radios to show their exact value.

I suppose you could also combine those in something like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants