String replace replacing wrong part - javascript

I have an image with a couple of arrows either side to increment/decrement the image filename. Here's the left arrow code:
$('#sidebar-b').on("click", "#lar", function() {
var num = parseInt($('#main-img').attr('src').match(/(\d+)/)[1], 10);
if (num > 1) {
$('#main-img').attr('src', $('#main-img').attr('src').replace(/\d+/, function(val) {
return parseInt(val)-1
}));
}
});
And the right is very similar.
$('#sidebar-b').on("click", "#rar", function(){
var num = parseInt($('#main-img').attr('src').match(/(\d+)/)[1], 10);
if (num < $('#scroller').children().length) {
$('#main-img').attr('src',$('#main-img').attr('src').replace(/\d+/, function(val) {
return parseInt(val)+1
}));
}
});
Works excellent when the images are in "images/" but if they are in "images/h3/" or any directory with a number, every time I click the arrows it simply increments the directory name instead (images/h3/1.jpg, images/h4/1.jpg etc.)
This is obviously no good.
Tried changing the regex, probably be better if it selected characters after the last / or before a period.
Could maybe even use id.lastIndexOf('/')?
I've been coding all day and my brain is just fried at the moment, so I'm going to give my eyes a rest and have a cup of tea.
Hopefully one of you amazing people will point out the obviousness of where I am going wrong.
Currently everything just looks like scrambled digits to me and I can't see the wood for the trees!

You don't really need regex in this case:
$('#sidebar-b').on("click", "#lar", function() {
var s = $('#main-img').attr('src') ;
var slashI = s.lastIndexOf('/'),
dotI = s.lastIndexOf('.') ;
var num = parseInt(s.substring(slashI + 1, dotI)) ;
if (!isNaN (num)) {
$('#main-img').attr('src', s.substring(0, slashI + 1) + (num - 1) + s.substring(dotI));
}
});

You need to use a positive lookahead based regex. Now this would increments the number which exists only before to the extension.
$('#sidebar-b').on("click", "#lar", function(){
var num = parseInt($('#main-img').attr('src').match(/(\d+)(?=\.[^\/.]*$)/)[1], 10);
if (num > 1) {
$('#main-img').attr('src',$('#main-img').attr('src').replace(/\d+(?=\.[^\/.]*$)/,
function(val) { return parseInt(val)-1}));
}
});

Try .match with RegExp /\d+\./
var url = "images/h4/1.jpg";
console.log(parseInt("images/h4/1.jpg".match(/\d+\./), 10));

Related

How to create number suffixes such as "100K" without having to be repetitive?

I've been having a problem that when my auto clicker in my clicker game goes fast enough to get to 200 thousand, it starts to lag, and then it doesn't function properly, or as fast.
Is there a way to make 100 thousand turn into 100K, and 101 thousand turn into 101K without being repetitive?
I tried this with my original code, and realized putting up to 1000 suffixes into each function would be a little too hard:
if (number >= 100000) {
document.getElementById(ID).innerHTML = "100K"
}
if (number >= 101000) {
document.getElementById(ID).innerHTML = "101K"
}
and on and on.
I don't want multiple if statements!
This would work, but it would take up way too much space, and I know there is an easier way to it, but I just couldn't find it. Can anyone provide a way to do this?
Try separating the job of formatting your number into a different function.
SUFFIXES = 'KMBTqQsSOND' // or whatever you'd like them to be
function getSuffixedNumber(num) {
var power = Math.floor(Math.log10(num));
var index = Math.floor(power / 3);
num = Math.round(num / Math.pow(10, (index * 3))); // first 3 digits of the number
return num + (SUFFIXES[index - 1] || ''); // default to no suffix if we get an out of bounds index
}
You can call the function like this: var x = getSuffixedNumber(101000), the value of x will be "101K".

Validate range inputs are not overlapping

I'm trying to validate that two range inputs who filter age do not go over one another. I can't find a way to have it done properly without the sliders behaving erratically, jumping from 0 to 50, and things like that.
I've tried different approaches (pure JS) with similar results:
if(input1.value >= input2.value || input2.value <= input1.value){
input1.value = toString(input2.value - 1);
input2.value = toString(input1.value + 1);
}
This one makes the sliders jump back to 50. I can't remember what else I've tried, but all do sort of the same thing. Either jump back to 50, or the minimumRange jump from 2 or 3 to 100.
I'd rather not use jQuery if at all possible
Here's the fiddle with the whole thing:
JSfiddle Validation and filters
Thank you!
This is how the function looks like now:
function filtroEdad(input1, input2) {
var edadMin = Number(input1.value);
var edadMax = Number(input2.value);
if(edadMin >= edadMax){
input1.value = (edadMax - 1).toString();
}
if(edadMax <= edadMin){
input2.value = (edadMin + 1).toString();
}
Thank you, #RaphaMex !!
Can't reproduce your issue in your fiddle, but I already see 2 issues in your code:
if input1.value is "50", then input1.value + 1 will be "501"
toString() should be called on numbers: 50.toString()
So your code should look like:
var minEdad = Number(input1.value),
maxEdad = Number(input2.value);
if(minEdad >= maxEdad) {
// Decide here what to do, for example
input1.value = (maxEdad - 1).toString();
}

Javascript/JQuery Regex remove spaces, parenthesis, periods, minus in link only

I have gotten this far thanks to a lot of searching, but I am stuck on a way to format the link only and not the text. I would like the link to have the numbers in the text, but without spaces, parenthesis, periods or the minus symbol and leave the text as is. The link should have as an example 555 123-1234
<div id="phonedirectory">
<ul>
<li>Phone 1 - 555 123-1234</li>
<li>Phone 2 - 555.123.4321</li>
<li>Phone 3 - (555) 123-6789</li>
</ul>
</div>
<script type="text/javascript">
//<![CDATA[
$(window).load(function(){
var regex = /\(?\d{3}\)?[-.\s]\d{3}[-.\s]\d{4}/g;
var text = $("body:first").html();
text = text.replace(regex, "$&");
$("body:first").html(text);
});
//]]>
</script>
Anyone have any ideas?
Whatever you do, don't (!) regex-replace the entire HTML of your page. Ever. This is asking for trouble.
The correct approach is more complicated. But in return it's... well... correct.
var phonePattern = /\(?\d{3}\)?[-.\s]\d{3}[-.\s]\d{4}/g,
phoneReplacement = '$&';
function replacePhoneNumbers(container) {
$(container).contents(":not(a)").each(function () {
var $this = $(this);
if (this.nodeType === 3) {
$(this).replaceWith( $this.text().replace(phonePattern, phoneReplacement) );
} else {
return replacePhoneNumbers(this);
}
});
}
$(function () {
replacePhoneNumbers(document.body);
});
The function is recursive. It inspects the entire container you give it (document.body in this case) and replaces text nodes specifically (nodeType === 3) but only if they are not already part of a link.
This way only those parts of the document are treated that acutally need treatment. The rest of the document is kept unchanged. No re-renders occur, no layout changes and no risk of breaking the document tree if you mess up the regular expression.
You can even roll that into a jQuery plugin if you want.
$.fn.extend({
phonelinkify: function (pattern, replacement) {
return this.contents().each(function () {
var $this = $(this);
if (this.nodeType === 3 && $this.parents("a").length === 0) {
$(this).replaceWith( $this.text().replace(pattern, replacement) );
} else {
return $(this).phonelinkify(pattern, replacement);
}
});
}
});
and
$(function () {
$("#phonedirectory").phonelinkify(/\(?\d{3}\)?[-.\s]\d{3}[-.\s]\d{4}/g, '$&');
});
To make a more custom replacement, change the phoneReplacement variable to a function.
phoneReplacement = function (num) {
return '' + num + '';
};
This will turn Phone 3 - (555) 123-6789 into
Phone 3 - (555) 123-6789
This works with both the original and the plugin version of this answer. Read up on .replace() to understand how passing functions as a replacement works.
Disclaimer: Whether the regular expressions in use here are completely appropriate for phone number matching or not (I very much doubt they are) is beyond the scope of this answer.
Honestly I would do this without using a regex.
var numOnly = function (inputString) {
var validChars = "0123456789";
var outputString = '';
var len = inputString.length;
for (var i = 0; i < len; i++) {
if (validChars.indexOf(inputString[i]) > -1) {
outputString += inputString[i];
}
}
return outputString;
}
var phoneNumber = numOnly(phoneNumberString);
Are you trying to do this?
$('li').html(function (i, html) {
var text = html.split(' - ').slice(1).join(' - '),
num = text.match(/\d+/g).join('');
return '' + text + '';
});

replace each selected value with random letter/number

So I'm wondering how can I for example go over each specific text or number I've set and change them. For example I have:
0000-0000
and I want to replace each 0 with some input I've set. For Example:
1111-1111
I'm trying create random serial code kind of script so I'd just like to start of by how to do that.
Thanks in advance.
Edit: So this is how I would generate the random number or letter, just gotta go trough each zeros to replace them with random value:
jQuery(document).ready(function ($) {
function randomAlphaNumber() {
var values = "abcdefghijklmnopqrstuvwxyz0123456789";
rN = values.charAt(Math.floor(Math.random() * values.length));
return rN;
}
$(".combination").html(randomAlphaNumber());
});
At its simplest I'd suggest:
function randomiseString(str){
var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
var _str = str.replace(/[^-]/g,function(a){
return chars[Math.floor(Math.random() * chars.length)];
});
return _str;
}
$('.combination').text(function(i,t){
return randomiseString(t);
});
JS Fiddle demo.
If you also want to use upper, and lower, case letters:
function randomised(len) {
return Math.floor(Math.random() * len);
}
function randomiseString(str){
var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
var _str = str.replace(/[^-]/g,function(a){
return chars[randomised(chars.length)][randomised(2) == 0 ? 'toUpperCase' : 'toLowerCase']();
});
return _str;
}
$('.combination').text(function(i,t){
return randomiseString(t);
});
JS Fiddle demo.

Adding characters to string (input field)

I have a text box where the value is the result of a calculation carried out in jQuery. What I would like to do, using jQuery, is to display brackets around the number in the text box if the number is negative.
The number may be used again later so I would then have to remove the brackets so further calculations could be carried out.
Any ideas as to how I could implement this?
Thanks
Zaps
function FormatTextBox(id) {
var txtBox = $(id).val();
//strip bracket to get the number only
txtBox = txtBox.replace("[", "").replace("]", "");
var val = parseFloat(txtBox);
if (val < 0) {
txtBox.val("[" + val + "]");
} else {
txtBox.val(val);
}
return val;
}
First, store your calculation in a variable. You shouldn't be using the DOM to store data (in most cases). This basically eliminates your problem.
Number.prototype.bracketed = function() {
if(this < 0) {
return '[' + -this + ']';
} else {
return '' + this;
}
};
var result = do_calculation();
myTextBox.value = result.bracketed();
// result still holds the original Number value.
If you really want to store the data as the .value of the text input, you can make an unbracketed function as well:
String.prototype.unbracketed = function() {
var parts = this.match(/^\[([0-9]+)\]$|^([0-9]+)$/); // [number] or number
if(parts[1]) { // [number]
return -parseInt(parts[1], 10);
}
if(parts[2]) { // number
return parseInt(parts[2], 10);
}
return NaN;
};
Assuming you might have multiple fields (and you don't want the negative sign):
jQuery('input').each(function(){
if(jQuery(this).val() < 0 ){
jQuery(this).val('['+-1*jQuery(this).val()+']');
}
}
)
Then when you grab the value again, just strip the brackets and multiply by -1 to make it negative.
EDIT:
You can also use jQuery('input').data() to store the original number so you don't have to parse it again. (read more: http://api.jquery.com/data/ )

Categories

Resources