Javascript replace works in console, not in code - javascript

I've been trying to setup a small booking system however I'm stuck. Basically, I add all the seat numbers that want to be booked into a string eg (a22~b20~f10). However when a seat is deselected it needs to be removed from the string. I have tried using .replace but to no avail, even in the console.
I then tried the code below. It works brilliantly in the console, but not at all in my code.
seatNumbersToBook.split(seatNumber+"~").join("");
The full function is here
var seatNumbersToBook = "";
function calcSeats(calc, seatNumber){
if(amountSeatsToBeBooked != 0 && seatNumber != "NaN" && calc == "-1"){
seatNumbersToBook = seatNumber + "~" + seatNumbersToBook;
}
if(calc == "+1"){
//remove from seatNumbersToBook array
seatNumbersToBook.split(seatNumber+"~").join("");
console.log(seatNumber);
}
// despite removing seat number from array, still MUST check in array to see if the seatnumber has already been recorded
amountSeatsToBeBooked = eval(amountSeatsToBeBooked + calc);
$("#remainingSeatsToBeBooked").html(amountSeatsToBeBooked);
console.log(seatNumbersToBook);
return amountSeatsToBeBooked;
}
Thanks a lot in advance!!

You do the split() then join() but don't assign the result back to seatNumbersToBook, so seatNumbersToBook is still old value

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join
String.prototype.split() and Array.prototype.join() does not change the string or array itself but returns a new string or array

Related

How to access the first two digits of a number

I want to access the first two digits of a number, and i have tried using substring, substr and slice but none of them work. It's throwing an error saying substring is not defined.
render() {
let trial123 = this.props.buildInfo["abc.version"];
var str = trial123.toString();
var strFirstThree = str.substring(0,3);
console.log(strFirstThree);
}
I have tried the above code
output of(above code)
trial123=19.0.0.1
I need only 19.0
How can i achieve this?
I would split it by dot and then take the first two elements:
const trial = "19.0.0.1"
console.log(trial.split(".").slice(0, 2).join("."))
// 19.0
You could just split and then join:
const [ first, second ] = trial123.split('.');
const result = [ first, second ].join('.');
I have added a code snippet of the work: (explanation comes after it, line by line).
function getFakePropValue(){
return Math.round(Math.random()) == 0 ? "19.0.0.1" : null;
}
let trial123 = getFakePropValue() || "";
//var str = trial123.toString();
// is the toString() really necessary? aren't you passing it along as a String already?
var strFirstThree = trial123.split('.');
//var strFirstThree = str.substring(0,3);
//I wouldn't use substring , what if the address 191.0.0.1 ?
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
Because you are using React, the props value was faked with the function getFakePropValue. The code inside is irrelevant, what I am doing is returning a String randomly, in case you have allowed in your React Component for the prop to be empty. This is to show how you an create minimal robust code to avoid having exceptions.
Moving on, the following is a safety net to make sure the variable trial123 always has a string value, even if it's "".
let trial123 = getFakePropValue() || "";
That means that if the function returns something like null , the boolean expression will execute the second apart, and return an empty string "" and that will be the value for trial123.
Moving on, the line where you convert to toString I have removed, I assume you are already getting the value in string format. Next.
var strFirstThree = trial123.split('.');
That creates an array where each position holds a part of the IP addrss. So 19.0.0.1 would become [19,0,0,1] that's thanks to the split by the delimiter . . Next.
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
This last piece of code uses the conditional if to make sure that my array has values before I try to splice it and join. The conditional is not to avoid an exception, since splice and join on empty arrays just returns an empty string. It's rather for you to be able to raise an error or something if needed. So if the array has values, I keep the first two positions with splice(0,2) and then join that array with a '.'. I recommend it more than the substr method you were going for because what if you get a number that's 191.0.0.1 then the substr would return the wrong string back, but with splice and join that would never happen.
Things to improve
I would strongly suggest using more human comprehensible variables (reflect their use in the code)
The right path for prop value checking is through Prop.Types, super easy to use, very helpful.
Happy coding!

JS Check Jquery inArray

I would like to use a onchange state on a select element to check if the value of the select is in an array.
I tried this :
function statutEmployeur(){
statliste = [];
statliste.push(1);
statliste.push(2);
statliste.push(5);
statid = jQuery("#statut").val();
if(jQuery.inArray(statid,statliste)>-1){
alert('inside array');
}else {
alert('outside array');
}
}
Each value that I tried are outside of the array.
Anybody can help me ?
Thanks
as pointed out by Stryner in the comments, try running your .val() through parseInt() to ensure you nave a numerical value (and not a string)
statid = jQuery("#statut").val();
to:
statid = parseInt(jQuery("#statut").val(), 10);
working fiddle: http://jsbin.com/maqesupuka/edit?html,js,console,output
the problem is you're searching in the array for a type of string (default type of inputs), but your array only contains numbers. You could either make your array into numbers, or do a type conversion like above to ensure you're working with the same type.

What's wrong with my delete button on my HTML/Javascript calculator

I'm trying to make a simple calculator using HTML, CSS, and Javascript. I'm done with the calculation part and the design but I'm having a hard time with my DEL button. My DEL button is supposed to backspace the last key pressed on the calculator.
I made a function called del() on my .js and this is what it looks like so far:
function del()
{
document.getElementById("dis").value = (document.getElementById("dis").value.getLength) - 1;
}
"dis" is the id of my calculator's display.
try this one
var val = document.getElementById("dis").value;
if(val.length > 0){
val = val.substring(0, val.length - 1);
document.getElementById("dis").value = val;
}
Because your code is setting the display's value to:
(document.getElementById("dis").value.getLength) - 1
Which is the number of digits (string length) of the displayed value minus one, so if the value was "500", it would set it to 2 (3-1). Clearly not what you want.
What you want is to get the value, cut it down to just the characters you want (probably with substr()) and then re-set the value to that string.
.getlength is undefined. If you want the length of the string, you should use str.length. Anyway, if you want to remove the last character, use this
str=str.substr(0,-1);
or, for your code
document.getElementById("dis").value = document.getElementById("dis").substr(0,-1);
you need to use String operations...MDN
something like this should work:
document.getElementById("dis").value = document.getElementById("dis").value.slice(0, -1)

Custom function for Google Spreadsheet - handling the array passed from the spreadsheet

I am trying to build a simple script to work with a Google Spreadsheet. The spreadsheet takes input from a Google Form, so there is a series of values in the spreadsheet like this:
My goal is to write a script that would strip the number from each form input in a user-specified range, then add all the numbers to provide a single score. So, for example, the user could type =sumColumns(H2:K2) in a cell, and it would return the sum of the scores (for the sample screenshot I posted, it would return the result of 3+3+0+3, 9).
Here is the code that I wrote to do this:
function sumColumns(values) {
var sum = 0;
for(var i = 0; i <= values.length; i++){
var input = values[0][i];
var x = input.toString();
var y = x.charAt(0);
var num = parseInt(y);
sum += num;
}
return sum;
}
The problem is that it only ever seems to add two values together. So, when I put =sumColumns(H2:K2) in a cell in the spreadsheet, it only returns 6. Also, on line 3, if I change it from i <= values.length to i < values.length it only adds one number, so that I get 3 as a result. My guess is that I am misunderstanding the way that the Google Spreadsheet values are passed to the function, but I have been completely unable to make it work. I'd really appreciate any help!
Oops - edited & saved the question, wrote an answer - and forgot to save it. I let Serge beat me to it! And, as usual, Serge's answer works well (with integer values). But you did ask about how things worked, so here you go.
When you give a Custom Function a range as a parameter, H2:K2 in this case, the function receives a two-dimensional array, equivalent to the return value of Range.getValues(). You can test this easily, by (temporarily) changing your function to return a JSON representation of the parameter:
function sumColumns(values) {
return JSON.stringify(values); // For debugging, just return string showing values
...
Here's what you'll see in the cell that contains =sumColumns(H2:K2):
[["3 (Rarely)","3 (Frequently)","0 (Never)","3 (Frequently)"]]
That's showing an Array enclosed by [ .. ], with another Array inside, also enclosed by square brackets, and that array has four elements. If we change the range to be H2:K3 instead, we get this (with whitespace added for clarity):
[
["3 (Rarely)","3 (Frequently)","0 (Never)","3 (Frequently)"],
["","","",""]
]
Now that you know that, it's easy to see why your function was giving the results it did.
First, for(var i = 0; i <= values.length; i++) is using the wrong array bounds to loop over, since values.length will tell us how many rows are in values. In H2:K2, that length is 1. Instead, we need to be looping over the columns in the first row (values[0]), with its 4 cells.
You were wondering about < vs <= for this loop - we do need to use < since it's a 0-based index, and .length returns a count of elements. So we end up with:
for (var i=0; i < values[0].length; i++){ ... }
Using parseInt() is a good choice, and works well for the values in your spreadsheet. It can be improved, though, by ensuring that any String values have leading non-numeric values stripped first - parseInt() can then find an Integer inside a string.
function sumColumns(values) {
return JSON.stringify(values); // For debugging, just return string showing values
var sum = 0;
for(var i = 0; i < values[0].length; i++){
var input = new String(values[0][i])
.replace( /^\D+/g, ''); // Strip any leading non-digits
sum += parseInt(input);
}
return sum;
}
I'm not good with custom function because I never use them but it seems that values is not really an array...
Comments in italic :
Hmmm embarrassing ... my first though was that it had to be a 2D array but I logged val[0] in my test and it returned an 'undefined' error... I must have mistyped something at that moment... Anyway, that's why I looked for a way around handling data as a string and using split and regex.
As usual with Mogsdad's answers you have an answer and all the explanations that go with it ;-) and, as often with him too, you get a better answer than mine.
(one restriction though (#Mogsdad) your comment about non integer values could be applied to your code as well... you simply strip out any decimal value with parseInt()...:-)
That said, your use case was well described and in the limits of this example both code should work as expected, Mogsdad's one being more 'academic' and programmatically correct.
end of comment.
Using this trick below it works as expected for any input range (1 or more row and columns):
function sumCol(val) { // returns the sum of all numeric values in range
var values = val.toString().split(',');
var sum = 0;
for(var n=0;n<values.length;++n){
sum+=Number(values[n].replace(/[^0-9+.]/ig,''));
}
return sum;
}
I changed also the number extraction mode to make it more universal.

Syntax explanation please

I'm trying to understand 2 different lines of code below. My javascript is weak, trying to improve it with jquery (hmmmm)
What I'm trying to use the drag sort plugin from http://dragsort.codeplex.com/ specifically I'm using the http://dragsort.codeplex.com/SourceControl/changeset/view/74794#1025059 example.
I've gotten to the stage now where I've used this approach
var serialStr = "";
$("#list1 li").each(function(i, elm) {
serialStr = (i > 0 ? "|" : "") + $(elm).children().html();
});
The example has the following.
var serialStr = new Array();
$("#list1 li").each(function(i, elm) {
serialStr[] = = $(elm).attr("itemId");
});
The reason I have the first approach is that I was testing everything out and its what they had in the HTML example. I'm now trying to save the state so I've moved onto the php example.
So my question is what is the primary difference going on in the different lines here? My understanding of the first line is that its selecting each child element inside of the li tag on list1 I don't really get the (i > 0 ? "|" : "") bit.
In the second snipplet from what I understand its selecting every attribute with the itemID assignee in list1 li ?
serialStr[] = (i > 0 ? "|" : "") +$(elm).children().html() is a shorthand if-clausule. It does the same as:
if(i > 0) {
serialStr[] = "|" +$(elm).children().html();
} else {
serialStr[] = "" +$(elm).children().html();
}
The expression (i > 0 ? "|" : "") is using the conditional operator condition ? expr1 : expr2 to not to prefix the first value with | but only every following values.
But the expression serialStr[] = = $(elm).attr("itemId") is invalid syntax. Javascript does not have a push operator [] like PHP has. Use Array.prototype.push instead.
I don't think you've pasted the code exactly as neither snippet makes sense. The first seems to want to be concatenating strings together, but is missing the += that would make that happen; the second is making a list, presumably to join() together afterwards, but is using some odd []= syntax that does not exist in JavaScript.
I don't really get the (i > 0 ? "|" : "") bit.
First time round the loop, pick "", subsequent times pick "|". This is the traditional way to make a string where each element is separated by a character.
But join() is generally a cleaner way to do that, and you can use map() to run a function over an array returning a new array, instead of having to manually create one:
var itemIds= $('#list1 li').map(function() {
return $(this).attr('itemId');
}).get().join('|');
(Or $(this).html() if you really want to get the HTML content, which sounds a bit questionable.)
map() is a jQuery function but ECMAScript Fifth Edition has a map() method on plain arrays too. About map in general.

Categories

Resources