Select textarea, focus it and simulate pressing a space bar - javascript

When user clicks on an img i want to add it's alt value into textarea and add a space to it as if user pressed it himself but not like this el.value += ' ';
Code :
var chatInput = document.querySelector('textarea[data-a-target="chat-input"]'); //textarea selector
var chatSend = document.querySelector('button[data-a-target="chat-send-button"]');
emoteList.addEventListener('click', function(e){
if(e.target.nodeName == 'IMG'){
chatInput.focus();
chatInput.value += e.target.alt;
}
})
The text gets added into textarea, but textarea change event doesn't fire.
What would be the best way to do this? I have spent hours using both Javascript and jQuery to make it work using events but i can't get it right.
I tried focusing on textarea and using dispatch/fire event on window but it does nothing.
I tried firing keypress on textarea but it has no effect either.

if your problem is that change event is not triggering then you can manually trigger it by
var e = $.Event( "change" );
$("#altArea").trigger(e);

Don't need jQuery for this - just use chatInput.dispatchEvent(new Event('change'));.
const chatInput = document.querySelector('textarea');
chatInput.addEventListener('change', () => {
console.log('saw a change');
})
const chatSend = document.querySelector('button');
document.querySelector('#emote-list').addEventListener('click', (e) => {
if(e.target.nodeName !== 'DIV') return;
chatInput.focus();
chatInput.value += 'foo ';
chatInput.dispatchEvent(new Event('change'));
})
<textarea></textarea>
<div id="emote-list">click</div>

Related

contentEditable div Multilines issue on FireFox

I have a div with `contentEditable="true"
<div id="msgInput" contentEditable="true"></div>
When the user types in it and presses 'enter' it appends what the user typed to another div
<div id="output"></div>
But I need it so the user can type multiple lines (with shift+enter) without firing the 'keydown' event on the 'enter' key
Here is how I achieved this: (please note that I added the 'input' event Listener because I need to save what the user types in my state variable)
let input = document.getElementById('msgInput');
let output = document.getElementById('output');
let state = '';
input.addEventListener('input', function(event) {
state = event.target.textContent;
});
input.addEventListener('keydown', function(event) {
if (event.key === 'Enter' && !event.shiftKey) {
event.target.innerHTML = '';
output.innerHTML = state;
event.preventDefault();
}
});
On Chrome, this is working fine,
for example, If I type "first"
then shift+enter,
then type "second"
and then press enter, it will be appended like this:
first
second
And that's exactly what I want.
But on firefox, it's appended in one line (merged as one word)
firstsecond
I need it in firefox to have the same behavior as in chrome
here's a fiddle for this
https://jsfiddle.net/Lrnx24tb/2/
You could try replace textContent for innerText:
input.addEventListener('input', function(event) {
state = event.target.innerText;
});

How to specify the order of a focusout and a click event?

I have an input field with a JS focusout event. Under my input field, I have an autocomplete popup with suggestions. But when I click on a suggestion, it’s playing the focusout before the event listener on the click of the autocomplete! Any clues on how I can I fix this conflict?
Picture of the input and its autocompletion:
The click event:
resultsFrom.addEventListener('click', (event) => {
let e;
e = event.target.parentNode;
inputFrom.value = e.getAttribute('data-display');
});
The focusout event:
inputFrom.addEventListener('focusout', () => {
const list = document.querySelector('#results-from');
let first = list.firstChild;
inputFrom.value = first.getAttribute('data-display');
resultsFrom.innerHTML = '';
});
The focusout event has a property on the event object of relatedTarget - this is the element that's going to gain the focus, in this case, it will be the element you're clicking on.
You need to check if that element is within your results, and not clear them out if that's the case. Something like this:
inputFrom.addEventListener('focusout', (e) => {
const list = document.querySelector('#results-from');
if (!list.contains(e.relatedTarget)) {
//the target is not in the list, continue as before
//otherwise allow the click to function by not clearing out resultsFrom
let first = list.firstChild;
inputFrom.value = first.getAttribute('data-display');
resultsFrom.innerHTML = '';
}
});

#Html.TextBoxFor text changed event

I have an #Html.TextBoxFor as below :
#Html.TextBoxFor(u => u.SomeProperty, new { #class = "jtb", #id = "TrajName", placeholder = "Traj Name" })
Now what I want to achieve is I want to know when a new character is added to this textbox at the same time it is entered.
I want to change a button state to active at this time. I tried blur and change event. But it is fired only when the focus changes.
$(document).ready(function () {
$('#TrajName').val("");
$('#StartLocation').val("-Select Location-");
$('#EndLocation').val("-Select Location-");
document.getElementById("BtnAddTraj").disabled = true;
$("#TrajectoryName").blur(function () {
if ($('#TrajName').text != "")
document.getElementById("BtnAddTraj").disabled = false;
else
document.getElementById("BtnAddTraj").disabled = true;
});
});
I have a scenario where user can directly try to click on the button after entering some text(ie cursor still inside textbox and focus is not changed).
So is there any event that gives live trigger when a character is added instead of firing on focus change?
You need to bind an event handler to the keyup JavaScript event.
Further more, I recommend you to use .prop for set disabled property.
Please try this:
#Html.TextBoxFor(u => u.SomeProperty, new { #class = "jtb", #id = "TrajName", placeholder = "Traj Name" })
$("#TrajectoryName").keyup(function () {
if ($('#TrajName').val() != "")
$("#BtnAddTraj").prop('disabled',false);
else
$("#BtnAddTraj").prop('disabled',true);
});
Another solution is to trigger the input event to the TrajectoryName textbox. This would fire every time your input changes.
$("#TrajectoryName").on('input',function () {
if ($('#TrajName').val() != "")
$("#BtnAddTraj").prop('disabled',false);
else
$("#BtnAddTraj").prop('disabled',true);
});

Prevent From Writing on TextArea using Bind Event "input propertychange"

I am handling the content inside a textarea using binding a function to the event "input propertychange"
Like this:
$('#textarea').bind('input propertychange', function () {
var textarea = document.getElementById('textarea');
window.lastLineWriting = textarea.value.substr(0, textarea.value.length).split("\n").length;
var writingOnLine = textarea.value.substr(0, textarea.selectionStart).split("\n").length;
if (writingOnLine < window.lastLineWriting) {
//dont write on textarea
}
});
I don't know how to prevent the char typed by the user's keyboard to appear on the textarea... Inside that if I want to prevent the text to be inserted on textarea..
How can I do this?
you could easily stop the user from typing with this code, using jQuery:
$('textarea').bind('keypress', function (e) {
e.preventDefault();
return false;
});
NOTE:
this code will prevent the user from typing in all the textareas, to bind it specifically to one or some selected elements, you must change the selector to the desired elements.
var editable = false // Your Condition
if(editable != "true"){
$("#textarea" ).attr("disabled",true);
}

jQuery - triggering multiple events one by one

I'm using jquery tagsInput plugin where I need to dynamically modify the query(deleting the query or entering the new query) without actually typing in the search box connected with tagsInput plugin.
My problem here is I want to trigger backspace event at first then enter event next. Here is the code.
function triggering_events() {
$(".tag").each(function() {
var e = jQuery.Event("keydown");
e.keyCode = 8;
e.which = 8;
$("#input-search_tag").trigger(e); //triggering backspace event
});
var input = $("#input-search_tag");
input.val("food");
input.trigger(e); //triggering enter event
}
But only the backspace event is triggering from the above code. How can I make that enter event work?
Could anyone point out the mistake I've done?
Thanks!
you can try use the methods removeTag and addTag for remove and add tag's:
function triggering_events() {
var
idInput = 'input-search',
input = $("#" + idInput);
$("#"+idInput+"_tagsinput .tag").each(function() {
var tag = $.trim($(this).find('span:eq(0)').text());
input.removeTag(tag);
});
input.addTag("food");
}
run
There is an issue here:
$("#input-search_tag").val("food").trigger(e); //triggering enter event
.val() returns you a string value of the jquery Element, it is not a chainable method. strings do not have a trigger method.
You could fix this by splitting it into two calls:
var input = $("#input-search_tag");
input.val("food");
input.trigger(e); // triggering enter event
Or using .end():
$("#input-search_tag").val("food").end().trigger(e); //triggering enter event
Edit: putting it all together, along with reusing one event instead of creating multiples:
function triggering_events() {
var e = jQuery.Event("keydown");
e.which = 8;
$(".tag").each(function() {
$("#input-search_tag").trigger(e); // triggering backspace event
});
e.which = 13;
$("#input-search_tag").val("food").end().trigger(e); // triggering enter event
}

Categories