Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember CLI: custom input helper

I'm trying to extend Ember's TextField with UrlField so that if someone forgets to include http://, it does it for them.

Here's my View:

views/input-url.js

import Ember from 'ember';

export default Ember.TextField.extend({

    type: 'url',

    didInsertElement: function() {
        this._super.apply(this, arguments);
        this.formatValue();
    },

    onValueChange: function() {
        this.formatValue();
    }.observes('value'),

    formatValue: function() {
        var pattern = /^https{0,1}:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+/g;
        if (pattern.test(this.get('value')))
          return;

        if (!pattern.test('http://' + this.get('value')))
          return;

        this.set('value', 'http://' + this.get('value'));
    }

});

If I use it in my template like this, it works fine:

{{view "input-url" value=url}}

I prefer to use custom view helpers, so I created this (following the guide at the bottom of this page: http://guides.emberjs.com/v1.11.0/templates/writing-helpers/):

helpers/input-url.js

import Ember from 'ember';
import InputUrl from '../views/input-url';

export default Ember.Handlebars.makeBoundHelper(InputUrl);

Now trying to render this in my template doesn't work:

{{input-url value=url}}

I've also tried different permutations of this, including what's shown in the guide Ember.Handlebars.makeBoundHelper('input-url', InputUrl); (which throws an error), but I can't seem to get my input field to show up. What am I doing wrong?

like image 581
Johnny Oshika Avatar asked Sep 28 '22 08:09

Johnny Oshika


People also ask

How to create helper in Ember js?

To create a class-based helper, rather than exporting a simple function, you should export a subclass of Ember. Helper . Helper classes must contain a compute method that behaves the same as the function passed to Ember. Helper.

How to use helper in Ember js?

To implement the helper, we write a JavaScript function that takes its arguments as an array. This is because helpers can also receive named arguments, which we'll discuss next. import { helper } from '@ember/component/helper'; function substring(args) { let [string, start, end] = args; return string.

What is Handlebars template in Ember?

Ember uses the Handlebars templating library to power your app's user interface. Handlebars templates contain static HTML and dynamic content inside Handlebars expressions, which are invoked with double curly braces: {{}} . Dynamic content inside a Handlebars expression is rendered with data-binding.

What is a component in Ember?

Ember components are used to turn markup text and styles into reusable content. Components consist of two parts: a JavaScript component file that defines behavior, and its accompanying Handlebars template that defines the markup for the component's UI. Components must have at least one dash in their name.


2 Answers

Not sure what you are doing wrong with your view helper, but there is a much simpler solution: take advantage of the fact that Ember.Textfield is a component. http://emberjs.com/api/classes/Ember.TextField.html

Simply move views/input-url.js to components/input-url.js and get rid of your view helper.

Then {{input-url value=url}} should work automatically.

like image 53
Gaurav Avatar answered Oct 30 '22 23:10

Gaurav


If you want do to this using a helper, you cannot extend Ember.TextField because extends Ember.Component and is not a Handlebars helper.

The way to do this using a helper would actually be simpler. Since you are using Ember-CLI, you can create a helper called "input-url" with the command ember g helper input-url and the only code you would need is the code within your formatValue() function:

helpers/input-url.js

// define patter globally so it's not recreated each time the function is called    
var pattern = /^https{0,1}:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+/g;

export function inputUrl(value) {
    if (pattern.test(value)) {
        return value;
    }

    if (!pattern.test('http://' + value)) {
        return value;
    }

    return 'http://' + value;
};

export default Ember.Handlebars.makeBoundHelper(inputUrl);

And you can use it like:

{{input-url PASS_YOUR_URL_HERE}}

Where the value you pass will be the value of the value variable within the helper.

You could also create a component, as @Gaurav suggested, using the exact code you have above, just in components/input-url.js instead and delete the helper cause it is not necessary anymore. You also have to edit the corresponding template of the component if you want it to display the value with a single handlebars expression:

templates/components/input-url.hbs

{{value}}

The usage with a component would be:

{{input-url value=PASS_YOUR_URL_HERE}}
like image 42
nem035 Avatar answered Oct 30 '22 22:10

nem035