Is there a simple way to check if a string in JavaScript matches a certain thing for example:
Lets say the you wanted to check for the first word which had:
/admin this is a message
Then using JS to look for /admin so that I can direct the message in my chat window??
One way would be to use indexOf() to see if /admin is at pos 0.
var msg = "/admin this is a message";
var n = msg.indexOf("/admin");
If n = 0, then you know /admin was at the start of the message.
If the string does not exist in the message, n would equal -1.
Or,
string.match(/^\/admin/)
According to http://jsperf.com/matching-initial-substring, this is up to two times faster than either indexOf or slice in the case that there is no match, but slower when there is a match. So if you expect to mainly have non-matches, this is faster, it would appear.
To achieve this, you could look for a "special command character" / and if found, get the text until next whitespace/end of line, check this against your list of commands and if there is a match, do some special action
var msg = "/admin this is a message", command, i;
if (msg.charAt(0) === '/') { // special
i = msg.indexOf(' ', 1);
i===-1 ? i = msg.length : i; // end of line if no space
command = msg.slice(1, i); // command (this case "admin")
if (command === 'admin') {
msg = msg.slice(i+1); // rest of message
// .. etc
} /* else if (command === foo) {
} */ else {
// warn about unknown command
}
} else {
// treat as normal message
}
You could use Array.slice(beg, end):
var message = '/admin this is a message';
if (message.slice(0, 6) === '/admin') {
var adminMessage = message.slice(6).trim();
// Now do something with the "adminMessage".
}
Related
I am trying to make a simple encoder in javascript, and copying the output to the clipboard, but the code gives an error.
I tried this code:
function encode() {
let alphabet = " abcdefghijklmnopqrstuvwxyz1234567890-=!##$%^&*()_+[];'/.,'{}|:~";
const a_list = alphabet.split('');
const m_list = prompt("message: ").split('');
let return_message = "";
for (let i = 0; i < m_list.length; i++) {
let current_letter = m_list[i];
let translated_letter = a_list[a_list.indexOf(current_letter) + 5];
return_message += translated_letter;
}
navigator.clipboard.writeText(return_message);
}
encode()
but the console gives this error:
Error: DOMException {INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, …}
I host the server in replit.
When I try to do an alert with the encoded words, it works fine.
navigator.clipboard.writeText requires a transient user activation. That is why it works when you click on an alert box.
Transient user activation is required. The user has to interact with the page or a UI element in order for this feature to work.
The "clipboard-write" permission of the Permissions API is granted automatically to pages when they are in the active tab.
https://devdocs.io/dom/clipboard/writetext
The error you are getting is because the indexOf function returns -1 when the sought character is not found in the a_list array.
You can check whether the index returned by indexOf is greater than or equal to zero before accessing the element in the a_list array. If the index returned is less than zero, you can simply add the original character to return_message.
Here is an example:
function encode() {
// Define the list of characters to be substituted
const alphabet = "abcdefghijklmnopqrstuvwxyz";
const charList = alphabet.split('');
// Receive the string to be substituted from the user
const inputString = prompt("Enter the string to be substituted:");
// Convert the string to an array of characters
const inputChars = inputString.split('');
// Create a new array with the substituted characters
const outputChars = inputChars.map(char => {
// Find the index of the current character in the character list
const index = charList.indexOf(char.toLowerCase());
// If the character is not in the character list, keep the original character
if (index === -1) {
return char;
}
// Find the next character in the character list
const nextIndex = (index + 1) % charList.length;
const nextChar = charList[nextIndex];
// Return the next substituted character
return char.toUpperCase() === char ? nextChar.toUpperCase() : nextChar;
});
// Convert the array of characters back to a string
const outputString = outputChars.join('');
// Display the substituted string in the console
navigator.clipboard.writeText(outputString);
}
encode()
And as answered in #dotnetCarpenter reply navigator.clipboard.writeText requires a transient user activation. That's why it works when an alert box is clicked.
Lets say I have the following string, which I may receive and require my program to act up on:
ACTION -F filter string -L location string -M message string
How can I reliably extract the 'arguments' from this string, all of which are optional to the user?
I spent a lot of time instead writing ACTION, filter, location, message and using .split(", ") to put the args to an array but found this too difficult to work reliably.
var content = req.body.Body.split(", "); // [ Type, Filter, Location, Message]
var msgType = content[0].trim().toUpperCase();
if (msgType === 'INFO') {
// return info based on remainder of parameters
var filterGroup = content[1].trim();
var destination = content[2].trim();
var message = '';
// The message may be split further if it is written
// with a ',' so concat them back together.
if (content.length > 2) { // Optional message exists
// Message may be written in content[3] > content[n]
// depending how many ', ' were written in the message.
for (var i = 3; i < content.length; i++) {
message += content[i] + ", ";
}
}
}
Is the -a argument format even the best way? Much googling returns information on extracting the arguments used to run a nodeJS program, but that isn't applicable here, as the program is already running and the string not used at runtime. I'm at the design stage so have complete control over the format of the user input, but they're sending a SMS with these commands so the simpler the better!
I'm writing in javascript and would appreciate your thoughts
You can use a regex to match the -X pattern and then use a loop to extract the strings between each pattern match.
The regex here is /(?<=\s)\-[A-Za-z](?=\s)/g, which looks for a dash followed by a letter with a white space character on either side.
const input = "ACTION -F filter string -L location string -M message string";
let regex = /(?<=\s)\-[A-Za-z](?=\s)/g;
let args = [];
while(match = regex.exec(input))
{
args.push(match);
}
let solved = [];
for(let i = 0; i < args.length; i++)
{
let cmd = args[i][0];
let idx = args[i].index;
let val;
if(i + 1 == args.length)
val = input.substr(idx + cmd.length + 1);
else
val = input.substring(idx + cmd.length + 1, args[i + 1].index - 1);
solved.push({
cmd: cmd,
val: val
});
}
console.log(solved);
I'm working on a PHP-chat right now.
When a user logs in he automatically sends a message "logged in" that is shown to everybody, when he logs out he automatically sends "logged out" that is shown to everybody (except him of course).
When all users logged out, all messages are deleted automatically.
I'm now working on a function that tells you, whether you are alone in the chatroom or not.
I want to solve this using JavaScript. The script I use right now counts how often the term "logged in" and the term "logged out" appears in the chat history (yeah, not the ultimate solution, but absolutely sufficient for my use)
Here's the code:
function countverlassen(){
var temp = document.body.innerText;
// the g in the regular expression says to search the whole string
// rather than just find the first occurrence
var countverlassen = (temp.match(/verlassen/g) || []).length +1;
console.log(countverlassen);
}
function countbetreten(){
var temp = document.body.innerText;
// the g in the regular expression says to search the whole string
// rather than just find the first occurrence
var countbetreten = (temp.match(/betreten/g) || []).length;
console.log(countbetreten);
if (countbetreten >= 2 && countbetreten != countverlassen){
$('.alleine').hide();
}
else if (countverlassen >= 2 && countbetreten == countverlassen) {
$('.alleine').show();
}
}
The class "alleine" only contains the text "You are alone in here right now".
When another user logs in this should be hidden, when all other users except you log out it should be displayed again.
Hiding the class works fine, but it just won't reapper again when everybody else logged out.
You can see it in action here: http://team3.digital-cultures.net/index.php#
Just pick a name and chosse a start / destination from the dropdown.
What am I doing wrong?
Thanks!
EDIT: For testing purposes you can just enter "betreten" ("logged in" in German) and "verlassen" ("logged out in German") in the chat, no need to log in with multiple accounts :)
You need to use return to get a value out. Using the function name is only creating a new local variable. I've renamed the var to make this clearer.
function countverlassen(){
var temp = document.body.innerText;
// the g in the regular expression says to search the whole string
// rather than just find the first occurrence
var verlassenCount = (temp.match(/verlassen/g) || []).length +1;
console.log(verlassenCount);
return verlassenCount;
}
Use countverlassen() to call the function and get the value. Store the value instead of calling the function every time.
function countbetreten() {
var temp = document.body.innerText;
// the g in the regular expression says to search the whole string
// rather than just find the first occurrence
var betretenCounter = (temp.match(/betreten/g) || []).length;
var verlassenCounter = countverlassen();
console.log(betretenCounter);
if (betretenCounter >= 2 && betretenCounter != verlassenCounter) {
$('.alleine').hide();
} else if (verlassenCounter >= 2 && betretenCounter == verlassenCounter) {
$('.alleine').show();
}
}
Here what the textbox result looks like,
Please add the following DNS entries
144.68.238.87 name.domain
144.68.238.88 name.domain
144.68.238.89 name.domain
The goal is to validate name.domain by making sure that the user replace name.domain to server name on textbox before submit it. If the user doesn't replace name.domain with their server name, then it will send alert message and return false until user replace it correctly.
Here is my codes,
function DomainValidate() {
var arrayOfLines = document.getElementById('txt').value.split('/n');
arrayOfLines.shift(); //use shift to skip the first line
for (i = 0; i < arrayOfLines.length; i++) {
//somewhere here need to split to get name.domain and then verify it
var domainName = arrayOfLines[i].split(" ", 2);
if(domainName.Equals("name.domain")
{
alert("You must replace name.domain to your new server name");
return false;
}
}
}
I am not sure if these are correct since I couldn't debug the javascript.
First issue I can see is that your character for the newline is incorrect. It should be \n not /n. Second issue I see is that i is a global variable, when it should be local. Third issue is that arrayOfLines[i].split(' ', 2); returns an array, but you are treating it like it returns a string on the next line if (domainName.Equals('name.domain').
With those corrections your code would look more like this:
function domainValidate() {
var arrayOfLines = document.getElementById('txt').value.split('\n');
arrayOfLines.shift(); //use shift to skip the first line
for (var i = 0; i < arrayOfLines.length; i++) {
var line = arrayOfLines[i].trim();
// Grab the second part of the split line, which represents the domain name
var parts = line.split(' ');
var domainName = parts[parts.length - 1];
if (!domainName || domainName === 'name.domain') {
alert("You must replace name.domain to your new server name");
return false;
}
}
}
As far as I can tell without testing, this should work as expected. The best way to test this though is with jsfiddle. Add your html and this script and call it to see if it produces the expected result.
Easiest way that I think
Suppose the id of textbox is domainTxt
src = document.getElementById("domainTxt");
if(verifyInput(src.value)){
//submit your form here
} else
{
return false;
}
function verifyInput(txtVal){
if(txtVal.indexOf("name.domain") >-1){
return false;
}else {
return true;
}
}
I wrote a small script to recreate the Chrome address bar, wherein my code checks an input for any domain extension(.com, .edu etc.) and sets a boolean flag to true if an extension is found.
It then checks the flag and based on the result opens the website or sends it to google as a query.
Additionally, if it is a website, it checks if the string contains http:// and www. and if not, adds it to the string before using Window.Open() to open the target.
What's wrong here?
function openSite(){
var domain_extensions = [".aero", ".asia", "...All Other Extensions...", ".zr", ".zw"];
var isSite = false;
var userIn = document.getElementById('in_field').value; //Retrieves Textbox code
for (var i=0; i < domain_extensions.length; i++)
if (userIn.search(domain_extensions[i]) !==-1)
isSite = true;
//Checks against the array of extensions
if (isSite === true){
if (userIn.search("http://") === -1 || userIn.search("https://") === -1)
{if(userIn.search("www.") === -1)
userIn = "http://www." + userIn;
else
userIn = "http://" + userIn;
}
window.open(userIn, '_blank');
//if extension is found, open website
//if qualifier http:// or https:// and/or www. not found, append and open website
}
else{
var str = encodeURI("http://www.google.com/search?q=" + userIn);
window.open(str, '_blank');
} //Searches query for common extensions; if not found search google
}
This is a problem, I believe, with your usage of the search function. This function takes a regular expression as its argument. The . character is special in regex, and matches any character.
For example:
var test = "blasdfahsadfcomasdfasd";
console.log(test.search(".com")); // prints 11
Prepend the . with a backslash in order to override this behavior:
var test = "blasdfahsadfcomasdfasd";
console.log(test.search("\\.com")); // prints -1
Additionally, if you want to check only at the end of a string, add a $ symbol at the end of the strings like so:
var test = "blasdfahsadf.comasdfasd";
console.log(test.search("\\.com$")); // prints -1; prints 12 w/o the $