REACT -- How to change the click state of a focused / blurred event - javascript

I'm trying to switch between a focused / blurred state for a search bar. Right now the tag has a click handler that shows an input field if the element is clicked. I'm trying to reverse this effect and hide the visibility of the input field when the user clicks outside the element.
My code is:
var Search = React.createClass({
getInitialState:function(){
return{ inputVisible:false }
},
showInput:function(){
this.setState({ inputVisible:true });
},
componentDidUpdate:function(){
if( this.state.inputVisible ){
this.getDOMNode().focus();
}
},
renderInput: function(){
return (
<input type="text" style={this.props} />
);
},
renderLink: function(){
return (
<a><h3 onClick={this.showInput}>Search</h3></a>
);
},
render: function() {
if( this.state.inputVisible ){
return this.renderInput();
}else{
return this.renderLink();
}
}
});
I've tried adding logic to the componentDidUpdate function, so that
if (input.state.isVisible == false ) {
this.getDOMNode().blur();
}
I've also tried adding an onBlur handler to the element and tried creating a hideInput method:
hideInput: function() {
this.setState({ inputVisible:false });
}
and adding to the element:
<a><h3 onClick={this.showInput} onBlur={this.hideInput}>Search</h3></a>
But something just isn't working. Can anyone point out what I'm doing wrong?

You can't focus an H3 element without a tabindex attribute, and so it can't be "blurred" to begin with, thus the onBlur event doesn't fire. Try attaching the onBlur event on the rendered input element in your renderInput method.
Here's an example: http://plnkr.co/edit/STMPIkIQEIAZPZQ9SCq4?p=preview

Related

Click is being invoked before focusOut event in js

I have input element which will take input and filter the contents and the filter event will be trigger once the user gets focused out from the input element.
When the user having the focus in the input element and he clicks in one of the button, the click event is invoked first and then the focus out event, as it creates conflicts while generating the filtered content.
I tried changing the order of code and other options such as changing the way of invocation of the click event - none of the ways worked out for me
$('body').on('focusout', '.classname', functionname);
function functionname(e) {
if (typeof e == 'object') {
}
}
$('body').on('click', '.buttonclass', function (e) {});
Could someone help me to build The FocusOut event to trigger first and then the click event.
Based on the current conditions, you have to - inside the click handler - retrieve the validation result, and based on that result, decide if button submission should or should not occur.
JS Code:
$("#input").focusout(function(){
var that = this;
valid = this.value.length ? true : false;
!valid && window.setTimeout(function() {
$(that).focus();
}, 0);
});
$("#button").click(function(e) {
if ( !valid ) { return false; }
e.preventDefault();
alert('execute your filter)');
});

Focus remains on field

I'm trying to figure out why my focus remains on an element. This is html from the autocomplete angular plug-in that I'm using:
<autocomplete id="search" ng-model="query" attr-placeholder="" click-activation="true" data="items" on-type="updateItems" on-select="searchItems"></autocomplete>
but every time I press enter no matter if I have my focus on the input field or not, or even on an other field, the on-select function is called every time.
this thing is in the plugin itself, maybe it needs some changes?
document.addEventListener("blur", function (e) {
// disable suggestions on blur
// we do a timeout to prevent hiding it before a click event is registered
setTimeout(function () {
scope.select();
scope.setIndex(-1);
scope.$apply();
}, 150);
}, true);
You could monitor what was the last selected input field with this code :
var lastFocusedElement = '';
// This would catch any input field - so you could add your forms selector too.
// for example : $("#myForm:input")
$(":input").focus(function () {
lastFocusedElement = $(this);
});
Then use the complete callback function from animate :
$("#div_NotificationOuter").animate({ bottom: '+=30px' }, 4000,function(){
if (lastFocusedElement != ''){
lastFocusedElement.trigger('focus');
}
});

Can I stop a click from triggering website's usual actions?

As an experiment with React.js, I am trying to build a chrome extension that uses a content script to inject a input field (and now a button too) into certain websites. In this case I am trying to inject it into Twitter. It looks like this:
please note that the code puts the button and input below the text, but it will have the same result
The injection works, but I can't actually use the input. I inject the element into tweets on the home page, and when I click on the input to type in it, it triggers the tweet and expands or contracts. This removes the focus from the input rendering it useless. I have tried to call back focus onBlur, and stopPropagation() onClick, but onClick isn't triggered and I'm not sure how to bring back focus with onBlur. How can I stop losing focus?
If you want to test it yourself, react-with-addons.js came from the starter kit here
EDIT: I tried adding button to the code to see if I could click on that, and I can. I can click on it with out triggering the tweet itself. This means there is something specific to the input box that is causing trouble, or there is something in the button that is blocking propagation of the click.
Is there something special triggered when you click on an input field that other elements don't have that the tweets might have?
EDIT 2: I have now tried to add stopPropagation to a containing div and increasing it's z-index, neither of them will stop it.
EDIT 3: I have now tried onMouseDown(and onMouseUp, and onClick, all at the same time) with stopPropagation, with no luck. The strange part is I tried isPropagationStopped() afterwards, and it returns true. If this is so then why is Twitter still being triggered?
test_input.js
/**
* #jsx React.DOM
*/
var Test_Input = React.createClass({
maintain_focus: function(){
e.stopPropagation();
console.log("=====");
},
refocus: function(e){
e.stopPropagation();
},
handle_click: function{
console.log("clicked");
}
render: function(){
return (<div>
<button onclick={this.handle_click}>
<input className="new_note_input" placeholder="Note" onclick={this.maintain_focus} onBlur={this.refocus}></input>
</div>);
}
});
var elements_to_append_to = document.getElementsByClassName('content');
[].forEach.call(elements_to_append_to, function(element){
var container = $("<span />");
$(element).after(container);
React.renderComponent(<Test_Input />, container[0]);
});
manifest.json
{
"name": "Test Input",
"version": "0.1",
"manifest_version": 2,
"permissions": ["tabs", "bookmarks", "declarativeWebRequest", "*://*/*"],
"content_scripts": [
{
"matches": [ "https://twitter.com/*"],
"css":["src/social_notes.css"],
"js":[ "build/jquery-2.1.0.min.js", "build/react-with-addons.js", "build/test_input.js"]
}
]
}
e.stopPropagation() works on event handlers. Since input field click triggers default behaviour, instead of e.stopPropagation(), e.preventDefault() with a return false; in the input box click handler should do the trick.
In the handler, do a $(this).focus(); before returning false. This will keep the text box in focus.
eg:
$(".inputField").on("click", function(e){
e.preventDefault();
$(this).focus();
return false;
})
Try adding a click handler on the div you're inserting and do e.stopPropagation() in the handler, like this:
/**
* #jsx React.DOM
*/
var Test_Input = React.createClass({
maintain_focus: function(){
e.stopPropagation();
console.log("=====");
},
refocus: function(e){
e.stopPropagation();
},
handle_click: function(){
console.log("clicked");
},
div_click: function(e) {
e.preventDefault();
e.stopPropagation();
},
render: function(){
return (<div onclick={this.div_click}>
<button onclick={this.handle_click}>
<input className="new_note_input" placeholder="Note" onclick={this.maintain_focus} onBlur={this.refocus}></input>
</div>);
}
});
var elements_to_append_to = document.getElementsByClassName('content');
[].forEach.call(elements_to_append_to, function(element){
var container = $("<span />");
$(element).after(container);
React.renderComponent(<Test_Input />, container[0]);
});
BTW, there are some syntax errors in your code.

using jquery i want the a div to hide when the input is empty?

For example say i have a text box and a hidden div called suggestions
$("#suggestinput").on({
keyup: function(){
$("#suggestions").addClass("active");
},
blur: function () {
$("#suggestions").removeClass('active');
}
//another event to know if input is empty while on focus, then removeClass('active');
});
The first event is when the user types in the input show suggestion, the second one is blur, so when the user unfocuses on the input the suggestions el will hide, i want a third event to check while on focus if the input is empty remove active class.
Working example is here thanks: http://jsfiddle.net/HSBWt/
Try this - http://jsfiddle.net/HSBWt/1/
$("#suggestinput").on({
keydown: function(){
$("#suggestions").addClass("active");
},
blur: function () {
$("#suggestions").removeClass('active');
},
keyup: function () {
if ( $(this).val() == "" ) {
$("#suggestions").removeClass('active');
}
}
});

Combo doesn't blur when manually shifting focus

I have a combo box that's rigged to do shift focus to another form element immediately after the user has selected a value, with this config:
new Ext.form.ComboBox({
// ...
listeners: {
select: function( a, record ) {
if ( typeof( record ) == 'undefined' ) {
return;
}
if ( !Ext.getCmp('input-name').getValue() ) {
Ext.getCmp('input-name').focus();
}
},
blur: function() {
console.log('blurred');
},
render: function( field ) {
if ( !config.activity ) {
field.onTriggerClick();
}
}
},
// ...
});
However, a strange thing happens. The 'input-name' form field receives focus, and I can start typing in it, but the combo field is never blurred. It still has the 'x-form-focus' style, and the 'blur' event is never fired. Only when I use the mouse to click another field, the combo is blurred.
Does anyone know what's going on, and how I can circumvent this?
This is how I solved it:
listeners: {
select: function( a, record ) {
if ( typeof( record ) == 'undefined' ) {
return;
}
/**
* There's some weird stuff going on in the combo control, that causes it not to blur when shifting focus,
* so we have to do it manually. This action has to be deferred, because the control is going to refocus
* itself at the end of the function firing this event (onViewClick()).
*/
this.moveFocus.defer( 100, this );
},
render: function( field ) {
field.moveFocus = function() {
if ( !Ext.getCmp('input-name').getValue() ) {
Ext.getCmp('input-name').focus();
this.triggerBlur();
}
};
if ( !config.activity ) {
field.onTriggerClick();
}
}
},
When any piece of code gets executed as the a part of an event and that resulted in some other event to fire, then the new event doesn't get fired.
onBlur should be executed only when a user performs some action in the UI because of which the combo box looses focus, rather than field loosing focus programmatically.

Categories