0
votes

In a non Ember world I could put this in my document ready:

$("input").on("invalid", function(event) {
  $(this).addClass('isDirty');
});

And then I would know that whenever a form is submitted, it would inturn fire the invalid event on invalid inputs and allow me to mark them as dirty for css purposes. I tried to do this in Ember in a component (in didInsertElement):

export default Ember.Component.extend({
  didInsertElement: function() {
    this.$('input, textarea').on('invalid', function() {
      console.log('worked!');
      Ember.$(this).addClass('isDirty');
    });
  },
  actions: {
    keyDownAction: function(value, event) {
      // Mark input/textarea as dirty
      Ember.run(() => {
        this.$('input, textarea').addClass('isDirty');
      })

      if (this.get('keyDown')) {
        this.sendAction('keyDown', value, event);
      }
    },
    focusInAction: function(value, event) {
      if (this.get('focusIn')) {
        this.sendAction('focusIn', value, event);
      }
    },
    focusOutAction: function(value, event) {
      // Mark input/textarea as dirty
      Ember.run(() => {
        this.$('input, textarea').addClass('isDirty');
      })

      if (this.get('focusOut')) {
        this.sendAction('focusOut', value, event);
      }
    }
  }
})

hbs:

{{input type=type value=value id=inputId class=inputClass name=name tabindex=tabindex autofocus=autofocus required=required list=list
  min=min max=max step=step
  key-down="keyDownAction" focus-in="focusInAction" focus-out="focusOutAction"}}
<span class="bar"></span>
<label class="{{if value 'text-present'}}">{{placeholder}}</label>

But my event isn't firing. Can I attach the ember input helper to the html5 invalid event?

3
Can you show how do you use this component?Daniel Kmak

3 Answers

1
votes

It works for me. You just need to make sure you wrap both component and submit button (for example, <button type='submit'>Submit</button>) in <form> element.

For example, template:

<form>
  {{my-component type='text' required='true' placeholder='My field'}}
  <button type='submit'>Submit</button>
</form>

Clicking submit button without <form> will do nothing. Clicking submit button when both elements are inside <form> will log worked! in console, add class isDirty to <input> and display native browser dialog to fill this field.

0
votes

It looks like you're doing things way too complicated. from what i understand is you're marking a textarea's validty depending on its value.

Lets say you have a text area

{{textarea value=textValue class="form-control"}}

And this input is supposed to have value for validity.

 textAreIsValid: function() {
   return !Ember.isEmpty(this.get('textValue'); // meaning the text can't be empty.
 }.property('textValue')

To show its validity you to user, i would wrap the text area like this

 <div class="control-group {{if textAreIsValid 'valid-class' 'has-error'}}">
        XX text area XX
 </div>

Also instead of keyPres and up you could be observing the value

areaValueChanged: function() {

}.observes('textValue'),
0
votes

It turns out that adding an Ember action to the submit button, such as:

<button type="submit" {{action 'testAction'}}>Go</button>

And returning false from the action, was not enough.

I did try adding preventDefault=false to the button, which worked in that the invalid event fired, but didnt work in that the whole page then submited rather than Ember handling things

The best solution therefore was to call this.$('form')[0].checkValidity(); just before returning false in the action, i.e.

if (formIsInvalid) {
  this.$('form')[0].checkValidity();
  return false;
}

Example twiddle now working: https://ember-twiddle.com/13af9d78ff5007626960