Rectangle 27 14

Focus the First Input Element

I just ran into this issue and I'm using react 15.0.1 15.0.2 and I'm using ES6 syntax and didn't quite get what I needed from the other answers since v.15 dropped weeks ago and some of the this.refs properties were deprecated and removed.

  • Focus the first input (field) element with an error (after submit)

I used autoFocus={true} on the first <input /> on the page so that when the component mounts, it will get focus.

This took longer and was more convoluted. I'm keeping out code that isn't relevant to the solution for brevity.

I need a global state to know if I should set the focus and to disable it when it was set, so I don't keep re-setting focus when the components re-render (I'll be using componentDidUpdate() to check for setting focus.)

This could be designed as you see fit for you application.

{
    form: {
        resetFocus: false,
    }
}

The component will need to have the resetfocus property set and a callBack to clear the property if it ends up setting focus on itself.

import { connect } from 'react-redux';
import MyField from '../presentation/MyField';
import ActionCreator from '../actions/action-creators';

function mapStateToProps(state) {
    return {
        resetFocus: state.form.resetFocus
    }
}

function mapDispatchToProps(dispatch) {
    return {
        clearResetFocus() {
            dispatch(ActionCreator.clearResetFocus());
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(MyField);
import React, { PropTypes } form 'react';

export default class MyField extends React.Component {
    // don't forget to .bind(this)
    constructor(props) {
        super(props);
        this._handleRef = this._handleRef.bind(this);
    }

    // This is not called on the initial render so
    // this._input will be set before this get called
    componentDidUpdate() {
        if(!this.props.resetFocus) {
            return false;
        }

        if(this.shouldfocus()) {
            this._input.focus();
            this.props.clearResetFocus();
        }
    }

    // When the component mounts, it will save a 
    // reference to itself as _input, which we'll
    // be able to call in subsequent componentDidUpdate()
    // calls if we need to set focus.
    _handleRef(c) {
        this._input = c;
    }

    // Whatever logic you need to determine if this
    // component should get focus
    shouldFocus() {
        // ...
    }

    // pass the _handleRef callback so we can access 
    // a reference of this element in other component methods
    render() {
        return (
            <input ref={this._handleRef} type="text" />
        );
    }
}

Myfield.propTypes = {
    clearResetFocus: PropTypes.func,
    resetFocus: PropTypes.bool
}

The general idea is that each form field that could have an error and be focused needs to check itself and if it needs to set focus on itself.

There's business logic that needs to happen to determine if the given field is the right field to set focus to. This isn't shown because it will depend on the individual application.

When a form is submitted, that event needs to set the global focus flag resetFocus to true. Then as each component updates itself, it will see that it should check to see if it gets the focus and if it does, dispatch the event to reset focus so other elements don't have to keep checking.

edit As a side note, I had my business logic in a "utilities" file and I just exported the method and called it within each shouldfocus() method.

reactjs - React set focus on input after render - Stack Overflow

reactjs
Rectangle 27 11

The Google Chrome UI for auto-complete requests varies, depending on whether autocomplete is set to off on input elements as well as their form. Specifically, when a form has autocomplete set to off and its input element's autocomplete field is not set, then if the user asks for autofill suggestions for the input element, Chrome might display a message saying "autocomplete has been disabled for this form." On the other hand, if both the form and the input element have autocomplete set to off, the browser will not display that message. For this reason, you should set autocomplete to off for each input that has custom auto-completion.

form
input

The question is related to AngularJS in case there is a solution to capturing the auto-fill text in Angularjs. I was not aware of having to set autocomplete off on the input's though.

I tried setting autocomplete="off" on both the form and the input elements and the auto complete is still autocompleting and the value still does not get set to my angular model.

autocomplete="off"

javascript - Angularjs Chrome autocomplete dilemma - Stack Overflow

javascript angularjs google-chrome autocomplete
Rectangle 27 2

pattern will not prevent characters from being typed into the input element, it will only set off validation.

To prevent non numeric characters from being entered you can use a directive that intercepts the value being typed.

angular.module('components', []).directive('numbersOnly', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            ngModelCtrl.$parsers.push(function (inputValue) {
                var transformedInput = inputValue.replace(/\.\.+/g, '.');
                ngModelCtrl.$setViewValue(transformedInput);
                ngModelCtrl.$render();

                return inputValue;
            });
        }
    }
});
transformedInput = inputValue.replace(/\.\.+/g, '.');

javascript - Unable to set only numbers input - Stack Overflow

javascript angularjs html5
Rectangle 27 3

You can set the "required" in the input elements and style / code how you want to handle with $valid of a form. Check out http://dailyjs.com/2013/06/06/angularjs-7/

Mouli, thanks for your answer, I know it's weird, but in the original state, the user will see three inputs, and will be required to fill at least one, but not all of them. So that's why I think that adding required won't fit for me. I need some equivalent of $("input").val() == "" applied to angularjs. Thanks!!

javascript - AngularJS - Form Custom Validation - Check if at least on...

javascript html validation angularjs
Rectangle 27 3

You can set the "required" in the input elements and style / code how you want to handle with $valid of a form. Check out http://dailyjs.com/2013/06/06/angularjs-7/

Mouli, thanks for your answer, I know it's weird, but in the original state, the user will see three inputs, and will be required to fill at least one, but not all of them. So that's why I think that adding required won't fit for me. I need some equivalent of $("input").val() == "" applied to angularjs. Thanks!!

javascript - AngularJS - Form Custom Validation - Check if at least on...

javascript html validation angularjs
Rectangle 27 1

You need to create a custom ControlValueAccessor for the component (ComboDatePickerComponent) that contains the view (HTML) from your question. In writeValue() or onTouched() you can set and read the values of the three individual input elements.

angular2 forms - Angular 2 Custom Control link to ngControl with Contr...

angular angular2-forms
Rectangle 27 116

Although this doesn't answer the question (requiring a common script), I though it might be useful for others to know that HTML5 introduces the 'autofocus' attribute:

<form>
  <input type="text" name="username" autofocus>
  <input type="password" name="password">
  <input type="submit" value="Login">
</form>

autofocus is the attributename . What about its value ?Somethig like autofocus=true not needed ? What does it mean not to set any value ?

In HTML5, some attributes do not need to have a value, 'checked' is another attribute where this is the case. I believe that when the value is left off, it is implied that the it is the same as the name (e.g. autofocus="autofocus" and checked="checked").

My Spring app breaks when I try to use autofocus with no value on spring:form. autofocus="autofocus" works fine, though. Thanks, @Jacob.

@Geek The autofocus attribute, as many other, is a boolean attribute type. That's why it is used only in a declarative way, not by assigning a value to it. See more details in w3c spec: w3.org/TR/html5/infrastructure.html#boolean-attribute

javascript - How to set the focus to the first input element in an HTM...

javascript html forms focus
Rectangle 27 33

You can get the input element and then set its readOnly property to true as follows:

document.getElementById('InputFieldID').readOnly = true;
<script type="text/javascript">
  function onLoadBody() {
    document.getElementById('control_EMAIL').readOnly = true;
  } 
</script>
onLoadBody()
<body onload="onLoadBody">

I appreciate the response, but its doesnt seem to be working for me - do you mind checking: bit.ly/1aI1Zxn ???

@chris

Awesome - thanks Vijay, i just had to make the body reference have <body onload="onLoadBody();"> - just in case anyone sees this in the future.

How to make a input field readonly with JavaScript? - Stack Overflow

javascript input readonly
Rectangle 27 88

You can also try jQuery based method:

$(document).ready(function() {
    $('form:first *:input[type!=hidden]:first').focus();
});

It Works! I'm starting to integrate jQuery in my web application. So, I think I will stick with this approach! Many thanks, Marko!

What happens if the first form on the page is hidden in this case? Or if the first element on the form is hidden via CSS? Surely this would fail. I am being pedantic of course but that's how I roll.

In my case (using ASP.NET) I have just ONE form which is never hidden. So this works for me.

@Jame Hughes, you can write it as a function and call it when u need it, and you can make exceptions. For me this solution really helped.

javascript - How to set the focus to the first input element in an HTM...

javascript html forms focus
Rectangle 27 31

You can get the input element and then set its readOnly property to true as follows:

document.getElementById('InputFieldID').readOnly = true;
<script type="text/javascript">
  function onLoadBody() {
    document.getElementById('control_EMAIL').readOnly = true;
  } 
</script>
onLoadBody()
<body onload="onLoadBody">

I appreciate the response, but its doesnt seem to be working for me - do you mind checking: bit.ly/1aI1Zxn ???

@chris

Awesome - thanks Vijay, i just had to make the body reference have <body onload="onLoadBody();"> - just in case anyone sees this in the future.

How to make a input field readonly with JavaScript? - Stack Overflow

javascript input readonly
Rectangle 27 525

Define a directive and have it $watch a property/trigger so it knows when to focus the element:

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh's comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

Create a directive essentially like the one above. Watch some scope property, and when it becomes true (set it in your ng-click handler), execute element[0].focus(). Depending on your use case, you may or may not need a $timeout for this one:

Update 7/2013: I've seen a few people use my original isolate scope directives and then have problems with embedded input fields (i.e., an input field in the modal). A directive with no new scope (or possibly a new child scope) should alleviate some of the pain. So above I updated the answer to not use isolate scopes. Below is the original answer:

Name: <input type="text" focus-me="{{shouldBeOpen}}">
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

Since we need to reset the trigger/focusInput property in the directive, '=' is used for two-way databinding. In the first directive, '@' was sufficient. Also note that when using '@' we compare the trigger value to "true" since @ always results in a string.

@MarkRajcok just curious about this: this version works but if I set an ng-model on the input field, the model value is lost when I use this directive w/the isolate scope is used. The problem doesn't happen if I try Josh's version w/out the isolate scope. Still a newbie, and I'd like to understand the difference. Here is a Plunker that shows it.

I found that #1 works very well with AngularJS 1.0.6. However, when running under a debugger, I noticed that every time I dismissed and reopened my modal, I was seeing one more additional call to the function that sets focus than the time before. I modified that function slightly to unbind the watch when value != "true", and that appeared to address my issue.

So... on a stateful page I had the same thing going because $watch is $watch and angular developers love $watch... well I hit a problem, Mr @MarkRajcok, a problem I solved with the (basic) solution I proposed below.

hmm for me the code works, as in i can see it executing properly and element[0] is the right control. however .focus() does not trigger a focus. possibly bootstrap or something else is interfering with this?

@blesh, thanks. I hadn't noticed this issue since I only tested the modal case. I updated the first plunker and the directive code snippet with a more general solution: the directive now catches the blur event and sets the boolean to false using $parse.

angularjs - How to set focus on input field? - Stack Overflow

angularjs angularjs-directive
Rectangle 27 523

Define a directive and have it $watch a property/trigger so it knows when to focus the element:

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh's comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

Create a directive essentially like the one above. Watch some scope property, and when it becomes true (set it in your ng-click handler), execute element[0].focus(). Depending on your use case, you may or may not need a $timeout for this one:

Update 7/2013: I've seen a few people use my original isolate scope directives and then have problems with embedded input fields (i.e., an input field in the modal). A directive with no new scope (or possibly a new child scope) should alleviate some of the pain. So above I updated the answer to not use isolate scopes. Below is the original answer:

Name: <input type="text" focus-me="{{shouldBeOpen}}">
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

Since we need to reset the trigger/focusInput property in the directive, '=' is used for two-way databinding. In the first directive, '@' was sufficient. Also note that when using '@' we compare the trigger value to "true" since @ always results in a string.

@MarkRajcok just curious about this: this version works but if I set an ng-model on the input field, the model value is lost when I use this directive w/the isolate scope is used. The problem doesn't happen if I try Josh's version w/out the isolate scope. Still a newbie, and I'd like to understand the difference. Here is a Plunker that shows it.

I found that #1 works very well with AngularJS 1.0.6. However, when running under a debugger, I noticed that every time I dismissed and reopened my modal, I was seeing one more additional call to the function that sets focus than the time before. I modified that function slightly to unbind the watch when value != "true", and that appeared to address my issue.

hmm for me the code works, as in i can see it executing properly and element[0] is the right control. however .focus() does not trigger a focus. possibly bootstrap or something else is interfering with this?

angularjs - How to set focus on input field? - Stack Overflow

angularjs angularjs-directive
Rectangle 27 519

Define a directive and have it $watch a property/trigger so it knows when to focus the element:

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh's comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

Create a directive essentially like the one above. Watch some scope property, and when it becomes true (set it in your ng-click handler), execute element[0].focus(). Depending on your use case, you may or may not need a $timeout for this one:

Update 7/2013: I've seen a few people use my original isolate scope directives and then have problems with embedded input fields (i.e., an input field in the modal). A directive with no new scope (or possibly a new child scope) should alleviate some of the pain. So above I updated the answer to not use isolate scopes. Below is the original answer:

Name: <input type="text" focus-me="{{shouldBeOpen}}">
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

Since we need to reset the trigger/focusInput property in the directive, '=' is used for two-way databinding. In the first directive, '@' was sufficient. Also note that when using '@' we compare the trigger value to "true" since @ always results in a string.

@MarkRajcok just curious about this: this version works but if I set an ng-model on the input field, the model value is lost when I use this directive w/the isolate scope is used. The problem doesn't happen if I try Josh's version w/out the isolate scope. Still a newbie, and I'd like to understand the difference. Here is a Plunker that shows it.

I found that #1 works very well with AngularJS 1.0.6. However, when running under a debugger, I noticed that every time I dismissed and reopened my modal, I was seeing one more additional call to the function that sets focus than the time before. I modified that function slightly to unbind the watch when value != "true", and that appeared to address my issue.

hmm for me the code works, as in i can see it executing properly and element[0] is the right control. however .focus() does not trigger a focus. possibly bootstrap or something else is interfering with this?

angularjs - How to set focus on input field? - Stack Overflow

angularjs angularjs-directive
Rectangle 27 21

document.forms[0].elements[0].focus();

This can be refined using a loop to eg. not focus certain types of field, disabled fields and so on. Better may be to add a class="autofocus" to the field you actually do want focused, and loop over forms[i].elements[j] looking for that className.

Anyhow: it's not normally a good idea to do this on every page. When you focus an input the user loses the ability to eg. scroll the page from the keyboard. If unexpected, this can be annoying, so only auto-focus when you're pretty sure that using the form field is going to be what the user wants to do. ie. if you're Google.

javascript - How to set the focus to the first input element in an HTM...

javascript html forms focus
Rectangle 27 83

Before HTML5, we have an easy but workable way: Firstly set an maxlength attribute in the textarea element:

<textarea maxlength='250' name=''></textarea>
$(function() {  
    $("textarea[maxlength]").bind('input propertychange', function() {  
        var maxLength = $(this).attr('maxlength');  
        if ($(this).val().length > maxLength) {  
            $(this).val($(this).val().substring(0, maxLength));  
        }  
    })  
});

Make sure the bind both "input" and "propertychange" events to make it work on various browsers such as Firefox/Safari and IE.

Resorting to use of HTML5 is not an answer. We expect cross-browser support. That makes this by far the most correct answer.

Note that this solution is not "pure" javascript, it requires use of JQuery. (In case you try it without JQuery, and wonder why it does not work.)

Unfortunately this doesn't quite work as expected for any newlines in the textarea. I'm guessing JavaScript is treating a newline as one character rather than two so when I try to insert a "max length" string into the database I get an error.

I might be wrong, but if I'm typing a short story, and am inserting text at the start of the text box, the end of the text will be getting chopped off as I type. Possibly without my knowledge.

@3Dom: "Resorting to use of HTML5 is not an answer." - Using the HTML5 doctype is supported cross-browser (they tested various doctypes to see what worked in older browsers), and using an attribute introduced in HTML5 with a JavaScript fallback for browsers that don't support it is cross-browser compatible too.

input - Set maxlength in Html Textarea - Stack Overflow

html input textarea
Rectangle 27 83

Before HTML5, we have an easy but workable way: Firstly set an maxlength attribute in the textarea element:

<textarea maxlength='250' name=''></textarea>
$(function() {  
    $("textarea[maxlength]").bind('input propertychange', function() {  
        var maxLength = $(this).attr('maxlength');  
        if ($(this).val().length > maxLength) {  
            $(this).val($(this).val().substring(0, maxLength));  
        }  
    })  
});

Make sure the bind both "input" and "propertychange" events to make it work on various browsers such as Firefox/Safari and IE.

Resorting to use of HTML5 is not an answer. We expect cross-browser support. That makes this by far the most correct answer.

Note that this solution is not "pure" javascript, it requires use of JQuery. (In case you try it without JQuery, and wonder why it does not work.)

Unfortunately this doesn't quite work as expected for any newlines in the textarea. I'm guessing JavaScript is treating a newline as one character rather than two so when I try to insert a "max length" string into the database I get an error.

I might be wrong, but if I'm typing a short story, and am inserting text at the start of the text box, the end of the text will be getting chopped off as I type. Possibly without my knowledge.

@3Dom: "Resorting to use of HTML5 is not an answer." - Using the HTML5 doctype is supported cross-browser (they tested various doctypes to see what worked in older browsers), and using an attribute introduced in HTML5 with a JavaScript fallback for browsers that don't support it is cross-browser compatible too.

input - Set maxlength in Html Textarea - Stack Overflow

html input textarea
Rectangle 27 16

The most comprehensive jQuery expression I found working is (through the help of over here)

$(document).ready(function() {
    $('input:visible:enabled:first').focus();
});

I was using this, noticed it runs extremely slowly on IE when have a large number >1000 of checkboxes in a table. Not sure what to do about it, might have to just give up on focusing the first input field.

javascript - How to set the focus to the first input element in an HTM...

javascript html forms focus
Rectangle 27 120

//input is the input element

input.focus(); //sets focus to element
var val = this.input.value; //store the value of the element
this.input.value = ''; //clear the value of the element
this.input.value = val; //set that value back.

For the cursor to be move to the end, the input has to have focus first, then when the value is changed it will goto the end. If you set .value to the same, it won't change in chrome.

Setting the focus before setting the value is the key to get it work in Chrome.

Why put this. in front of input on lines 2, 3, and 4? We already know that input is the input element. Using this seems redundant. Good solution otherwise!

@Tareq They are not the same. This trick is much better than the accepted answer.

$input.focus().val($input.val());

Use JavaScript to place cursor at end of text in text input element - ...

javascript
Rectangle 27 7

If you're using the Prototype JavaScript framework then you can use the focusFirstElement method:

Form.focusFirstElement(document.forms[0]);

javascript - How to set the focus to the first input element in an HTM...

javascript html forms focus