I am trying to format an <input> box using javascript / jquery.
The Goal - As the user types, add hyphens automatically after every third character.
123123123 becomes 123-123-123
I have a working code, but it is super slow and clunky. I am looking for recommendations on how to improve the code
$('#serial').keyup(function(){
$(this).val( $(this).val().trim() );
var str = $(this).val();
var newStr = str.replace(/-/g, "");
var valuesArray = newStr.split("");
var newVal = "";
while ( i = valuesArray.shift() ){
if(newVal.length === 3){
newVal += "-";
} else if (newVal.length === 7){
newVal += "-";
}
newVal += i;
}
$(this).val(newVal);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<label for="serial">Type something magical</label>
<input type="text" id="serial" name="serial">
Use input event istead of keyup it's very useful to track input fields changes :
$('#serial').on('input', function(){
NOTE : The code seems slow because keyup won't fire until you release the key, but you can type the next character before releasing the first.
Hope this helps.
Update :
You don't need any loop here, you can use substr to cut your string and insert the separator - and use maxlength to define the max number of charaters you want to contain your serial :
$('#serial').on('input', function()
{
var input_value = $(this).val().trim().replace(/-/g, "");
if(input_value.length > 3){
input_value = input_value.substr(0, 3) + '-' + input_value.substr(3);
}
if (input_value.length > 7){
input_value = input_value.substr(0, 7) + '-' + input_value.substr(7);
}
$(this).val(input_value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="serial" name="serial" maxlength="11">
try this code, replaced inefficient regex with substring
$('#serial').input(function(){
$(this).val( $(this).val().trim() );
var str = $(this).val().trim().split( "-" ).join("");
var output = "";
while ( str.length > 3 )
{
output += str.substring(0,3) + "-";
str = str.substring(3);
}
output += str;
$(this).val(output);
});
A little further optimization
$('#serial').on('input', function() {
var str = $(this).val().trim();
var i = 3;
while (i < str.length) {
if (str.charAt(i) == '-') {
i += 4;
} else {
str = str.slice(0, i) + '-' + str.charAt(str.length-1);
}
}
$(this).val(str);
});
jsfiddle https://jsfiddle.net/h5hdvcwu/1/
Related
I have this scripts that works. As of now it changes the image correctly for the last set, I want to put it in a loop where I have m=k, but it does not work
like
for (m = 0; m < k; ++m) {
<script>
$(function() {
var m = 1;
var resultb = $('[id^=input_]').filter(function () {
return this.id.match(/input_\d+$/); //regex for the pattern "input_ followed by a number"
}).length;
var k = resultb;
m = k;
$("#input_"+m).change(function() {
var val = $("#input_"+m+" option:selected").text();
var valval = $("#input_"+m+"option:selected").val();
var n = val.indexOf('(');
val = val.substring(0, n != -1 ? n : val.length);
var img_option='images/sample/'+val+'.jpg';
if ($("#input_"+m+" option:selected").val() > 0)
$("a.lb:first").html( "<img src="+ img_option+">");
$('a.lb:first img').css({'width' : '350px' });
$('a.lb:first img').addClass( "img-fluid" );
});
});
</script>
Your m values appear to be 1-based, so your loop will want to start at 1.
That being said, you don't need a for loop at all. Just select the elements you want:
$(function() {
const inputs = $('[id^=input_]').filter(function () {
return this.id.match(/input_\d+$/); //regex for the pattern "input_ followed by a number"
});
inputs.on('change', function() {
// I'm assuming that `#input_X` is actually a `<select>`, not an `<input>`
// You should probably adjust your naming convention to be less confusing
let text = this.options[this.selectedIndex].text;
let value = this.options[this.selectedIndex].value;
let parenthesis = text.indexOf("(");
if( parenthesis > -1) text = text.substring(0, parenthesis);
let source = `images/sample/${text}.jpg`;
if( value > 0) $("a.lb:first").html(`<img src="${source}" style="width: 350px" class="img-fluid" />`);
});
});
You'll notice I've given your variables more reasonable names, used let and const as somewhat more appropriate, and just generally tidied the code up to be as clean and understandable as possible.
I've seen similar questions asked on Stack Overflow regarding this topic, but I haven't seen anything specific that would help me. My issue is that I can't seem to figure out how to replace a dash in hiddenWord with a correctly guessed letter while still retaining the dashes for un-guessed letters. Here is what I have so far and I'm not even sure if it's on the right track.
<script type="text/javascript">
// Declaration of Variables
var wordPool= ["Alf", "MarriedWithChildren", "Cheers", "MASH", "CharlesInCharge", "FmailyTies", "KnightRider", "MagnumPI", "MiamiVice"];
var lives = 6;
var myLetter;
var letter;
var wordChoice;
var hiddenWord;
var i;
var enter;
// Selects word randomly from wordPool[]. Then replaces the letters with "- ".
function selectedWord() {
var number = Math.round(Math.random() * (wordPool.length - 1));
wordChoice = wordPool[number];
for(i = 0; i < wordChoice.length; i++){
hiddenWord = wordChoice.replace(/./g,"- ");
}
console.log(hiddenWord);
}
// Gives myLetter a value of key pressed. If key is "Enter" selectedWord() initiates
document.onkeyup = function(event) {
var myLetter = event.key;
if(myLetter === "Enter"){
selectedWord();
}
console.log(myLetter);
}
</script>
I have seen some stuff with jQuery and PHP but I have to do it in javascript for class. Any help would be appreciated and if this has been addressed before please let me know.
You can check each character at the word string, compare it with the chosen character and replace it, if it is the same character.
I changed your code a bit to reflect what you are looking for.
Also make sure to lowercase all characters to make it easier for the player.
// Declaration of Variables
var wordPool= ["Alf", "MarriedWithChildren", "Cheers", "MASH", "CharlesInCharge", "FmailyTies", "KnightRider", "MagnumPI", "MiamiVice"];
var lives = 6;
var myLetter;
var letter;
var wordChoice;
var hiddenWord;
var i;
var enter;
// Change character to selected one
function checkCharacter(n) {
for(i = 0; i < wordChoice.length; i++){
console.log(wordChoice[i].toLowerCase() + "==" + n);
if(wordChoice[i].toLowerCase() == n.toLowerCase()){
hiddenWord = setCharAt(hiddenWord,i,n);
}
}
console.log("[" + hiddenWord + "]");
}
function setCharAt(str,index,chr) {
if(index > str.length-1) return str;
return str.substr(0,index) + chr + str.substr(index+1);
}
// Selects word randomly from wordPool[]. Then replaces the letters with "- ".
function selectedWord() {
var number = Math.round(Math.random() * (wordPool.length - 1));
wordChoice = wordPool[number];
hiddenWord = wordChoice.replace(/./gi,"-");
console.log(wordChoice + "[" + hiddenWord + "]");
}
// Gives myLetter a value of key pressed. If key is "Enter" selectedWord() initiates
document.onkeyup = function(event) {
var myLetter = event.key;
if(myLetter === "Enter"){
if(lives == 0){
selectedWord();
lives = 6;
}else{
lives--;
}
}
console.log(myLetter);
checkCharacter(myLetter);
}
//Select a random word at start
selectedWord();
I made a JSfiddle that is working and playable:
Check it out here...
Try
hiddenWord += "- "
Instead of replace
Or
hiddenWord += wordChoice[i].replace(/./g,"- ");
Here's an example:
var word = "do this";
var displayWord = [];
for (var i = 0; i < word.length; i++) {//build array
if (word[i] === " ") {
displayWord.push(" ");
} else {
displayWord.push("-");
}
}
function update(userGuess) {//update array
for (var i = 0; i < word.length; i++) {
if (word[i] === userGuess) {
displayWord[i] = userGuess;
} else {
displayWord[i] = displayWord[i];
}
}
}
//Guess letters
update("h");
update("o");
displayWord = displayWord.join('');//convert to string
alert(displayWord);
Check out the pen - https://codepen.io/SkiZer0/pen/VbQKPx?editors=0110
I am trying to create a function that auto formats the text box as the user is typing in their Canadian Postal Code.
This is my original function, but the problem is that it doesn't catch if the person writes in the wrong format.
EX. AA1 10A when it should always be in the format of A0A 0A0.
$("#tbPostalCode").on("change keyup paste", function(){
var output;
var input = $(this).val();
input = input.replace(/[^a-zA-Z0-9]/g, '');
input = input.toUpperCase();
var front = input.substr(0, 3);
var end = input.substr(3, 5);
if (front.length < 3) {
output = front;
} else if (front.length == 3 && end.length < 3) {
output = front+ " " + end;
} else if (front.length == 3 && end.length == 3) {
output = front+ " " + end;
}
$(this).val(output);
});
This is what I have been trying to make work. To basically split the string and replace the specific spots of the index according to the regEx requirements. So I am just trying to figure out how to make this work.
$("#tbPostalCode").on("change keyup paste", function(){
var output;
var input = $(this).val();
input = input.splice("");
input[1,4,6] = input.replace(/[^0-9]/g, '');
input[0,2,5] = input.replace(/[^a-zA-Z]/g,'');
input = input.toUpperCase();
var front = input.substr(0, 3);
var end = input.substr(3, 5);
if (front.length < 3) {
output = front;
} else if (front.length == 3 && end.length < 3) {
output = front+ " " + end;
} else if (front.length == 3 && end.length == 3) {
output = front+ " " + end;
}
$(this).val(output);
});
Code Block 1 Fiddle: https://jsfiddle.net/jessica_mather123/730gj842/7/
Code Block 2 Fiddle: https://jsfiddle.net/jessica_mather123/f21sx97j/
This is the RegEx I want it to follow:
[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d
Debuggex Demo
HTML5 input validation handles this pretty well across browsers. Automatically deleting input without providing notice as to what is going on makes for a confusing UI experience. Try HTML input/form validation. You can plug your regex right in there...
HTML Code
<textarea id="test"></textarea>
<button id="button_test">Ok</button>
Javascript
$(document).ready(function()
{
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
});
$("#button_test").on("click",function()
{
var as=document.getElementById("test").value;
console.log(as);
});
We can get the values from textarea line by line using val and split functions. But
Is it possible to get the value from textarea line by line for very long word?.In the example i need to get the output as 123e2oierhqwpoiefdhqwo and pidfhjcospid as separate values.
Jsfiddle link here
You can use something like this. This will insert line breaks into into the textarea.
Credits: https://stackoverflow.com/a/4722395/4645728
$(document).ready(function() {
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
});
$("#button_test").on("click", function() {
ApplyLineBreaks("test");
var as = document.getElementById("test").value;
console.log(as);
});
//https://stackoverflow.com/a/4722395/4645728
function ApplyLineBreaks(strTextAreaId) {
var oTextarea = document.getElementById(strTextAreaId);
if (oTextarea.wrap) {
oTextarea.setAttribute("wrap", "off");
} else {
oTextarea.setAttribute("wrap", "off");
var newArea = oTextarea.cloneNode(true);
newArea.value = oTextarea.value;
oTextarea.parentNode.replaceChild(newArea, oTextarea);
oTextarea = newArea;
}
var strRawValue = oTextarea.value;
oTextarea.value = "";
var nEmptyWidth = oTextarea.scrollWidth;
var nLastWrappingIndex = -1;
for (var i = 0; i < strRawValue.length; i++) {
var curChar = strRawValue.charAt(i);
if (curChar == ' ' || curChar == '-' || curChar == '+')
nLastWrappingIndex = i;
oTextarea.value += curChar;
if (oTextarea.scrollWidth > nEmptyWidth) {
var buffer = "";
if (nLastWrappingIndex >= 0) {
for (var j = nLastWrappingIndex + 1; j < i; j++)
buffer += strRawValue.charAt(j);
nLastWrappingIndex = -1;
}
buffer += curChar;
oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
oTextarea.value += "\n" + buffer;
}
}
oTextarea.setAttribute("wrap", "");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<textarea id="test"></textarea>
<button id="button_test">Ok</button>
Use .match(/pattern/g). As your OP ,pattern should start \w (Find a word character) and match string sequence {start,end}
$("#button_test").on("click",function()
{
var as=document.getElementById("test").value;
console.log(as.match(/(\w{1,22})/g));
});
If you made the textarea width fixed using css you could do this:
css
textarea { resize: vertical; }
javascript
$("#button_test").on("click",function(){
var as=document.getElementById("test").value;
var len = document.getElementById("test").cols;
var chunks = [];
for (var i = 0, charsLength = as.length; i < charsLength; i += len) {
chunks.push(as.substring(i, i + len));
}
console.log(chunks);
});
This is probly not the best way, but it works and i hope it could help you.
First thing, i found the textarea allow 8px for default fontsize charactere.
Exemple :
Textarea with 80px
=> Allow line with 10 char maximum, all other are overflow on new line.
From this you can do a simple function like this :
$("#button_test").on("click",function()
{
console.clear();
var length_area = $("#test").width();
var length_value = $("#test").val().length;
var index = Math.trunc(length_area/8);
var finalstr = $("#test").val().substring(0, index) + " " + $("#test").val().substring(index);
console.log(finalstr);
});
Here the JSFiddle
The <textarea> element has built in functionality to control where words wrap. The cols attribute can be set (either harded coded in the HTML or set with the .attr() method using jQuery). The attribute extends the text area horizontally and it also automatically wraps text at the set value.
Example jsFiddle
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
var newString = $("#test").val().toString();
var splitString = parseInt($("#test").attr("cols"), 10) + 1;
var stringArray = [];
stringArray.push(newString);
var lineOne = stringArray[0].slice(0, splitString);
var lineTwo = stringArray[0].slice(splitString);
var lineBreakString = lineOne + "\n" + lineTwo;
console.log(lineTwo);
$('#test').after("<pre>" + lineBreakString + "</pre>");
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
var newString = $("#test").val().toString();
var splitString = parseInt($("#test").attr("cols"), 10) + 1;
var stringArray = [];
stringArray.push(newString);
var lineOne = stringArray[0].slice(0, splitString);
var lineTwo = stringArray[0].slice(splitString);
var lineBreakString = lineOne + "\n" + lineTwo;
$('#test').after("<pre>" + lineBreakString + "</pre>");
//console.log(lineBreakString);
pre {
color: green;
background: #CCC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<textarea id="test" cols='21'></textarea>
<button id="button_test">Ok</button>
The example addresses the specific question asked. If you want to deal with larger blocks of text, you should use the .each() method and for loops to iterate over each line break.
Documentation:
.slice()
textarea
.push()
.parseInt()
.attr()
I have searched too much on same topic but not is perfect for what I am looking for.
I have a string like :
var string ='<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>'
Now what I want is to substring it with limit with javascript substring function but don't want tags to be cut in middle like for example
<strong><span>Hii </span> <p
It should be like
<strong><span>Hii </span> <p>
I am using
string.substr(0,200)
string is dynamic variable with html tags
My solution:
function smart_substr(str, len) {
var temp = str.substr(0, len);
if(temp.lastIndexOf('<') > temp.lastIndexOf('>')) {
temp = str.substr(0, 1 + str.indexOf('>', temp.lastIndexOf('<')));
}
return temp;
}
http://jsfiddle.net/8t6fs67n/
Its not elegant but it works, will increase the characters to include the next closing tag
https://jsfiddle.net/q680vors/
Just change length to the required number of characters.
var string ='<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>';
var length = 2;
var openTag = 0, closeTag = 0,i=0;
for(i; i<length; i++)
{
if(string[i] == "<")
openTag++;
if(string[i] == ">")
closeTag++;
}
if(openTag > closeTag)
{
while(string[i] != ">")
i++;
}
var newString = string.substring(0,(i+1));
alert(newString);
I don't see reason to do so, but theoretically something like this:
function substrWithTags(str, len) {
var result = str.substr(0, len),
lastOpening = result.lastIndexOf('<'),
lastClosing = result.lastIndexOf('>');
if (lastOpening !== -1 && (lastClosing === -1 || lastClosing < lastOpening)) {
result += str.substring(len, str.indexOf('>', len) + 1);
}
return result;
}
var s = '<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>'
// <strong><span>Hii </span> <p>this is just a demo <spa
s.substr(0, 53);
// <strong><span>Hii </span> <p>this is just a demo <span>
substrWithTags(s, 53);
I think my function is more accurate when it comes to being more sensitive on the content syntax. If your substring length cuts a word in half for example, the word will be included fully.
function HTML_substring(string, length) {
var noHTML = string.replace(/<[^>]*>?/gm, ' ').replace(/\s+/g, ' ');
var subStringNoHTML = noHTML.substr(0, noHTML.indexOf(" ", length));
var words = subStringNoHTML.split(" ");
var outPutString = "";
var wordIndexes = [];
words.forEach((word, key) => {
if (key == 0) {
outPutString += string.substr(0, string.indexOf(word) + word.length);
wordIndexes[key] = string.indexOf(word) + word.length;
} else {
let i = wordIndexes[key - 1];
outPutString += string.substring(i, string.indexOf(word, i) + word.length);
wordIndexes[key] = string.indexOf(word, i) + word.length;
}
});
return outPutString;
}
If I understood you correctly, you want to to do something like this?
var limit = 28;
var test = '';
var string = '<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>';
do {
test = string.substring(0,limit);
limit++;
} while(test.charAt(test.length-1) !== '>');
test will be equal to '<strong><span>Hii </span> <p>'
or will ends with any another closing tag which is above your limit
Well, I did a function:
function my_substring (str) {
var answer = [], x;
for (var i=0, l=str.length; i<l; i++) {
x = i;
if (str[i] == '<') {
while (str[++i] != '>');
answer.push( str.substring(x, i+1) );
}
else {
while (++i < l && str[i] != '<');
answer.push( str.substring(x, i) );
i--;
}
}
return answer;
}
var string =
"<strong><span>Hii </span> <p>this is just a demo <span>string<span></p></strong>"
console.log ( my_substring(string) );
This code will output:
["<strong>",
"<span>",
"Hii ",
"</span>",
" ",
"<p>",
"this is just a demo ",
"<span>",
"string",
"<span>",
"</p>",
"</strong>"
]
Then you can select what you want in the array. Hope it helps.