JS - Prevent append to be added multiple times - javascript

I have a form that has a mobile field. On submit button I put an event to add a value to the mobile field (it adds the country region code automatically which is a fixed value of "11"), so when the user clicks on Submit, the JS adds the "11" value to the mobile so the this field goes to the data base like this "1155555555" (the user just typed "55555555").
Ok, the problem is that if the user left an empty field (all fields are required), and clicks on Submit, the form won´t be sent but it will add the value "11" to the mobile field no matter what, and when the user fills up the empty field and click on Submit for the second time, it will add AGAIN the value "11", so the mobile goes like "111155555555", and so on and so forth.
Basically, what I need is to prevent this function from happening multiple times. It has to happen only once. How do I achieve this using JS?
HTML:
<input id="mobile" name="MOBILE" type="tel"><input type="number" value="11" id="front" class="hide">
<button type="submit" onclick="append11()">SUBMIT</button>
JS:
function append11(){
var mobilenumber = document.getElementById("mobile");
var front = document.getElementById("front").value;
mobilenumber.value=front+mobilenumber.value;
alert(mobilevalue.value);
}

Why you don't append the 11 in the function?
Like:
function append11(){
var mobilenumber = document.getElementById("mobile");
mobilenumber.value="11"+mobilenumber.value;
alert(mobilevalue.value);
}

I think you should heed the comment responses to your original question. Your approach has some risks.
But I'll assume you're a beginner who's just trying to learn how to do something like what you're asking about, so the javascript below applies a few principles you might consider.
function isNumberValid9(num) {
console.log(num, num.length);
//check string length and pattern
//this could be combined into a single regex, e.g.: mobileValue.match("^[0-9]{9}$")
var isValid9 = num.length === 9 && num.match("^[0-9]+$");
console.log(isValid9); //display the value about to be returned
return isValid9;
}
/* Conditionally prepend "11" */
function maybeAppend11() {
var mobilenumber = document.getElementById("mobile");
var mobileValue = mobilenumber.value;
//only prepend "11" if the number matches your expected pattern and length
if (isNumberValid9(mobileValue)) {
var front = document.getElementById("front").value;
mobilenumber.value = front + mobileValue;
}
alert(mobilenumber.value);
}
<input id="mobile" name="MOBILE" type="tel" value="555555555"><input type="number" value="11" id="front" class="hide">
<button type="submit" onclick="maybeAppend11()">SUBMIT</button>

Related

How to show input field in only Uppercase using Oracle Jet oj-input-text?

I want to show letters only in uppercase in input text field.
<oj-input-text style="text-transform: uppercase;" id="text-input" placeholder="Select new Item number"
value="{{newItemNumber}}"></oj-input-text>
I have tried adding css "text-transform: uppercase" property to the element but that did not work. I also wrapped the element in a span and added css property but of no use. I want the input field to convert and show all input letters to uppercase as the user types. Is there a way to do it in ojet?
Thank you for your response. I realized that we can access and edit the input tag inside oj-input-text and perform our operations accordingly. Following code fixed my problem:
<oj-input-text id="text-input" placeholder="Select new Item number"
value="{{newItemNumber}}">
<input data-oj-internal="" type="text"
class="oj-inputtext-input oj-text-field-input oj-component-initnode"
placeholder="Select new Item number" id="text-input|input" oninput="let p = this.selectionStart; this.value = this.value.toUpperCase();this.setSelectionRange(p, p);">
</oj-input-text>
Another possibility besides OP's answer is to change the value when raw data (on each key pressed) is changed, e.g.
<oj-input-text value="{{newItemNumber}}" on-raw-value-changed="[[uppercaseMe]]"></oj-input-text>
class ViewModel {
constructor() {
const self = this;
self.newItemNumber = ko.observable();
self.uppercaseMe = (event) => self.newItemNumber(event.detail.value.toUpperCase());
}
}
It's not perfect as you sometimes can see the last lowercase-pressed character for a fraction of a second but does the job.

How do a maintain an accurate character count between input from separate fields using JS?

I am using a form to build a block of text, the final output of which needs to be kept under a certain character count.
For the user, I need to be able to provide real-time character counting so they can adjust their entries as appropriate.
Basic HTML would be as follows:
<form>
<input type="text" id="#input1">
<input type="text" id="#input2">
</form>
<div class="character-counter">0</div>
However my JS/jQuery is not working very well: while it is outputting a counter in real time, it seems to be concatenating the final results in the output despite me parsing the variables as integers.
$('#input1').keyup(function() {
// Variables
var currentCharCount = parseInt($('.character-counter').text());
var fieldLength = parseInt($(this).val().length, 10);
var newCharCount = fieldLength + currentCharCount;
// Counter output
$('.character-counter').text(Number(newCharCount));
});
$('#input2').keyup(function() {
// Variables
var currentCharCount = parseInt($('.character-counter').text());
var fieldLength = parseInt($(this).val().length, 10);
var newCharCount = fieldLength + currentCharCount;
// Counter output
$('.character-counter').text(Number(newCharCount));
});
The correct solution will update the '.character-counter' div with the correct total character count between the fields every time a character is typed or deleted or pasted in.
Thanks!
You don't want the old value of the character-counter element at all, you purely want to use the lengths of the text in the two inputs. Separately: Don't use keyup, use input. (What if the user right-clicks and pastes? No keyup occurs...)
Separately, the id attributes of your input fields are incorrect: They shouldn't have the # on them.
So (see comments):
// You can hook the event on both fields with the same call
// Note using `input`, not `keyup`
$("#input1, #input2").on("input", function() {
// Get the length of each input's current value, then put it
// in the .character-counter div
$('.character-counter').text($("#input1").val().length + $("#input2").val().length);
});
<form>
<input type="text" id="input1">
<!-- No # here --------^ -->
<input type="text" id="input2">
<!-- Nor here ---------^ -->
</form>
<div class="character-counter">0</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Partial Password Masking on Input Field

So I need to mask a SSN# input field, lets say the ssn is 123-45-6789, I need to display ***-**-6789 (real time as they enter each digit) but I still need to retain the original value to submit.
I got to the point where I can do that if the user strictly enters the value but it breaks if the user does anything else such as delete, or moving cursor to a random position and adds/deletes a number, copy pasting/deleting, etc. I really don't want to listen to a bunch of events to make this work if thats even possible.
I also tried having a div sit on top of the input field to display the masked ssn while the actual ssn was transparent/hidden behind it but again they lose the functionality of being able to add/delete/select delete/paste in random parts (other then when they start at the end) and also the cursor not totally in sync with the end of the ssn number (asterisk size was the issue). This also broke on some mobile browsers.
I also thought of having two separate input fields, one type password, and one type text sit right next to each other, but again highlighting and deleting/pasting between the two would be an issue.
Ideally if there was something out there to have an input field have two types, part of the value be type password and the rest be type text, that would be fantastic. Btw this is for react js app.
TLDR: Need a fully functional input field that will do password masking on only first 5 digits of ssn and be plaintext for last 4 digits (while having the full plaintext value available for submission).
Thanks!
This might be a little sloppy, but it works as you want it to, is all in one text field, returns the full accurate SSN (despite replacing first 5 values with bullet points), and allows for editing anywhere in the field.
<input type="password" id="ssn" maxlength=9 />
<script>
var ssn = document.getElementById('ssn');
ssn.addEventListener('input', ssnMask, false);
var ssnFirstFive = "";
var secondHalf = "";
var fullSSN = "";
function ssnMask(){
if (ssn.value.length <= 5){
ssn.type = 'password';
}
else{
detectChanges();
secondHalf = ssn.value.substring(5);
ssn.type = 'text';
ssn.value = "•••••";
ssn.value += secondHalf;
fullSSN = ssnFirstFive + secondHalf;
}
}
function detectChanges() {
for (var i = 0; i < 5; i++){
if (ssn.value[i] != "•"){
ssnFirstFive = ssnFirstFive.substring(0, i) + ssn.value[i] + ssnFirstFive.substring(i+1);
}
}
}
</script>
Essentially, every time the input is changed, it checks to see if it matches the first 5 from before, and if it doesn't, it will update the necessary characters.
You can use 3 different fields and make then password fields.
Add a focus handler that changes their type into text and a blur handler that changes them back to password.
You can combine them before submission or on the server.
#ssn1{width:25px;}
#ssn2{width:20px;}
#ssn3{width:35px;}
<input type="password" name="ssn" maxlength=3 id="ssn1" />
<input type="password" name="ssn" maxlength=2 id="ssn2"/>
<input type="password" name="ssn" maxlength=4 id="ssn3"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$('[name="ssn"]').focus(function() {
$(this).attr("type", "text")
});
$('[name="ssn"]').blur(function() {
$(this).attr("type", "password")
});
</script>
You can also write a pass handler to all a full SSN to be pasted in the first field and have all three fields get set.
This is the closest you are going unless you work with a single full text box and give the user the ability to mask and unmask the field.
In production apps, this actually the approach I take:
Masked:
Unmasked:
You can implement you own focus/blur functions to automatically unmask/mask the field as needed.
Achieve this using html data attributes.
i have used the same html tag and store actual value in html tag attribute (data-value) to use later on and store value to display in html tag attribute value.
Function to partial mask input value
function mask_field_value(obj, mask_letters_count=7){
mask_value = $(this).data('mask-value') || '';
unmask_value = $(this).data('unmask-value') || '';
if (obj.value.length <= mask_letters_count){
obj.type = 'password';
mask_value = obj.value;
$(this).data('mask-value', obj.value);
} else {
obj.type = 'text';
unmask_value = obj.value.substring(mask_letters_count);
obj.value = "*".repeat(mask_letters_count) + unmask_value;
$(this).data('unmask-value', unmask_value);
}
$(this).data('value', mask_value + unmask_value);
console.log($(this).data('value'));
}
Add an event on input fields to mask
$(document).ready(function () {
$(document).on('keyup', '.mask_input_display', function () {
mask_field_value(this);
});
});

Custom Validation on HTML Number Input Misbehaving

In putting together a small webapp, I'm trying to ensure that end users are unable to place invalid characters in a number field that can hold signed floats. I'm using Dojo to search on an applied CSS class (in this case, ogInputNumber) and set events on input, keyup, and blur.
Ideally, I would like the input to be type="number" and to only allow digits, a hyphen (for signed floats), and a period character to act as a decimal place. If a user includes more than one hyphen or period character, the JS should truncate that second invalid character and everything thereafter in the input. Unfortunately, the JS behaves differently depending on whether the input is type="number" or type="text".
For type="text", if I attempt to enter the text 2.6a, 2.6 is fine, but the a is caught on the input event and prevented from appearing in the input. This is the desired behavior, but I would like to have the input as type="number" so the number spinners appear and for ease of use with mobile devices (so the number keyboard is brought up by default).
For type="number", if I attempt to enter the text 2.6a, the 2.6 is allowed to remain, but as soon as a is typed, the entire field is cleared out. That will prevent any invalid characters, but it's annoyingly overzealous. I've replicated this behavior on Chrome, Firefox, IE11, and Opera.
Can anyone offer any suggestions as to why the JS operates differently between inputs with type="text" and those with type="number"?
HTML:
<p>
<label for="numberInput1">Text Input</label>
<input id="numberInput1" class="ogInputNumber" type="text" />
</p>
<p>
<label for="numberInput2">Number Input</label>
<input id="numberInput2" class="ogInputNumber" type="number" />
</p>
JS:
// Checks number input fields for proper formatting
require(["dojo/domReady!", "dojo/on", "dojo/query"],
function (ready, on, query) {
query(".ogInputNumber").forEach(function (node) {
// Replace all the non-numeric, non-period, and non-hyphen characters with nothing while the user is typing
on(node, "input, keyup", function () {
this.value = this.value.replace(/[^\d\.-]/g, '');
});
// When the user leaves the input, format it properly as a signed float (or zero if it's something weird)
on(node, "blur", function () {
try {
if (this.value) {
this.value = parseFloat(this.value).toString();
} else {}
} catch (error) {
this.value = 0;
}
});
});
});
Working JSFiddle: http://jsfiddle.net/etehy6o6/1/
I think that's the default behavior of number input type, but I'm not sure. It's logical to think the input should not let the user put anything that is not a number, so it clears all the value before you can fire your keyup event.
So to keep the last valid value declare a variable outside the scope of your event and set it to the replaced value that was not cleared because invalid key input.
Using the code in your Fiddle:
Edited because addressed bug in comments
HTML
<!-- I asigned default values to test other scenarios -->
<p>
<label for="numberInput1">Text Input</label>
<input id="numberInput2" class="ogInputNumber" type="text" value="3.1416" />
</p>
<p>
<label for="numberInput">Number Input</label>
<input id="numberInput" class="ogInputNumber" type="number" value="3.1416" />
</p>
Javascript
// Checks number input fields for proper formatting
require(["dojo/domReady!", "dojo/on", "dojo/query"],
function (ready, on, query) {
query(".ogInputNumber").forEach(function (node) {
var validValue = this.value;
// Replace all the non-numeric, non-period, and non-hyphen characters with nothing while the user is typing
on(node, "input, keyup", function () {
if (this.value == '' && validValue.length > 1) {
this.value = validValue;
}
this.value = this.value.replace(/[^\d\.-]/g, '');
validValue = this.value;
});
// When the user leaves the input, format it properly as a signed float (or zero if it's something weird)
on(node, "blur", function () {
try {
if (this.value) {
this.value = parseFloat(this.value).toString();
} else {}
} catch (error) {
this.value = 0;
}
});
});
});

how to validate the below criteria on the text fields and display the pop up page on satisfying all the condition using javascript validation

**Below is the input text fileds**
<form:form commandName="DRCNdetails" id="frm1" method="POST" action="addNewDelayReason.do" >
<form:input id="text1" path="delayCategory" cssClass="padR10 boxSizing" maxlength="75"></form:input>
<form:input path="preFix" id="text2" cssClass="padR10 boxSizing" maxlength="6"> </form:input>
<form:input path="reasonValue" maxlength="150" id="reasonValue" cssClass="textbox width100" cssStyle="visibility:hidden"></form:input>
</form:form> <button class="btnStyle blueBtn" onclick="formvalidation(),validateSpecialCharacters()"> <span class="left">
Submit
on submit need to vaidate the id's "text1","text2" fileds , on successful validation should display the below pop up screen that is showLtBox('mask', 'addMisdReasonCode1'), the conditions are below:
should not allow the null values for both the fileds, and special characters,and integers and alert me accordingly , on satisying this criteria only it should display the pop up screen showLtBox('mask', 'addMisdReasonCode1')
As far as I understand the question, you need to create a validation function that would be triggered upon pressing the submit button.
I already see that you have created to function that would be triggered on "OnClick" operation, However the syntax is incorrect.
You need to separate between the two function using ";" and not ","
You need to use only one function for validation - this would be more readable than the code you have written.
The result should be returned to the onclick command.
Example:
change the attribute onclick as follows:
onclick="return FullValidation();"
Create new JavaScript function that includes the two validations and return validation result;
function FullValidation() {
var validationResultOK = formvalidation();
if (validationResultOK) {
validationResultOK = validateSpecialCharacters();
}
if (validationResultOK) {
// Popup alert should be here, I put alert as example.
alert("Out your message here");
}
return validationResultOK;
}
Use Javascript Regular expression..
var pattern = new RegExp(/^[a-zA-Z]{n}$/);
where n is number of charecters you want to accept.
the above regular expression matches only charecters(both cases).
Now retrieve the value from your text fields
var text1 = document.getElementById("#your_id").value;
var text2 = document.getElementById("#your_id").value;
if(pattern.test(text1) && pattern.test(text2))
{
// your popup code
}

Categories

Resources