Multicheck of Cognos textbox prompts - javascript

I have two textbox prompts that I need to validate to only accept numbers or an empty field and if you input anything else than numbers or the empty field the run button should be disabled.
oCR = cognos.Report.getReport('_THIS_');
var prompts;
var f1 = oCR.prompt.getControlByName('Prompt1');
var f2 = oCR.prompt.getControlByName('Prompt2');
prompts = [f1,f2];
for (var i=0; i < prompts.length; i++) {
prompts[i].setValidator(validate);
}
function validate() {
var result = false;
for (var i=0; i < prompts.length; i++) {
var x = prompts[i].getValues();
if(x.length == 0) { result = true;}
if(x.length == 1 && x['use'] == " ") {result = true};
if(x.length > 0) {
var sValue = x['use'];
var codeFormat = new RegExp("^\\d+$")
if(codeFormat.test(sValue)) {
result=true;
}
}
}
if(result == true) {
getLink("Runreport").css("background-color", "#005FA5").css("border-color", "#005FA5").css("pointer-events","auto");
} else {
getLink("Runreport").css("background-color", "#dddddd").css("border-color", "#cccccc").css("pointer-events","none");
}
return result;
}
This doesn't really work the way I want. Because now it checks if both prompts checks for true. But if one prompt is true and the other is false it should be false not true. Anyone have an idea how to resolve this?

Here's your validate function simplified and restructured a bit:
function validate(values) {
var result = true,currentresult = true,x;
if (values.length > 0) {
if (isNaN(values[0].use)) {
currentresult = false;
}
}
for (var i=0; i < prompts.length; i++) {
x = prompts[i].getValue();
if (x.length > 0) {
if (isNaN(x)) {
result = false;
break;
}
}
if (prompts[i] != this) {
prompts[i].checkData();
}
}
if (result) {
getLink("Runreport").css("background-color", "#005FA5").css("border-color", "#005FA5").css("pointer-events","auto");
} else {
getLink("Runreport").css("background-color", "#dddddd").css("border-color", "#cccccc").css("pointer-events","none");
}
return currentresult;
}
Since you want the failure of either of your two prompts to cause invalidation, we start by setting the result to true. We then look for the special case that a prompt is invalidated. That special case results when the length of the prompt is not 0 (outer if), and the contents of the prompt is not a number (inner if). I used the isNaN() function because it will return true if the passed in value is a not a number and false if the value is a number. If isNan() returns true, then we set the result to false and break out of the for loop. The result is that if any of the prompts returns false, the whole result will be false.
For some more fun with text prompt validation, check out my advanced techniques Cognos Prompt Numeric Range Validation which demonstrates some other ways to do multi-prompt validation and Multi-prompt Validation which shows how to validate multiple prompts as a group.

Related

Return "True" if all the characters in a string are "x" or "X" else return false

I am looking at this code challenge:
Complete the function isAllX to determine if the entire string is made of lower-case x or upper-case X. Return true if they are, false if not.
Examples:
isAllX("Xx"); // true
isAllX("xAbX"); // false
Below is my answer, but it is wrong. I want "false" for the complete string if any of the character is not "x" or "X":
function isAllX(string) {
for (let i = 0; i < string.length; i++) {
if (string[i] === "x" || string[i] === "X") {
console.log(true);
} else if (string[i] !== "x" || string[i] !== "X") {
console.log(false);
}
}
}
isAllX("xAbX");
Your loop is outputting a result in every iteration. There are two issues with that:
You should only give one result for an input, so not in every iteration; currently you are reporting on every single character in the input string.
You are asked to return a boolean result (false/true), not to have the function print something. That should be left to the caller
You could take a simpler approach though, and first turn the input string to all lower case. Now you only have to look for "x". Then take out all "x" and see if something is left over. You can check the length property of the resulting string to decide whether the return value should be false or true:
function isAllX(string) {
return string.toLowerCase().replaceAll("x", "").length == 0;
}
console.log(isAllX("xxXXxxAxx")); // false
console.log(isAllX("xxXXxxXxx")); // true
If you are confortable with regular expressions, you could also use the test method:
function isAllX(string) {
return /^x*$/i.test(string);
}
console.log(isAllX("xxXXxxAxx")); // false
console.log(isAllX("xxXXxxXxx")); // true
You can try this way.
function isAllX(str) {
let isX = true;
let newString = str.toLowerCase();
for (let i = 0; i < newString.length; i++) {
if (newString[i] !== "x") {
isX = false;
}
}
return isX;
}
console.log(isAllX("xAbX"));
console.log(isAllX("XXXxxxXXXxxx"));
You can use regex to find the same.
function allX(testString) {
return /^x+$/i.test(testString);
}
console.log(allX("xxXX"));
console.log(allX("xxAAAXX"));
Without any method if you want
function isAllX(str) {
let flag = true;
for (let i = 0; i < str.length; i++) {
if (str[i] !== "x" && str[i] !== "X") {
flag = false;
// break;
}
}
return flag;
}
console.log(isAllX("xAbX"));
console.log(isAllX("XXXxxxXXXxxx"));
console.log(isAllX("xx"));
You can try converting the string to a single case, then looping over it while checking for the condition as below
function isAllX(string) {
const newString = string.toUpperCase();
for (let i = 0; i < newString.length; i++) {
if (newString[i] !== "X") {
return false
}
}return true
}

check the alphabetical order

I am a newbie who is trying hard to have a grip on javascript. please help me to consolidate my fundamentals.
input will be a string of letters.
following are the requirements.
function should return true if following conditions satisfy:
letters are in alphabetical order. (case insensitive)
only one letter is passed as input. example :
isAlphabet ('abc') === true
isAlphabet ('aBc') === true
isAlphabet ('a') === true
isAlphabet ('mnoprqst') === false
isAlphabet ('') === false
isAlphabet ('tt') === false
function isAlphabet(letters) {
const string = letters.toLowerCase();
for (let i = 0; i < string.length; i++) {
const diff = string.charCodeAt(i + 1) - string.charCodeAt(i);
if (diff === 1) {
continue;
} else if (string === '') {
return false;
} else if (string.length === 1) {
return true;
} else {
return false;
}
}
return true;
}
It's generally a better practice to start your function off with dealing with the edge-cases rather than putting them somewhere in the middle. That way, the function returns as soon as it can - and it's a lot easier to read than a waterfall of if..else statements.
function isAlphabet(letters) {
if ("" == letters) {
return false;
}
if (1 == letters.length) {
return true;
}
const string = letters.toLowerCase();
// carry on with your loop here.
}
You've got the right idea, but it can be simplified to just fail on a particular error condition, i.e when a smaller character follows a larger one:
function isAlphabet(letters) {
const string = letters.toLowerCase();
let lastChar;
for (let i = 0; i < string.length; i++) {
// Grab a character
let thisChar = string.charCodeAt(i);
// Check for the failure case, when a lower character follows a higher one
if (i && (thisChar < lastChar)) {
return false;
}
// Store this character to check the next one
lastChar = thisChar;
}
// If it got this far then input is valid
return true;
}
console.log(isAlphabet("abc"));
console.log(isAlphabet("aBc"));
console.log(isAlphabet("acb"));
You can use the simple way to achieve the same as below
function isAlphabet(inputString)
{
var sortedString = inputString.toLowerCase().split("").sort().join("");
return sortedString == inputString.toLowerCase();
}
console.log("abc = " + isAlphabet("abc"));
console.log("aBc = " + isAlphabet("aBc"));
console.log("acb = " + isAlphabet("acb"));
console.log("mnoprqst = " + isAlphabet("mnoprqst"));
Note: Mark the answer is resolves your problem.

Why indexOf in javascript not working?

I'm not sure what I'm doing wrong here. The first instance that I use indexOf it works perfectly fine, but when I use it the second time it's not returning the result that I'm expecting.
function mutation(arr) {
//return arr;
res = "";
for (var x=0; x<arr[1].split("").length; x++) {
if (arr[0].indexOf(arr[1].split("")[x]) !== -1) {
res += "t";
} else {
res += "f";
}
}
// res = ttt
if (res.indexOf("f") !== -1) {
return true;
} else {
return false;
}
}
mutation(["hello", "hey"]);
// this returns true instead of false
mutation(["floor", "loo"]);
// returns false instead of true
mutation should return false if an element from arr[1] is not present in arr[0] else return true.
your code isn't working because when you say:
res.indexOf("f") != -1
this means: "I found an f", but you're treating it as if it means "I did not find an f".
In your case that you want to return false if you find an 'f', but you're returning true. Flip your true and false cases:
if (res.indexOf("f") != -1) {
return false;
} else {
return true;
}
ALSO your for loop is wrong because x starts at 0, so you need to go to < length not <= length of your string.
for (var x=0; x < arr[1].split("").length; x++) {
and now your code works as you wanted it to.
Just edited your code. Click on the <p> to check:
function mutation(arr) {
//return arr;
res = "";
for (var x=0; x< arr[1].split("").length; x++) {
res += arr[0].indexOf(arr[1].split("")[x]) > -1 ? 't' : 'f';
}
return res.indexOf('f') > -1;
}
$('p').click(function(){
alert(mutation(["hello", "hey"]));
alert(mutation(["floor", "loo"]));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click me</p>
If you simplify the logic a bit, that's easier to check:
function mutation(arr) {
return arr[1].split('').reduce(function(res, x) {
return arr[0].indexOf(x) >= 0;
}, true);
}
Thanks Leon for the correction.
I tried to not chance your logic, the mistake are:
You're trying to compare with all characters on the array[0], not only the first.
If you find a character equals on the first character on array[0] you should return true.
Correct code:
function mutation(arr) {
res = "";
for (var x=0; x<=arr[1].split("").length; x++) {
if (arr[0].split("")[0].indexOf(arr[1].split("")[x]) !== -1) {
return true;
}
}
return false;
}

checking strings in an array

I'm trying to see if the string in the first element of the array contains all of the letters of the string in the second element of the array.
For example
['hello', 'hey'] = false;
['Army', 'Mary'] = true;
Here is my code
function mutation(arr) {
a = arr[0].toLowerCase().split("");
b = arr[1].toLowerCase().split("");
for(i = 0; i < a.length; i++){
if(b.indexOf(a[i]) != -1){
console.log('true');
} else {
console.log('false');
}
}
}
mutation(['Army', 'Mary']);
UPDATED
I need to see if element 1 contains all the letters for element 2 before I return back anything.
This would do, I'm sure there are better and optimal solutions though,
1) Storing the return result in a boolean, as var result = true;.
2) Check if both the Strings are equal/same, no need to loop, return the result which is true.
3) loop through each characters and see if the target element contains them, if found a mismatch set, result to false, break and return result.
function mutation(arr) {
a = arr[0].toLowerCase().split("");
b = arr[1].toLowerCase().split("");
var result = true;
if(a === b)
return result;
for(i = 0; i < a.length; i++){
if(b.indexOf(a[i]) === -1){
result = false;
break;
}
}
return result;
}
mutation(['Army', 'Mary']);
UPDATE Added a condition if (a === b) return true; to skip for loop.
No need of loop, you can take advantage of array functions.
Steps
Sort both arrays
Cast to the string
Check if strings2 contains string1
function mutation(arr) {
var a = arr[0].toLowerCase().split(''),
b = arr[1].toLowerCase().split('');
// For exact equality
return a.sort().toString() === b.sort().toString();
// return b.sort().toString().indexOf(a.sort().toString()) > -1;
}
document.write('Army and Mary: ' + mutation(['Army', 'Mary'])); // true
document.write('<br />a and b: ' + mutation(['a', 'b'])); // false
document.write('<br />ab and abc: ' + mutation(['ab', 'abc'])); // false
Simply you need to loop throught the second element letters and return false if a character doesn't exist in first element, or continue the loop if it exists.
Then check if the counter is equal to your string length then it contains all the given letters and return true:
function mutation(arr) {
a = arr[1].toLowerCase().split("");
b = arr[0].toLowerCase().split("");
if (a === b) return true;
for (i = 0; i < a.length; i++) {
if (b.indexOf(a[i]) === -1) {
return false;
}
}
if (i === a.length) {
return true; // all the letteers of element one exists in the second element
}
}
if (mutation(['Army', 'Mary'])) {
alert("Element one contains all letters of second element !");
} else {
alert("Sorry!");
}
Note:
Make sure you loop throught the second element characters and not the first one, see the a = arr[1].toLowerCase().split("");.
//mutation function work ignoring case and order of character in strings
function mutation(arr) {
var first = arr[0].toLowerCase();
var second = arr[1].toLowerCase();
for(var i = 0; i < second.length; i++){
if(first.indexOf(second[i]) == -1){
return false;
}
}
return true;
}
//this returns true
mutation(["hello", "ol"]);

Javascript - Find if number is positive or negative

I see other solutions to my question but none that help me.
I want to create a function to find if a number is positive/negative. The function should take an integer argument and return true if the integer is positive and false if it is negative.
Also, prompt the user again and again if anything other than a number is entered
Here's the code so far
When I enter a number, it keeps alerting me it is true or false but won't let me enter another.
How do I control my loop so I can ask until -1 is entered? It is not giving me a chance to enter -1
function isPositive(num) {
var result;
if (num >= 0) {
result = true;
} else if (num < 0) {
result = false;
}
return result;
}
var num;
num = parseInt(prompt("Enter a number"));
while (num != -1) {
alert(isPositive(num));
if (isNaN(num)) {
alert("No number entered. Try again");
num = parseInt(prompt("Enter a number"));
isPositive(num);
while (num != -1) {
alert(isPositive(num));
}
}
}
There's a few things wrong with your code, so here's a rewrite with comments:
function isPositive(num) {
// if something is true return true; else return false is redundant.
return num >= 0;
}
// when you want to keep doing something until a condition is met,
// particularly with user input, consider a while(true) loop:
var num;
while (true) {
num = prompt("Enter a number");
// check for null here
if (num === null) {
alert("No number entered. Try again.");
continue; // return to the start of the loop
}
num = parseInt(num, 10); // second argument is NOT optional
if (isNaN(num)) {
alert("Invalid number entered. Try again.");
continue;
}
// once we have a valid result...
break;
}
// the loop will continue forever until the `break` is reached. Once here...
alert(isPositive(num));
Math.sign(number)
which returns either a 1, -1 or 0
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
The number 0 is neither positive, nor negative! :P
function isPositive(num)
{
if(num < 0)
return false;
else
return true;
}
Or a simple way,
function isPositive(num)
{
return (num > 0);
}
You are testing if it isn't -1. Try this:
if(num < 0){
...IS NEGATIVE...
}else{
...IS POSITIVE...
}
This checks if it is less than or greater than 0.

Categories

Resources