autofocus attribute not working in Firefox on display state change - javascript

I'm trying to add auto focus to a form. I have it working in Chrome but cannot get it working in Firefox with the below code. I think the reason could potentially be that it needs to be just autofocus rather than autofocus="autofocus". Would I be correct in assuming this? If so is there some way I can add it? I'm using a framework called SilverStripe and don't have direct access to editing the input field as it's done dynamically so would need to do it via JavaScript most likely.
<input type="text" name="Search" class="form-control search-form" id="TemplateSearchForm_SearchForm_Search" placeholder="Search..." autofocus="autofocus">
Note I am initially hiding the input box and displaying on the click of an icon by adding a class:
jQuery('.search').click(function () {
if(jQuery('.search-btn').hasClass('fa-search')){
jQuery('.search-open').fadeIn(500);
} else {
jQuery('.search-open').fadeOut(500);
}
});

I couldn't find anything in the HTML specification to validate the autofocus behavior exhibited by Chrome. Here's an excerpt from the spec on this behavior.
From 4.10.19.7 Autofocusing a form control: the autofocus attribute:
When an element with the autofocus attribute specified is inserted into a document, user agents should run the following steps:
[...]
Note: This handles the automatic focusing during document load.
It doesn't mention anything about applying this behavior when the display state changes (as Chrome is apparently doing), only when the element is first inserted into the DOM. This actually appears to a be a bug in Chrome as Firefox is following the HTML spec.
Instead of using the autofocus attribute, you will have to trigger the focus through JavaScript.

You could use JavaScript to automatically focus into any elements with autofocus='yes'
$('[autofocus="yes"], [autofocus="autofocus"], [autofocus="true"]').focus();
This should, theoretically target any elements that have autofocus set to either true, yes, or autofocus and focus on them.

Related

Vue crashes when binding input with large strings

I've got this input that is bound with a property:
// in the template
<input type="text" v-model="someProp">
// in the script
export default {
data() { return {
someProp: ''
}
}
The issue is that this input will be bound with a very long string (21k characters long). Upon copy/pasting the string into the input, the tab temporarily crashes in the following fashion:
Can't scroll
Text cursor stops blinking
Window freezes
Components that shouldn't be displayed appear
There seems to be some overprocessing when binding with large inputs. What can I change in my code to prevent the lag?
And, if possible: is the overprocessing because of Vue or the browser?
Apparently, some browsers optimize large text input only for textarea elements, but not for input. Doing the following change in my template prevented the tab from lagging:
// change this
<input type="text" v-model="someProp">
// to this
<textarea type="text" v-model="someProp"></textarea>
(with some additional styling, of course).
The issue seems to come from the browser and not from Vue, but that's all I can tell - additional input would be greatly appreciated!

Fill an input field that is not of type text and that triggers events in CasperJS

I have to do automated tests on a website and I want to use CasperJS to learn. For proprietary reasons I can not give too much code.
Here is the example of the input that I am trying to fill:
<input data-bind="value: firstname, valueUpdate: ['blur'], css: {valid:(firstname.isValid() )} " title="" class="valid" aria-required="true" id="firstname" name="firstname">
As you can see, this input is not of type text and has no value attribute. Therefore, I can not use the casper.fill() method. Furthermore, if I enter the web page scope using evaluate() and change the input value using document.querySelector, the change will not be permanent as of the events attached to the text change on the input will not be triggered.
Here is my code:
this.waitForSelector('#memberTitle', function then(){
var testname = 'thisIsNotPermanent';
this.evaluate(function(testname){
document.querySelector('#firstname').value = testname;
}, testname);
});
If I capture the screen right after, I will see my text written in the input box. However, if I wait 500ms and take another capture, the text is gone as, I suppose, the events are triggered or just cleaned because it actually failed to trigger correctly.
The events attached to the input are of Blur, Change and Keypress.
Using CasperJS, how could I go to the lowest level possible to mimic a user using his keyboard and fully use the website's functionalities already in place?
The whole point of those tests are to work with what is in place. The idea is to not have to manually go through the JavaScript of the web site.
That's exactly what the casper.sendKeys(selector, keys) function is for which will send native keypresses and (hopefully) trigger the events on that text element:
this.waitForSelector('#memberTitle', function then(){
var testname = 'thisIsNotPermanent';
this.sendKeys('#firstname', testname);
}).wait(20, function(){
this.capture('screenshot.png');
});
<input> elements without a type attribute default to Text type.
This answer is here to complete the question from another angle. As Artjom B. mentionned, the correct way to fill an input and to trigger its events is by using the sendKeys() function. However, if you ever have a case, like mine, where the events will not trigger or will take a certain amount of time, know that you can trigger those manually.
If you use the firefox inspector tool, you will see that your input or tag will have an event attached to it marked as ev. If you select it, you will have a breakdown of all the events, in order, that are triggered.
You can see that the jQuery click() event will be called. In casperjs, from the evaluate scope you can now do this :
this.evaluate(function(){
$(".discard-answer").click();
})
From there, you can chain jQuery events, like in my case where I had to .blur().change().click();
It is important to know if the event is jQuery or not.
Hope this helps.

How to get content length of invalid input?

I have an element:
<input type="number">
When I type in $500, it fails validation, so
console.log("el.value");
//returns ""
This is expected.
Here's the question:
How can I check that there is content?
I'm trying to show/hide placeholder text (no, I can't use the native stuff). It needs to be type="number" because I need to force the mobile number keyboard.
Any thoughts?
Update:
From the responses below I can see that I wasn't clear enough in my question.
1) I need to use JavaScript to tell me whether there is content in the input. (I don't need to extract it, I just need to see whether there is content).
This is tricky, because invalid content (like putting words in a number input field) means the value="" even if there is content typed in.
This is the exact problem I need to solve.
inputEl.validity.valid might work but I can't find any docs on how well it is supported across browsers.
Check if you can do something with that :
html
<input id="my-input" type="number">
js
$(document).ready(function(){
$('#my-input').on('input', function(){
console.log($(this).val());
});
});
At mobile device specially Samsung append value in field do not throw key press event,
you can validate the field with onChange="check(this)"
if (variablename==""){
//no content
}
or
if (variablename.length==0){
//no content
}
If the only reason you need to force the input type to be a number is for the number-pad, why don't you instead make type="text" and pattern="\d*"? This way you can handle and check the input any way you'd like, but still, force the number-pad to show.
<input type="text" pattern="\d*">
This was the one that actually answered it:
How to get the raw value an <input type="number"> field?
Basically you can check input.validity.valid or input.validity.badInput.
Not supported in IE but good support elsewhere.
More details on it here:
https://developer.mozilla.org/en-US/docs/Web/API/ValidityState

Placeholder for deactivated input[type="text"] in IE 10/11

Situation 1
Why is the placeholder selectable in a deactivated input[type="text"]?
<input name="minMax2" disabled="disabled" id="minMax2" type="text"
placeholder="min. 100 / max. 200" min="100" max="200">
Situation 2
I've even have a weird situation where I can type text into the placeholder but this does happens if I click into a text field which is deactivated but because I've left another field and an attached change event did enable the datepicker.
Any idea? Did I miss something or is this a bug of Internet Explorer 10 and 11?
Looks like this is a browser behavior. As an alternative you can keep it enabled (style it appropriately as disabled if needed) and add attribute onfocus="this.blur()"
Here's your demo modified: http://jsfiddle.net/a8ezd/1/
I made a few changes to your jsfiddle from what I understand to be your problem. In your jsfiddle you included jQuery so I thought I would add to your script. I have just changed how you have declared disabled in your input and also made a change to your script so that it now removes the disabled attribute on focus.
$('#test3').prop("disabled", false).focus();
http://jsfiddle.net/a8ezd/3/
If you want to go further and make it so that the user can't even select the placeholder slightly when it's e.g. disabled then you could alter the user select in the css by adding the following with the appropriate browser prefix:
user-select:none;
Example of that here:
http://jsfiddle.net/a8ezd/4/

Submitting programmatically inserted value and registering for the auto complete feature

I found that if you programmatically fill an input element with a value using javascript and subsequently press the button (without touching the input element), the value will not be registered with the auto complete feature in ie (testing with 6, 7, 8), whereas this does work in "normal" modern browsers. The values will only be added to the auto complete register if you manually press at least one key and subsequently press the submit button.
Is there any workaround to make older ie browser register programmatically inserted values? For example, is there a way to simulate typing the value that actually fills out this value in the input element?
<form method="POST">
<input type="text" name="test" />
<input type="submit" />
</form>
<script>
var input = document.getElementsByName("test")[0];
input.value = "some value";
</script>
No. IE8 and his older brothers are, well, old and unsupported with newer frameworks due to these kind of problems.
Modern browsers will know to save the correct value, even if it was written through Javascript, since they write the real value of the input. IE8 and older save the value only if you have written it - there is no way to simulate a writing of the value as if the user would write it.

Categories