Actually register a "user" key input programmatically - javascript

Background:
I am writing a Chrome extension that programmatically replaces abbreviations with snippets of text. Like, it can auto-replace "brb" with "be right back".
The way (simplified to this question) I insert this snippet expansion is like this:
var newFullText = textBeforeAbbrev + expansionText + textAfterAbbrev;
textarea.value = newFullText; // OR
div.innerHTML = newFullText;
Problem:
The problem here is that although this correctly inserts the expanded text, the website does not catch it as an update to the textarea/div contents.
Some sites internally keep a track of textarea/div contents, updating it on input events. That means, if I do this expansion and submit the form, on some sites (like Facebook, Hipchat), this newFullText won't be registered - because it wasn't a user input event - so the website didn't catch it either!. So, the submitted value would be having the text prior to this expansion.
My attempts:
I've already tried firing the keydown and input events - on the concerned textareas - in this manner with NO luck at all:
function triggerKeypress(keyCode){
var ev = new Event("input");
ev.keyCode = keyCode;
this.dispatchEvent(ev);
}
My question:
Is these a way to achieve what I am requesting? Specifically:
Simulate a user keypress/keydown/input/whatever_necessary on the textarea/div/input element, so that the website internally catches it as an input/keypress(whatever event it is supposedly looking for), and updates its internal text, so that the submitted text correctly shows up
I'm looking for a native JS solution. My app is a Chrome extension so naturally I plan to support Chrome code, although cross-browser support is appreciated.
Minimum viable code sample:
Here's the zip file of the minimum code (11KB) you need to reproduce the issue. Please run it and try changing those two methods in the code to get them work, as stated in this question. I've confirmed the linked code does STILL NOT work on Hipchat, Facebook posts and comments. More details inside file README.txt.
How to use it?
1. Open Hipchat team chat, or Facebook.
2. Type "brb" into the team chat box/Facebook post/comments.
3. Press Shift+Space.
4. The expanded text "be right back" would clearly show up inside the textarea.
5. Press enter.
6. The submitted value will show up as "brb" instead of "be right back"
This question is not a duplicate question: please note that the other questions are about:
1. firing a keydown that fires their own custom handler, and which naturally do NOT work here
2. are way too out-dated and have become convoluted over time
3. use deprecated methods like Document.createEvent
Please let me know for more clarification. Thanks!

Related

Trying to programatically click a button on a web page with cefsharp

I'm using cefsharp and vb.net to put some code together to move to the next page of this site:
https://www.recommendedagencies.com/search#{}
The idea is to read the list of company names on each page and store to a csv file. This part I can do.
The problem I have is that I can't find the name of the 'Next' button - presumably if I had that I could execute some javascript on the browser to press the button.
I've inspected the page in Firefox, but can't see any name I can use - I'm not really familiar enough with html/page design to know why not or how it works.
Could anyone tell me a good method to get button names from a web page? - I've done some searching and even asked a similar question myself before, but I can't find anything which helps, given my patchy knowledge.
Thanks
Inspect the DOM for the 'Next' button.
Look for id's or classes that you can use to identify it.
use document.querySelector() to find the element by the css selector
call the element.click() function to programatically press next
const nextButton = document.querySelector('.sp-pages-nav_next')
nextButton.addEventListener('click', (event) => {
console.log('something clicked next')
})
nextButton.click()
<div class="sp-pages-nav sp-pages-nav_next" data-reactid=".1.3.4.1">Next</div>
In the above snippet on load you can see the code nextButton.click() invokes the console log. You can click the word Next manually to the same effect.
in cefsharp perhaps something like:
browser.ExecuteJavaScriptAsync("(function(){ document.querySelector('.sp-pages-nav_next').click(); })();");
A very similar example can be found here :
https://github.com/cefsharp/CefSharp/wiki/General-Usage#1-how-do-you-call-a-javascript-method-from-net
// When executing multiple statements, group them together in an IIFE
// https://developer.mozilla.org/en-US/docs/Glossary/IIFE
// For Google.com pre-populate the search text box and click the search button
browser.ExecuteJavaScriptAsync("(function(){ document.getElementsByName('q')[0].value = 'CefSharp Was Here!'; document.getElementsByName('btnK')[0].click(); })();");

How does Yahoo handle input considering you cannot modify its frontend to affect the email you send?

I was doing some research with emails and I believe I found an interesting technology, perhaps something very powerful from a cyber-security perspective.
If you open a Yahoo email in Google Chrome and click "Forward", you can do so with the javascript console.
You get the element by its classname or id and use the .click(), for instance after you open an email write this in your console
let x = document.getElementsByClassName("r_P u_b C_Z2aVTcY b_0 P_0 M_0 H_6Nds A_6EqO y_Z2hYGcu I_T C4_Z29WjXl ir3_1JO2M7 it3_dBP")[2];
x.click();
However there is no way to add your input programmatically and it makes me wondering how this is even possible.
In the image above, you can click on the "To" parameter and it will work. However THERE IS NO WAY to set your input from the javascript console in Google Chrome and then press the Send Button because it will simply not work. Don't believe me? Try it.
I noticed that one of the inputs has a "value" attribute which changes to the email you write as seen in the next picture
I did everything to set the right input, including the following commands:
let x = document.querySelectorAll('[id=message-to-field]')[0]
x.setAttribute("value","fakeemail#yahoo.com");
The email sets up correctly however when I click "Send" I get the error that no email was set
Other things I tried worth mentioning
Set up the email with a ; at the end like fakeemail#yahoo.com;
x.value = "fakeemail#yahoo.com"; // this sets the internal value, not the value attribute
x.parentElement.innerText = "fakeemail#yahoo.com";
I now have two questions:
How is this possible in terms of technology? Does Yahoo constantly control client-side inputs and at what expense (e.g resources, loading time, etc.) ?
Assuming there is a way, how can we set up the email input using the Javascript console in Google Chrome?

IBM BPM how to handle keypress events in Coach Views

I am somewhat familiar with HTML, CSS and JavaScript and have written some small apps using Angular and Ionic.
Now I am working with IBM BPM Coach Views and tries to make a simple Coach View
with an input field (bound to a string variable) and a button.
I would like to have the button disabled (in BPM language: read only) as long as
the field is empty, but when the user starts to type anything in the field, the button should become enabled. I have bound the visibility of the button to another string variable.
I have searched around and it seems I cannot find any simple examples of controlling visibility based on keypress events in BPM.
All I have seen are examples with Dojo components and Dijit widgets and currently that is a bit above my head. I would expect there must be some (relatively) simple way of doing it with some 20-40 lines of JavaScript in either the “Inline JavaScript” section or in one (or more) of the “Event Handlers” on the Behavior tab in the Coach View Designer in IBM BPM 8.5.6.
(it opens in a browser window because my Coach View runs in a Client Side Human Service).
Does anyone have such a simple example.
I would suggest you following approach.
Create one custom coach view (lets say CV1).
Within CV1 drag ibm bpm provided input text CV (give control id name as "inputText").
Within CV1 drag ibm bpm provided button CV (give control id name as "button").
Within inline JS or load event of CV1 write following code.
// get input text elment
var inputText = dojo.query("data-viewid['inputText']",this.context.element);
var button = dojo.query("data-viewid['button']",this.context.element);
//make button as disabled by default
button.setAttribute('disabled', true);
//key press event on input text
inputText.on("keydown", function(event) {
//Write your custom logic on key press
button.setAttribute('disabled', false);
});
What you are trying to achieve is validation script in "Data Change" tab of coach but if you want using events, use onInput or onChange even of input text coach view
if(me.getData()){
${viewId_of_button}.setEnabled(true);
}
else ${viewId_of_button}.setEnabled(false);
Product keeps updated, so look for code best for your version.
Note- if you use onChange, user may have to click outside the input field to trigger change event.

addField.setAction properties are not being retained...Possible causes?

I have some Javascript running in Acrobat XI that programmatically creates a series of buttons using the addField method. I need each button to run a specific lengthy Javascript routine upon MouseUp, but at the moment I can't seem to get any newly-created button to run even a trivially simple command.
Basically, when my code executes, everything works as intended with the exception of the .setAction property, which does not seem to be retained, leaving my newly created and formatted buttons without any functionality. I can go in after the fact and add the Javascript manually, of course, but in this case I need a programmatic solution.
Any ideas what I might be doing wrong here?
var cScript = "app.beep(0);";
var newBTN = this.addField(wName,"button",thisPage,RotatedRect);
//"wName","thisPage" and "RotatedRect" are well-defined elsewhere
newBTN.setAction=("MouseUp",cScript);
newBTN.delay = true;
newBTN.borderColor=color.red;
newBTN.borderStyle=border.s;
newBTN.delay=false;
This button is created as expected, and the formatting and name are as expected. The only problem is that the .setAction property does not seem to be saved at all. Nothing whatsoever happens when I click on the new button, and when I manually inspect the new button's properties, it has no action or javascript attached to it.
Turns out I was just being sloppy and not paying attention to syntax.
Removing the "=" from the newBTN.setAction=("MouseUp",cScript);line has fixed the problem.

How can I force an AngluarJS form to realize required fields have been filled through DOM manipulation (no user input)?

I've written an Excel VBA macro to paste some data into an AngularJS form -- it opens an Internet Explorer (11) window, navigates to the page containing the form, and crawls the document tree looking for certain elements by their ID, changing their values from blank to non-blank strings from the Excel sheet. However, when I submit the form, the form logic treats all the required fields as if they were still blank, drawing a red box around the supposed offending fields. (I can intervene at this point by clicking into each field, typing a random character at the end of the pasted data and immediately deleting it, and this triggers the logic that the required field is now filled.)
I'm not a javascript programmer and didn't design the form (nor can I change it in any way). I can manipulate the DOM elements (focusing and blurring the fields, for example, though that doesn't seem to work), and I can probably run any command that could be entered into the console in the browser debugger. Would any AngularJS expert know a relatively simple way to force the form to check itself?
Have you solved this problem Karim or found any solution? I recently had a project of mine, with the same problem.
Try to find the tag with ng-submit something like what I have 'ng-submit"=submit($event)"'. I referenced the form element and used .submit. In your case, try this:
Set HTMLFormEl = HTML.getElementById("accountNameValue")
HTMLFormEl.Submit
The 'submit' was the one that solved my problem. Let me know if this works for you.
Not a VBA nor AngularJS expert but I noticed that AngularJS has nothing to do in treating the required fields as if they were still blank. Just need to find the correct event to trigger. Just my opinion.
Don't know is my answer is actual or not, but i had the same problem, and i found a solution using Application.SendKeys. The function filling out the form looks like this
Function inputWrite(ByVal str As String, inputEl As Object, ByVal hwnd As LongLong) As Boolean
TryAgain_inputWrite:
strSub = Left(str, Len(str) - 1)
strKey = Right(str, 1)
inputEl.Focus
inputEl.Value = strSub
setToFore hwnd
Application.SendKeys strKey
Application.Wait DateAdd("s", 1, Now)
If (inputEl.Value = str) Then
inputWrite = True
Else
GoTo TryAgain_inputWrite
End If
End Function
setToFore is just a function to always keep the Internet Explorer on top of other applications, so the send key won't miss.

Categories

Resources