Position of cursor in WKWebView with an editable paragraph in iOS - javascript

Is there anyway to get the position of the cursor in a WKWebView in iOS that contains an editable paragraph (a paragraph with attributed contentEditable set to true)?
EDIT: To add additional information, the editable div can contain other subnodes

If you have access to document and mouse position inside the view you can use document.elementFromPoint(x, y);

This can be done in multiple ways using HTML5 (using autofocus atribute) or using javascript (document.getElementById("IDHERE").focus(); - using focus event). I will write all in one code snippet uncomment and use it based on your requirement.
//if u commnet the second form
let domObject = document.getElementById("lname"); // refer which object to focus
domObject.focus(); // event to trigger focus on the refereced dom object
//throw error till second form is uncommented
<!-- html5 way the most easiest way -->
<form action="/action_page.php">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname" autofocus><br>
<input type="submit">
</form>
<!-- autofocus refers where to focus -->
<!-- unncoment below and comment above -->
<!-- javascript way -->
<!--
<form action="/action_page.php">
First name: <input type="text" id="fname"><br>
Last name: <input type="text" id="lname"><br>
<input type="submit">
</form>
-->

Related

Wrong keyboard focus order - a11y

I have created an application in React.js with satisfying all WCGA accessible guidelines. But currently I'm facing some issues like
The keyboard focus always starts from first interactive element (back
button) regardless of the caret/cursor position in the document.
To understand this issue, I am adding a portion of source code where the user can enter their first name and last name. I have also added a back button on the top left of the same page.
Please find the code below:
<section >
<button onClick={()=>this.goback()>Back</button>
</section>
<section >
<form className="form-example">
<fieldset>
<legend>User Details:</legend>
{this.state.errors && this.state.errors.length? <section>
{this.state.errors}
</section> : null}
<section className='input-fields'>
<label> First Name:
<input
type="text"
aria-label='First Name'
id = 'name'
aria-required="true"
onChange={this.onchangeHandler}
value={this.state.firstName}
name="firstname"
/>
</label>
<label> Last Name:
<input
type="text"
aria-label='Last Name'
aria-required="true"
onChange={this.onchangeHandler}
id='lastName'
value={this.state.lastName}
name="lastName"
/>
</label>
<button type="button" id='submit' onClick={()=>this.submitForm()}>Login</button>
</section>
</fieldset>
</form>
</section>
People with visual impairments can become disoriented when tabbing takes focus someplace unexpected, or when they cannot easily find the content surrounding an interactive element. This means when an user places the cursor at the "first name" field and presses the "tab" button, the focus is going to the back button (which is the first interactive element in the page), but it's expected to go to the "last name" field.
scenario
- An html page contains multiple interactive elements. A user with some visual disabilities places the cursor in an element in the middle of the page, and presses tab key to move the focus to the very next element.
Issue
- The focus is going to the top of the page (first interactive element).
Can anyone suggest a solution to fix this issue?

Display element next to another from different parts of the DOM tree

I have two forms, one larger and one smaller. I would like to display the smaller form next to a specific input of the larger form. It's not valid html to embed one form within another in the DOM, but is there a way to display one form over / inside another form next to a specific input using CSS or JS?
<!-- Main Form -->
<form action="action1" method="post">
Name <input type="text" name="name" value="">
Job Title <input type="text" name="job_title" value="">
Cell Number <input type="tel" name="mobile" value=""> <!-- SMALLER FORM SHOULD DISPLAY NEXT TO CELL # INPUT -->
Favorite Sport <input type="text" name="favorite_sport" value="">
Hobbies <input type="text" name="hobbies" value="">
<input type="submit" value="Save">
</form>
<!-- Smaller form loaded via js -->
<form id="optin_js_loaded_form"></form>
<!-- js -->
<script src="external_js_library.js"></script>
<script>
// js code to load form into #optin_js_loaded_form using external_js_library.js
</script>
NOTES
The forms need to be separate because the smaller form is created via an external js library from a marketing service.
I know I could make the data from the larger form submit via ajax, but I'm hoping I can save some work by just changing where the smaller form displays.
EDIT 2020-02-05 14:40
Found a webpage that suggests some possible solutions, but doesn't give much direction on how to implement them. https://discourse.wicg.io/t/position-an-element-relatively-to-another-element-from-anywhere-in-the-dom/968
You could make use of the form attribute to avoid the nesting of form elements. You move the controls from the main form outside of that form element, and add the form attribute to all of them.
Now you can place the small form at its desired position, without violating the HTML rule that form elements should not be nested.
You would still need to apply some CSS on that small form element, so it does not flow to the left. Something like display: inline-block or similar could be useful.
Here is the suggested HTML part:
<form id="mainform" action="action1" method="post"></form>
<div>
Name <input type="text" name="name" form="mainform" value="">
Job Title <input type="text" name="job_title" form="mainform" value="">
Cell Number <input type="tel" name="mobile" form="mainform" value="">
<!-- Smaller form loaded via js -->
<form id="optin_js_loaded_form">
</form>
Favorite Sport <input type="text" name="favorite_sport" form="mainform" value="">
Hobbies <input type="text" name="hobbies" form="mainform" value="">
<input type="submit" form="mainform" value="Save">
</div>

jQuery targeting selector by input type and form name

I want to target any input of text type belonging to a form of a specific name. Because the form will have numerous input fields, I don't want to target a particular input name, but rather, capture the blur (or focusout) event for any input[type="text"] occurring within the form wrap.
My present code, which doesn't work:
$( document ).ready(function() {
$('form[name="tax_form"] input[type="text"]').on("blur",function() {
alert($(this).val());
});
});
I answered my own question. Because the code sample is essentially correct, there is no need for multiple people to try to solve the unsolvable. The problem had something to do with where I placed the javascript code, and nothing to do with structure or syntax of the code, itself.
The way the event "change" works is what it sounds like you want. An event handler doesn't actually fire when the input is clicked or if text is keyed in, it fires when text is entered and then the input loses focus.
In the following Snippet the same selector you are using is delegated to the "change" event. You'll notice that the ['tax_form'] has 4 text inputs yet the last one is the only one working. The reason is because if an input isn't assigned a type attribute, then by default type is 'text". So when using a selector based on an input's type="text", you must keep that in mind. So if you are in full control of your HTML, make sure that each input has a type attribute with an explicit value, or use classes which is better IMO.
SNIPPET
$(document).ready(function() {
$('form[name="tax_form"] input[type="text"]').on("change", function() {
alert($(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name='notIt'>
<fieldset>
<legend>Not a Tax Form</legend>
<input>
<input type="text">
<input>
<input type="text">
</fieldset>
</form>
<br/>
<br/>
<form name='stillNotIt'>
<fieldset>
<legend>Still not a Tax Form</legend>
<input type="text">
<input>
<input type="text">
<input>
</fieldset>
</form>
<br/>
<br/>
<form name='tax_form'>
<fieldset>
<legend>Tax Form</legend>
<input class='klass' value='TEXT INPUT BY DEFAULT'>
<input value='TEXT INPUT BY DEFAULT'>
<input name='text' value='TEXT INPUT BY DEFAULT'>
<input type='number'>
<input type='text' value='THIS ONE COUNTS'>
</fieldset>
</form>
Previous commentators were right, that my code was fine as-is. I took my selector code out of a header script file, and placed it at the bottom of my footer script, and it worked as expected.
In the end, it wasn't my code that was the problem, but rather something to do with where I placed it. Possibly other javascript or jQuery code stepping on it.
Your code should work fine. Here's a working example of it to prove it's working. The tax_form fields should console.log() on blur. The another_form should not.
$(function() {
$('form[name="tax_form"] input[type="text"]').on("blur",function() {
console.log($(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Tax Form</h1>
<form name="tax_form">
<input type="text" name="first" value="first">
<input type="text" name="second" value="second">
<input type="text" name="third" value="third">
</form>
<h1>Another Form</h1>
<form name="another_form">
<input type="text" name="first2" value="first2">
<input type="text" name="second2" value="second2">
<input type="text" name="third2" value="third2">
</form>

How to create a Password field in javascript

I am making a sign up page and the user have the option to either sign up as a an employee or as an administrator(radio buttons). If he chooses to signup as an administrator i need to add a Password field that he is supposed to know(the company should provide him with that password).
Here is what i tried
<form method="post" action="Registration.php" onSubmit="return valid(this)">
#some code here
Admin<input type="radio" name="radiobutton" id="v2" value="v2" onclick="ch()">
<script type="text/javascript">
function ch(){
var newInput=document.createElement("input");
newInput.setAttribute('type','password');
newInput.setAttribute('name','password');
newInput.setAttribute('value','password');
document.getElementById("v2").appendChild(newInput);
}
</script>
NOTE: This is my first time using javascript!
Edited the code,still doesn't work.
You created a new <input> element, but you never put it into the document.
If you want to see the element, you need to add it somewhere in the DOM tree by calling appendChild() on an existing element.
Jquery is much easier to use:
$(selector).append("<input type="password" name="password" value="password">");
Better way is to have a class called "hidden" that hides the element which has that class. so if we click on the employee radio, we give the admin fields' div the hidden class , thus hiding it and remove the hidden class from employee fields.
Admin<input type="radio" name="radiobutton" id="v2" value="v2" onclick="changefields(1)">
Employee<input type="radio" name="radiobutton" id="v2" value="v2" onclick="changefields(2)">
<div id='employees' class='hidden'>
<!-- input for employees -->
</div>
<div id='admins' class='hidden'>
<!-- input for admins -->
</div>
<script>
function changefields(type){
if(type==2){
$("#employees").removeClass("hidden");$("#admins").addClass("hidden");
}
else{
$("#admins").removeClass("hidden");$("#employees").addClass("hidden");
}
}
</script>
<style>.hidden{display:none}</style>
You need to create a new element.
var newInput=document.createElement("input");
and append the same element to DOM by appendChild().

Create new form fields with jQuery

I have a form which starts out with 2 text inputs. The standard scenario is the user enters a number in one field and his/her name in the other and then the page will be updated (not reloaded). But in some cases the user may want to enter several numbers which are connected to the same name and the way this will be implemented is by the user clicking an "add another" link next to the text box.
When the user clicks the "add another" link, the value from the textbox needs to be inserted into a new (dynamically created) text field and the text field where the user entered the number should be reset to default value. The user can enter 10 numbers this way before an alert is presented informing him/her about more efficient ways to do this operation.
I'm clueless as to how this is done (can it be done) jQuery and it would be great if someone can help out.
Here is the html I'm working with:
<div id="searchFields" class="control-group inlineForm">
<label for="regNr">Regnr</label> <input type="text" id="regNr" class="uprCase" placeholder="Regnr." size="6" maxlength="6">
<span class="addRegNr">add another</div>
<label for="poNr">PO.nr</label> <input type="text" id="poNr" placeholder="PO.nr." size="12" maxlength="12">
<input type="button" value="GET INFO" class="last" id="getBaseInf">
</div>
http://jsfiddle.net/RgKV9/
Cheers!
EDIT UPDATE
I've taken a liking to Aske G's example and have made some changes to it. Here is the new code I'm working with, jsfiddle.net/SDpfy Although I managed to do some minor changes to AskeG's code I cant figure out how to add unique ID's and individual delete links for each generated field that ends up in the basket. Also, how can I set the generated fields to readonly and animate them when they show up in the basket?
just add a click watcher to the span. Check this fiddle: http://jsfiddle.net/ranjith19/RgKV9/4/
I have done some basic changes. If you need custom names id's you should use a templating library and then append it
<div id="searchFields" class="control-group inlineForm">
<label for="regNr">Regnr</label> <input type="text" id="regNr" class="uprCase" placeholder="Regnr." size="6"
maxlength="6">
<label for="poNr">PO.nr</label> <input type="text" id="poNr" placeholder="PO.nr." size="12" maxlength="12">
<input type="button" value="GET INFO" class="last" id="getBaseInf">
<p></p>
</div>
<span class="addRegNr" style="display:inline">add another</span>
<script type="text/javascript">
$(document).ready(function () {
str_to_append = '<label for="regNr">Regnr</label> <input type="text" id="regNr" class="uprCase" placeholder="Regnr." size="6" maxlength="6">\
<label for="poNr">PO.nr</label> <input type="text" id="poNr" placeholder="PO.nr." size="12" maxlength="12">\
<input type="button" value="GET INFO" class="last" id="getBaseInf"><p></p>'
$(".addRegNr").click(function () {
$("#searchFields").append(str_to_append)
})
})
</script>
​
You can do it, using jquery append method.
here I leave a link with some examples:
http://api.jquery.com/append/
I guess, you might just be looking for something like this.
I would do something like this:
<div id="searchFields" class="control-group inlineForm">
<label for="regNr">Regnr </label><input type="text" id="regNr" class="uprCase" placeholder="Regnr." size="6" maxlength="6"/><br/>
</div>
<span class="addRegNr">add another</span><br/>
<label for="poNr">PO.nr</label> <input type="text" id="poNr" placeholder="PO.nr." size="12" maxlength="12">
<input type="button" value="GET INFO" class="last" id="getBaseInf">
and then some js that looked like this:
var $input = $("#searchFields").children();
$(".addRegNr").on("click", function(){
var $newField = $input.clone();
// change what you need to do with the field here.
$(this).siblings("#searchFields").append($newField);
});
It's also here: http://jsfiddle.net/tatLw/
Basing solution on this blog post jQuery – Dynamically Adding Form Elements by Charlie Griefer, you could try the following:
Markup:
<div id="searchFields" class="control-group inlineForm">
<form id="myForm">
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<label for="regNr">Regnr</label>: <input type="text" name="regNr" placeholder="Regnr." size="6" maxlength="6" />
<label for="poNr">PO.nr</label>: <input type="text" id="poNr" placeholder="PO.nr." size="12" maxlength="12">
</div>
<div>
<input type="button" id="btnAdd" value="add another Reg field" />
<input type="button" id="btnDel" value="remove fields" />
</div>
<input type="button" value="GET INFO" class="last" id="getBaseInf">
</form>
</div>​
Javascript:
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
// manipulate the name/id values of the input inside the new element
newElem.children(':first').attr('id', 'regNr' + newNum).attr('regNr', 'regNr' + newNum);
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
// enable the "remove" button
$('#btnDel').removeAttr('disabled');
// business rule: you can only add 5 names
if (newNum == 5)
$('#btnAdd').attr('disabled','disabled');
});
$('#btnDel').click(function() {
var num = $('.clonedInput').length;
$('#input' + num).remove(); // remove the last element
$('#btnAdd').attr('disabled',''); // enable the "add" button
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDel').attr('disabled','disabled');
});
$('#btnDel').attr('disabled','disabled');​
DEMO: http://jsfiddle.net/chridam/qW9ra/
To add any HTML with jQuery you will eventually end up calling .append(), or one of its variations like .before, .appendTo, etc.
These can be given raw HTML strings, but unless you have an HTML template ready and plain, don't use string concatenation to build your HTM. This is fragile and insecure. Instead, create the elements with jQuery() directly, like so:
jQuery('<input type="text"/>').attr({
value: '',
placeholder: '...',
id: '..'
})
.appendTo( .. )
In addition, don't forget to create labels for these new elements as well (if appropiate).
Another few best practices relevant to this scenario:
If you're going to be dynamically making new form elements appear (as opposed to adding more additional fields for an existing field), it is best to not create these with JavaScript. Instead make sure they are present in the page output from the beginning, then hide them from $(document).ready with .hide(). That way it will be a lot easier (as all you need is a reference to the hidden element, and call .show() when you have to). And that way it doesn't rely on javascript flow being present, enabled and functioning as expected because this way if anything happened along the way (exception thrown, cdn issues, whatever) the form will fallback to a fully-present version that just works.
If you're going to have a lot of these "+" or "add" button scenarios, I'd make a .clone() of the original field, strip it (clear value, remove id-attribute), and store it in a local variable. Then from the click handler, clone that, and put it into the document where you need it. You may also want to have a server-side fallback by making the add button a submit button with a certain name/value pair that the server detects as a non-final input in which case it will return the same page with the values pre-filled but with more fields.

Categories

Resources